1

I am working with wtsapi32.dll. (Window Terminal Service api)

I am trying to get user info from method WTSQueryUserConfig.

[DllImport("wtsapi32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WTSQueryUserConfig(
                           [MarshalAs(UnmanagedType.LPStr)] string pServerName,
                           [MarshalAs(UnmanagedType.LPStr)] string pUserName,
                           WTS_CONFIG_CLASS wtsConfigClass,
                           out StringBuilder pBuffer,
                           out int dataLength);

I have problem with user with SAM-Account-Name in japanese (unicode).

I have modified my class with (unicode version):

[DllImport("wtsapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WTSQueryUserConfigW(
                           [MarshalAs(UnmanagedType.LPStr)] string pServerName,
                           [MarshalAs(UnmanagedType.LPStr)] string pUserName,
                           WTS_CONFIG_CLASS wtsConfigClass,
                           out StringBuilder pBuffer,
                           out int dataLength);

But I call this method with japanese SAM-Account-Name it does not work.

Users without unicode characters works fine with non-unicode version method.

Ivan Rodriguez
  • 426
  • 4
  • 14
  • 4
    `[MarshalAs(UnmanagedType.LPStr)]` is unnecessary and in this case incorrect, since `LPStr` is always ANSI. Use `LPTStr` for both or `LPWStr` for the Unicode version specifically or just leave out the attribute (you've already specificed `CharSet`, so the marshaller should figure out the correct type on its own). – Jeroen Mostert Feb 20 '18 at 16:33
  • Jeroen is correct. In addition, there is a hard requirement to call WTSFreeMemory to release the memory that was allocated for the buffer. Right now that is not possible, so the program leaks memory. Fix that by using `out intPtr pBuffer`, Marshal.PtrToStringUni() provides the string. – Hans Passant Feb 20 '18 at 16:53
  • Thanks @JeroenMostert. Now It works fine. About Marshal I am trying to improve my code with Han's advice. Thanks a lot!! – Ivan Rodriguez Feb 21 '18 at 17:06

1 Answers1

1

Finally I only used the charset configuration for the input parameters

[DllImport("wtsapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WTSQueryUserConfigW(
                                    string pServerName,
                                    string pUserName,
                                    WindowsTerminalServiceConfig wtsConfigClass,
                                    out StringBuilder pBuffer,
                                    out int dataLength);
Ivan Rodriguez
  • 426
  • 4
  • 14