What are the proper arguments and return value marshalling for a syscall to WTSQuerySessionInformation

I’m trying to call the WTSQuerySessionInformation Windows function from the kernel32 library using the syscall.NewLazyDLL() interface.

I’m not really clear about what the data types should be or how to cast the return data properly.

The function in question has the following definition:

BOOL WTSQuerySessionInformation(
  _In_  HANDLE         hServer,
  _In_  DWORD          SessionId,
  _In_  WTS_INFO_CLASS WTSInfoClass,
  _Out_ LPTSTR         *ppBuffer,
  _Out_ DWORD          *pBytesReturned
);

where *ppBuffer is basically a pointer to a pointer that points to some datastructure, which varies depending on what arguments you pass to the function when calling it. (see MSDN - WTSQuerySessionInformation)

I have my go code defined like this:

func WTSQuerySessionInformation(hServer syscall.Handle, sessionId uint32, WTSInfoClass WTS_INFO_CLASS) (sess1buf [256]uint16, err error) {
    buflen := 0
    r1, _, e1 := procWTSQuerySessionInformation.Call(
        uintptr(hServer),
        uintptr(sessionId),
        uintptr(WTSInfoClass),
        uintptr(unsafe.Pointer(&sess1buf[0])),
        uintptr(unsafe.Pointer(&buflen)))
    if int(r1) == 0 {
        err = os.NewSyscallError("WTSQuerySessionInformation", e1)
    }
    fmt.Println("sess1buf:",sess1buf)
    return
}

I figured it out using go generate to expose windows apis:

//sys   WTSGetActiveConsoleSessionId() (sid uint32)
//sys   WTSQuerySessionInformation(hServer syscall.Handle, sid uint32, WTSInfoClass WTS_INFO_CLASS, buffer *uintptr, bytesReturned *uint32) (err error) [failretval==0] = wtsapi32.WTSQuerySessionInformationW
//sys   WTSFreeMemory(buffer uintptr) = wtsapi32.WTSFreeMemory

const WTS_CURRENT_SERVER_HANDLE = 0
const WTSDomainName = 7

sid := WTSGetActiveConsoleSessionId()

var buffer uintptr
var bytesReturned uint32
err := WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sid, WTSDomainName, &buffer, &bytesReturned);
if err != nil || bytesReturned <= 0 {
    return false
}
defer WTSFreeMemory(buffer)

WTSType := *(*uint32)(unsafe.Pointer(buffer))

....

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.