title: LdrLoadDll problem
body: <p>I am trying to code an alternative to LoadLibrary function, based on the idea of calling the function LdrLoadDll from ntdll.
  This function needs as a parameter the dll file to load, in a UNICODE_STRING format.
  I really can't get what I am doing wrong here (string seems to be correctly initialized), but when LdrLoadDll is called, I get the following error:</p>
  
  <p>Unhandled exception in "Test.exe" (NTDLL.DLL): 0xC0000005: Access Violation.</p>
  
  <p>I use Visual C++ 6.0 for this test, and I am using Windows 7 64 bit.</p>
  
  <p>I post full code here, thanks in advance for any help:</p>
  
  <pre><code>#include &lt;Windows.h&gt;
  
  
  typedef LONG NTSTATUS; //To be used with VC++ 6, since NTSTATUS type is not defined
  
  
  
  typedef struct _UNICODE_STRING { //UNICODE_STRING structure
    USHORT  Length;
    USHORT  MaximumLength;
    PWSTR  Buffer;
  } UNICODE_STRING;
  typedef UNICODE_STRING *PUNICODE_STRING;
  
  
  
  
  typedef NTSTATUS (WINAPI *fLdrLoadDll) //LdrLoadDll function prototype 
      (
           IN PWCHAR PathToFile OPTIONAL,
           IN ULONG Flags OPTIONAL, 
           IN PUNICODE_STRING ModuleFileName, 
           OUT PHANDLE ModuleHandle 
      ); 
  
  
  
  
  
  /**************************************************************************
    *      RtlInitUnicodeString   (NTDLL.@)
    *
    * Initializes a buffered unicode string.
    *
    * RETURNS
    *  Nothing.
    *
    * NOTES
    *  Assigns source to target-&gt;Buffer. The length of source is assigned to
    *  target-&gt;Length and target-&gt;MaximumLength. If source is NULL the length
    *  of source is assumed to be 0.
    */
   void WINAPI RtlInitUnicodeString(
       PUNICODE_STRING target, /* [I/O] Buffered unicode string to be initialized */
       PCWSTR source)          /* [I]   '\0' terminated unicode string used to initialize target */
   {
       if ((target-&gt;Buffer = (PWSTR) source))
       {
           unsigned int length = lstrlenW(source) * sizeof(WCHAR);
           if (length &gt; 0xfffc)
               length = 0xfffc;
           target-&gt;Length = length;
           target-&gt;MaximumLength = target-&gt;Length + sizeof(WCHAR);
       }
       else target-&gt;Length = target-&gt;MaximumLength = 0;
   }
  
  
  
  NTSTATUS LoadDll( LPCSTR lpFileName)
  {
    HMODULE hmodule = GetModuleHandleA("ntdll.dll");
    fLdrLoadDll   _LdrLoadDll = (fLdrLoadDll) GetProcAddress ( hmodule, "LdrLoadDll" );
  
    int AnsiLen = lstrlenA(lpFileName);
    BSTR WideStr = SysAllocStringLen(NULL, AnsiLen);
    ::MultiByteToWideChar(CP_ACP, 0, lpFileName, AnsiLen, WideStr, AnsiLen);
  
    UNICODE_STRING usDllFile;
    RtlInitUnicodeString(&amp;usDllFile, WideStr); //Initialize UNICODE_STRING for LdrLoadDll function
    ::SysFreeString(WideStr);
  
    NTSTATUS result = _LdrLoadDll(NULL, LOAD_WITH_ALTERED_SEARCH_PATH, &amp;usDllFile,0); //Error on this line!
  
    return result;
  }
  
  
  
  void main()
  {
    LoadDll("Kernel32.dll");
  }
  </code></pre>