Search code examples
c#.netwinapiinteropwin32exception

"Win32Exception: The operation completed successfully" after WTSQueryUserToken on 32bit Windows (64bit works)


I'm developing a small Windows Service in C# that needs to do interop with Win32 API at some point. I'm getting the following exception which does not make sense to me:

System.ComponentModel.Win32Exception: The operation completed successfully

Right after the last line in this C# snippet:

var sessionId = Kernel32.WTSGetActiveConsoleSessionId();
var userTokenPtr = new IntPtr();
if (!WtsApi32.WTSQueryUserToken(sessionId, out userTokenPtr))
{
    throw new Win32Exception(Marshal.GetLastWin32Error());
}

Here's how I'm declaring WTSQueryUserToken in WtsApi32:

[DllImport("Wtsapi32.dll", EntryPoint="WTSQueryUserToken")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WTSQueryUserToken
(
    [In, MarshalAs(UnmanagedType.U8)] ulong sessionId, 
    [Out] out IntPtr phToken
);

Some facts:

  • This works perfectly on 64bit Win7, but fails on a 32bit Win7.
  • There's no way the 10,000 handle limit has been reached when this is executed, it's the first Win32 call in a very small windows service.
  • I think there might be some underlying Win32 error but some bug overwrote the errorcode with a 0, thus giving me the "success" error message, but I don't know how to confirm or even diagnose this.
  • When I catch the exception, sessionId is 1 and userTokenPtr is 0. However, GetLastError returns 0 so I have no idea what happened.
  • Nearly all of the answers I found to this problem had to do with improper disposal of user controls. Since this is a Windows service, this is not the case.

I'm guessing there must be something wrong with my WTSQueryUserToken declaration, since it only fails on 32bit Windows, which leads me to think it's a marshaling problem. However, I still can't see what it might be.


Solution

  • Your sessionId parameter us defined as a c# ulong - an unsigned 64-bit integer, whereas the actual function export is expecting a Win32 ulong - an unsigned 32-bit integer.

    c# ulong data type

    Win32 data types