C# LoadLibrary ERROR_NO_TOKEN

2019-08-07 08:20发布

问题:

I'm loading a MFC dll with dependencies (let's say I'm loading D.dll, which depends on C.dll, B.dll and A.dll) in C#. Here's my code:

[DllImport( "kernel32.dll", CharSet = CharSet.Auto, SetLastError = true )]
static extern IntPtr LoadLibrary( string lpFileName );

private void btn_Click( object sender, EventArgs e )
{
int             nUltErr;
string          strDLL;
StringBuilder   strPDF;
StringBuilder   strXML;

strDLL = "C:\\DEVELOP\\Libs\\Interfaccia\\Interfaccia_C_2005\\DLL\\Interfaccia_C_2005.dll";
strFile1 = new StringBuilder( @"C:\DEVELOP\Libs\Interfaccia\TestCase\PROGRAM\tiger.pdf" );
strFile2 = new StringBuilder( @"C:\DEVELOP\Libs\Interfaccia\TestCase\PROGRAM\tiger.XML" );
if( LoadLibrary( strDLL ) != IntPtr.Zero )
{
    LoadPDF( strPDF );
    SaveXML( strXML );
    ClosePDF();
    FreeMemory();
}
else
{
    nUltErr = Marshal.GetLastWin32Error();
    MessageBox.Show( "Errore nel caricamento della dll." );
}

}

nUltErr is 1008 = 0x3F0, that should be ERROR_NO_TOKEN. What does exactly mean this in C#? Path to DLL IS right.

回答1:

The code ERROR_NO_TOKEN generally means that someone has attempted to call OpenThreadToken on a thread that was not impersonating. This may be a problem or not a problem - that's just the last error code to be recorded by SetlastError.

This call could be in the DllMain of Interfaccia_C_2005.dll, or in the DllMain of any library which is referenced in turn. It is not entirely obvious why they would need to do that but it is possible.

Also, this may not be the actual error causing failure. Among other causes, LoadLibrary will fail if the DllMain of Interfaccia_C_2005.dll, or in the DllMain of any library which is referenced in turn, returns false. If the DllMain returns false, without calling SetLastError, GetLastError will show the previous error, whatever it was. For example the system might be quite happy for OpenThreadToken to fail, but something else has gone wrong, which did not call SetLastError.

Essentially you need to fire up the Native Code debugger, and see what that tells you.



回答2:

You have not set the SetLastError field on your DllImport attribute.

This means you are not getting the correct value from Marshal.GetLastWin32Error().

Change LoadLibrary to this:

[DllImport( "kernel32.dll", CharSet = CharSet.Auto, SetLastError = true )]
static extern IntPtr LoadLibrary( string lpFileName );