Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2708
  • Last Modified:

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

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
PolySystems
Asked:
PolySystems
  • 6
  • 4
1 Solution
 
jkrCommented:
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
 
jkrCommented:
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
 
PolySystemsAuthor Commented:
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
jkrCommented:
Well, the code is/was OK, the issue is that you still have to set an application specific DLL directory first...
0
 
PolySystemsAuthor Commented:
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
 
jkrCommented:
>>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
 
PolySystemsAuthor Commented:
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
 
jkrCommented:
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
 
PolySystemsAuthor Commented:
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
 
jkrCommented:
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now