title: Windows DLL function behaviour is different if DLL is moved to different location
body: <p>I'm attempting to debug some very opaque issues with DLLs in Unreal on a CI machine (see <a href="https://stackoverflow.com/questions/68258600/unreal-diagnosing-why-windows-cannot-load-a-dll">Unreal: Diagnosing why Windows cannot load a DLL</a> for more information). <code>glu32.dll</code> seems to be the DLL at which the Unreal process falls over, and as Windows Server doesn't contain all the graphics-related DLLs that normal Windows 10 does, I was recommended to upload certain DLLs from my machine/Microsoft redistributables in order to make sure the Unreal build process could run.</p>
  <p>For sanity purposes, I've written a small utility program to test whether <code>glu32.dll</code> on my machine can be dynamically loaded and can have its functions called correctly. I'm planning to run this executable on the troublesome CI machine soon to see what happens.</p>
  <p>The code for the program is below:</p>
  <pre><code>#include &lt;windows.h&gt; 
  #include &lt;iostream&gt;
  #include &lt;GL/gl.h&gt;
  
  extern &quot;C&quot;
  {
      typedef const GLubyte* (__stdcall *ErrorStringFunc)(GLenum error);
  }
  
  int main(int argc, char** argv)
  {
      if (argc &lt; 2)
      {
          std::cerr &lt;&lt; &quot;Usage: GLU32Loader.exe &lt;path to glu32.dll&gt;&quot; &lt;&lt; std::endl;
          return 1;
      }
  
      const char* path = argv[1];
      std::cout &lt;&lt; &quot;Attempting to load: &quot; &lt;&lt; path &lt;&lt; std::endl;
  
      HMODULE dllHandle = LoadLibraryA(path);
  
      if (!dllHandle)
      {
          std::cerr &lt;&lt; &quot;Could not load &quot; &lt;&lt; path &lt;&lt; std::endl;
          return 1;
      }
  
      std::cout &lt;&lt; &quot;Successfully loaded DLL: 0x&quot; &lt;&lt; dllHandle &lt;&lt; std::endl;
  
      const char* funcName = &quot;gluErrorString&quot;;
  
      std::cout &lt;&lt; &quot;Looking up function: &quot; &lt;&lt; funcName &lt;&lt; std::endl;
      ErrorStringFunc func = reinterpret_cast&lt;ErrorStringFunc&gt;(GetProcAddress(dllHandle, funcName));
  
      if (func)
      {
          std::cout &lt;&lt; &quot;Successfully loaded function: 0x&quot; &lt;&lt; func &lt;&lt; std::endl;
  
          const GLubyte* str = (*func)(100902);
          std::cout &lt;&lt; &quot;Error string for value 100902: \&quot;&quot; &lt;&lt; str &lt;&lt; &quot;\&quot; (0x&quot; &lt;&lt; static_cast&lt;const void*&gt;(str) &lt;&lt; &quot;)&quot; &lt;&lt; std::endl;
      }
      else
      {
          std::cerr &lt;&lt; &quot;Failed to load function &quot; &lt;&lt; funcName &lt;&lt; std::endl;
      }
  
      FreeLibrary(dllHandle);
  
      return 0;
  }
  </code></pre>
  <p>When I run the executable and point it to <code>glu32.dll</code> in the <code>System32</code> folder, I get expected output:</p>
  <pre><code>&gt; GLU32Loader.exe &quot;C:\Windows\System32\glu32.dll&quot;
  Attempting to load: C:\Windows\System32\glu32.dll
  Successfully loaded DLL: 0x00007FFC7A350000
  Looking up function: gluErrorString
  Successfully loaded function: 0x00007FFC7A35C650
  Error string for value 100902: &quot;out of memory&quot; (0x000001E5757F51D0)
  </code></pre>
  <p>However, if I copy the DLL to my desktop and run the program again, although the DLL and function appear to be loaded, the string returned from the function is empty:</p>
  <pre><code>&gt; GLU32Loader.exe &quot;C:\Users\Jonathan\Desktop\glu32.dll&quot;
  Attempting to load: C:\Users\Jonathan\Desktop\glu32.dll
  Successfully loaded DLL: 0x00007FFC8DDB0000
  Looking up function: gluErrorString
  Successfully loaded function: 0x00007FFC8DDBC650
  Error string for value 100902: &quot;&quot; (0x0000025C5236E520)
  </code></pre>
  <p>Why would this be? It's exactly the same DLL, just in a different folder, and I would have thought that any other dependent DLLs that it references should still be available because they're all in <code>System32</code>. Is there some mystical property of Windows DLLs that I'm not familiar with that might cause this to happen?</p>