Jump to content

DllCall and returned pointers?

Recommended Posts

hello forum,

i'm currently struggling with reading the return values from DllCall()

Func _CheckIfRemoteSession()
    ;# uses WTSQuerySessionInformation from "Wtsapi32.dll" - see http://msdn.microsoft.com/en-us/library/windows/desktop/aa383838%28v=vs.85%29.aspx
    ;# BOOL WTSQuerySessionInformation(
    ;#   __in   HANDLE hServer,
    ;#   __in   DWORD SessionId,
    ;#   __in   WTS_INFO_CLASS WTSInfoClass,
    ;#   __out  LPTSTR *ppBuffer,
    ;#   __out  DWORD *pBytesReturned
    ;# );

    ;# example how to use pinvoke (csharp):
    ;#  [DllImport("Wtsapi32.dll")]
    ;#  public static extern bool WTSQuerySessionInformation(System.IntPtr hServer, int sessionId, WTSInfoClass wtsInfoClass, out System.IntPtr ppBuffer, out uint pBytesReturned);

    Local Const $WTS_CURRENT_SESSION = -1
    Local Const $WTSClientProtocolType = 16
    Local $buffer = -1
    Local $bytesReturned = -1

    Local $retVal = DllCall("Wtsapi32.dll", "int", "WTSQuerySessionInformation", "ptr", 0, "int", $WTS_CURRENT_SESSION, "int", $WTSClientProtocolType, "ptr*", $buffer, "dword*", $bytesReturned)
    If @error Or ($retVal[0] == 0) Then Return (-1)

    MsgBox(0, "DEBUG", "retVal[0]: " & $retVal[0] & ", retVal[4]: " & $retVal[4] & ", retVal[5]: " & $retVal[5] & ", buffer: " & $buffer)

    ;# remote session (RDP) returns "2"
    ;# local sessoin returns "0"

in particular this is what i'm passing in: "ptr*", $buffer

and this is what i'm seeing in the msgbox to display the results:

retVal[0]: - 1 (return value)

retVal[4]: - 0x008F73D0 (the stuff i'm interested in)

retVal[5]: - 2 (BytesReturned)

buffer: -1 (the stuff i'm interested in)

so "0x008F73D0" looks like a pointer ...?

how do i read the value stored at this address?

with pinvoke (csharp) i have seen something like:

value = Marshal.ReadInt32( buffer );

how to achieve the same with autoit? what is it i'm missing?

thanks in advance, francoiste

Link to post
Share on other sites

$Ret = DllCall("wtsapi32.dll", "int", "WTSQuerySessionInformation", "ptr", 0, "int", -1, "uint", 16, "ptr*", 0, "dword*", 0)
ConsoleWrite(DllStructGetData(DllStructCreate('ushort', $Ret[4]), 1) & @CR)
DllCall("wtsapi32.dll", "none", "WTSFreeMemory", 'ptr', $Ret[4])

Link to post
Share on other sites

oh, well. i still don't get it, i'm afraid.

i want to handle scenarios with remote desktop, terminal services, citrix, and alike ...

first step is to gather all user sessions on localhost listing the following attributes:

  • $SessionId
  • $WinStationName
  • $ConnectState
it's all inside "wtsapi32.dll".

so first i need:

BOOL WTSEnumerateSessions(
  __in   HANDLE hServer,
  __in   DWORD Reserved,
  __in   DWORD Version,
  __out  PWTS_SESSION_INFO *ppSessionInfo,
  __out  DWORD *pCount

where it says for ppSessionInfo:

A pointer to a variable that receives a pointer to an array of WTS_SESSION_INFO structures. Each structure in the array contains information about a session on the specified RD Session Host server. To free the returned buffer, call the WTSFreeMemory function.

To enumerate a session, you must have "Query Information" permission.

ok, so this structure array consists of:

typedef struct _WTS_SESSION_INFO {
  DWORD               SessionId;
  LPTSTR                 pWinStationName;

and the WTS_CONNECTSTATE_CLASS is defined as follows:


i completely don't understand how to wrap those arrays and structures into DllStructGetData(DllStructCreate(...), ...)

i'd very much appreciate if someone could assist me in putting that information into the following array:

Local $avArray[3]
$avArray[0] = $SessionId
$avArray[1] = $WinStationName
$avArray[2] = $ConnectState

thanks in advance, francoiste

Link to post
Share on other sites

Global Const $tagWTS_SESSION_INFO = 'dword SessionId;ptr WinStationName;uint State'

$Ret = DllCall('wtsapi32.dll', 'int', 'WTSEnumerateSessionsW', 'ptr', 0, 'dword', 0, 'dword', 1, 'ptr*', 0, 'dword*', 0)

$Offset = 0
For $i = 1 To $Ret[5]
    $tInfo = DllStructCreate($tagWTS_SESSION_INFO, $Ret[4] + $Offset)
    $Offset += DllStructGetSize($tInfo)
    ConsoleWrite('SessionId:      ' & DllStructGetData($tInfo, 'SessionId') & @CR)
    ConsoleWrite('WinStationName: ' & DllStructGetData(DllStructCreate('wchar[1024]', DllStructGetData($tInfo, 'WinStationName')), 1) & @CR)
    ConsoleWrite('State:          ' & DllStructGetData($tInfo, 'State') & @CR)
    ConsoleWrite('--------------' & @CR)

DllCall('wtsapi32.dll', 'none', 'WTSFreeMemory', 'ptr', $Ret[4])

Of course, you need to check for errors but you can do it yourself.

Edited by Yashied
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...