Solved

I cant get GetDllDirectory to actually return the list of dll search directories.

Posted on 2009-04-07
10
2,341 Views
Last Modified: 2012-06-27
I am trying to execute GetDllDirectory from kernel32.dll I can find the function in there, and call it, and the call is successful (caue GetLastError says so, but the returned search list is null.
I have tried this code on xp sp3 and vista, and it does the same thing. Actually the entry point for ascii is GetDirectoryA. I have tried fiddling with WINVER etc but nothing works, I have tried the sdk version of kernel32.dll too, and the one in c:\i386 and c:\windows\Sysem32.
here is what i get when i run it.  
dinky
cant get dll path. res=0 []
The operation completed successfully.
#include <windows.h>

#include <Winbase.h>

#include <winerror.h>

#endif
 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#include <time.h>

#include <assert.h>

#define _WIN32_WINNT 0x0503

#define _WINVER  0x0503
 

static void Spit(void)

{

   int glee;

   LPVOID lpMsgBuf;

   glee = GetLastError();

   FormatMessage(

       FORMAT_MESSAGE_ALLOCATE_BUFFER |

       FORMAT_MESSAGE_FROM_SYSTEM |

       FORMAT_MESSAGE_IGNORE_INSERTS,

       NULL,

       glee,

       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */

       (LPTSTR) &lpMsgBuf,

       0,

       NULL

   );

   fprintf(stdout,lpMsgBuf);

   LocalFree( lpMsgBuf );

   return;

};

void xxx(void)

{

   char *DllName="kernel32";

   HINSTANCE z=LoadLibrary(DllName);

   if (z == NULL)

      fprintf(stderr,"cant open %s\n",DllName);

   else

   {

      char *f1="GetDllDirectoryA";

      int (WINAPI *GetDllDirectoryA)(int,char *);
 

      GetDllDirectoryA = (int (WINAPI *)(int,char * )) GetProcAddress(z,f1);

      if ( GetDllDirectoryA == NULL)

         fprintf(stderr,"cant get GetDllDirectoryA\n");

      else

      {

         char B[8192] = {""};

         int res= GetDllDirectoryA( 8192,B);

         if ( res == 0 || GetLastError() != NO_ERROR)

         {

            fprintf(stderr,"cant get dll path. res=%ld [%s] \n",res,B);

            Spit();

         }

         else

         {

            assert ( res < 8192);

            fprintf(stdout,"%s\n",B);

         }

      }

      FreeLibrary(z);

   }

}
 

main(int argc,char **argv)

{

   xxx();

}

Open in new window

0
Comment
Question by:PolySystems
  • 6
  • 4
10 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 24090024
Well, as the docs (http://msdn.microsoft.com/en-us/library/ms683186(VS.85).aspx) state: "Retrieves the application-specific portion of the search path used to locate DLLs for the application.". So, in order to retrieve an application-specific DLL path, you need to set one first. See the attached sample (BTW, no need to do that using function pointers...)
#define _WIN32_WINNT 0x0503

#define _WINVER  0x0503

#include <windows.h>

#include <Winbase.h>

#include <winerror.h>
 

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#include <time.h>

#include <assert.h>
 

 

static void Spit(void)

{

   int glee;

   LPVOID lpMsgBuf;

   glee = GetLastError();

   FormatMessage(

       FORMAT_MESSAGE_ALLOCATE_BUFFER |

       FORMAT_MESSAGE_FROM_SYSTEM |

       FORMAT_MESSAGE_IGNORE_INSERTS,

       NULL,

       glee,

       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */

       (LPTSTR) &lpMsgBuf,

       0,

       NULL

   );

   fprintf(stdout,(char*)lpMsgBuf);

   LocalFree( lpMsgBuf );

   return;

};

 

void main(int argc,char **argv)

{
 

         SetDllDirectory("c:\\tmp");

         char B[8192];

         int res= GetDllDirectory( 8192,B);

         if ( res == 0 || GetLastError() != NO_ERROR)

         {

            fprintf(stderr,"cant get dll path. res=%ld [%s] %d \n",res,B, GetLastError());

            Spit();

         }

         else

         {

            assert ( res < 8192);

            fprintf(stdout,"%s\n",B);

         }

}

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 24090071
BTW, why do you need to call that function? If it is about where Windows looks for DLLs, see http://msdn.microsoft.com/en-us/library/ms682586.aspx ("Dynamic-Link Library Search Order")
0
 

Author Comment

by:PolySystems
ID: 24092463
I am very sorry. This is the code I meant to include.
#if defined _MSC_VER

#include <windows.h>

#include <Winbase.h>

#include <winerror.h>

#endif
 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#include <time.h>

#include <assert.h>

#define _WIN32_WINNT 0x0503

#define _WINVER  0x0503
 

static void Spit(void)

{

   int glee;

   LPVOID lpMsgBuf;

   glee = GetLastError();

   FormatMessage(

       FORMAT_MESSAGE_ALLOCATE_BUFFER |

       FORMAT_MESSAGE_FROM_SYSTEM |

       FORMAT_MESSAGE_IGNORE_INSERTS,

       NULL,

       glee,

       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */

       (LPTSTR) &lpMsgBuf,

       0,

       NULL

   );

   fprintf(stdout,lpMsgBuf);

   LocalFree( lpMsgBuf );

   return;

};

void xxx(void)

{

   char *DllName="kernel32";

   HINSTANCE z=LoadLibrary(DllName);

   if (z == NULL)

      fprintf(stderr,"cant open %s\n",DllName);

   else

   {

      char *f1="GetDllDirectoryA";

      int (WINAPI *GetDllDirectoryA)(int,char *);
 

      GetDllDirectoryA = (int (WINAPI *)(int,char * )) GetProcAddress(z,f1);

      if ( GetDllDirectoryA == NULL)

         fprintf(stderr,"cant get GetDllDirectoryA\n");

      else

      {

         char B[8192] = {""};

         int res= GetDllDirectoryA( 8192,B);

         if ( res == 0 || GetLastError() != NO_ERROR)

         {

            fprintf(stderr,"cant get dll path. res=%ld [%s] \n",res,B);

            Spit();

         }

         else

         {

            assert ( res < 8192);

            fprintf(stdout,"%s\n",B);

         }

      }

      FreeLibrary(z);

   }

}
 

main(int argc,char **argv)

{

   xxx();

}

~

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 24093390
Well, the code is/was OK, the issue is that you still have to set an application specific DLL directory first...
0
 

Author Comment

by:PolySystems
ID: 24097607
I tried t he "set one first" and thats the only one I get back.
I want the list of places that are searched for a DLL including the standard ones. From machine to machine, this may change, and besides, one of the places it checks is the dir where the .exe lives that is being fired off, and I expect to see that in the list too.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 86

Expert Comment

by:jkr
ID: 24097780
>>I want the list of places that are searched for a DLL including the standard
>>ones

Yes, that's what http://msdn.microsoft.com/en-us/library/ms682586.aspx ("Dynamic-Link Library Search Order") explains. But, you'll only get back something from 'GetDllDirectory()' when you have set a value via 'SetDllDirectory()', see http://msdn.microsoft.com/en-us/magazine/cc300448.aspx ("Discover Improved System Info, New Kernel, Debugging, Security, and UI APIs"): "The documentation for SetDllDirectory describes the exact search order and makes for interesting reading. GetDllDirectory returns whatever value has been previously set by calling SetDllDirectory". Also check out http://msdn.microsoft.com/en-us/library/ms686203(VS.85).aspx ("SetDllDirectory")
0
 

Author Comment

by:PolySystems
ID: 24101941
I can't see the statement in the msdn ref  that you only get back what you set yourself. I believe you  though because that is what I am seeing,  but its such a limited functionality that I am surprised at the way it works. So with all said and done, no matter what kind of stuff was done to alter the dll search path, there is no way to ask the kernel to just give me a path of the places it searches, including  the home of my .exe and the current directlry,  and all other search directorys to look...
 That complete final  declaration as to the search path, in the right order, is what I thought I might get.
What it seems i get is a parroting of what I gave it in SetDllDirectory?  Thats of such limited value that I wonder if there is a dimension to it that I dont understand.
0
 
LVL 86

Expert Comment

by:jkr
ID: 24102124
Well, just search for 'GetDllDirectory' in http://msdn.microsoft.com/en-us/magazine/cc300448.aspx - the sentence clearly reads "GetDllDirectory returns whatever value has been previously set by calling SetDllDirectory."

I am sorry about that, but what other value should that thing return? The other places where Windows looks for DLLs are already documented in http://msdn.microsoft.com/en-us/library/ms682586.aspx ("Dynamic-Link Library Search Order") and still apply. Now, what you and your app can do is extending that by adding another directory to precede this search order. This of course limits the use of this feature to DLLs that you load via 'LoadLibrary()' after making that adjustment...
0
 

Author Comment

by:PolySystems
ID: 24112529
what is should return is a list including my own .exe location and and the durrent directory we are cd-ed and whatever system directories a re in the search path, together with whatever special SetDllDirectories may have been specified.  There are enough tricky indirections involved, some my directories, some  system directories etc. to  make one final  adjudication by the kernel very usefull Not just a parrot back of what  was  set by SetDllDirectory
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 24113271
Hm, you can always obtain your exe's location calling 'GetModuleFileName()' (http://msdn.microsoft.com/en-us/library/ms683197(VS.85).aspx) and you can check PATH via the environment variable with the same name - what exactly is your ultimate goal that you want to achieve?
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now