' ########################################################################################
' Microsoft Windows
' File: WtsApi32.inc
' Contents: Windows Terminal Server public APIs
' Copyright (c) 2011 Jos? Roca
' Portions Copyright (c) Microsoft Corporation.
' All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#IF NOT %DEF(PBX_WtsApi32_PBI)
#DEFINE PBX_WtsApi32_PBI
%EQUATE `WTSAPI32_INC = 1
#INCLUDE ONCE "Legacy/System/WTypes.inc"
#INCLUDE ONCE "Core/Windows.inc"
'/*===================================================================
'== Defines
'=====================================================================*/
'/*
' * Specifies the current server
' */
'#define WTS_CURRENT_SERVER ((HANDLE)NULL)
'#define WTS_CURRENT_SERVER_HANDLE ((HANDLE)NULL)
'#define WTS_CURRENT_SERVER_NAME (NULL)
%EQUATE `WTS_CURRENT_SERVER = 0
%EQUATE `WTS_CURRENT_SERVER_HANDLE = 0
$WTS_CURRENT_SERVER_NAME = ""
'/*
' * Specifies the current session (SessionId)
' */
'#define WTS_CURRENT_SESSION ((DWORD)-1)
%EQUATE `WTS_CURRENT_SESSION = &HFFFFFFFF
'/*
' * Specifies any-session (SessionId)
' */
'#define WTS_ANY_SESSION ((DWORD)-2)
%EQUATE `WTS_ANY_SESSION = &HFFFFFFFE
'/*
' * Possible pResponse values from WTSSendMessage()
' */
#IF NOT %DEF(%IDTIMEOUT)
%EQUATE `IDTIMEOUT = 32000
#ENDIF
#IF NOT %DEF(%IDASYNC)
%EQUATE `IDASYNC = 32001
#ENDIF
'#ifndef __HYDRIX_H__
%EQUATE `USERNAME_LENGTH = 20
%EQUATE `CLIENTNAME_LENGTH = 20
%EQUATE `CLIENTADDRESS_LENGTH = 30
'#endif
'/*
' * Shutdown flags
' */
%EQUATE `WTS_WSD_LOGOFF = &H00000001 ' // log off all users except
 ' // current user; deletes
 ' // WinStations (a reboot is
 ' // required to recreate the
 ' // WinStations)
%EQUATE `WTS_WSD_SHUTDOWN = &H00000002 ' // shutdown system
%EQUATE `WTS_WSD_REBOOT = &H00000004 ' // shutdown and reboot
%EQUATE `WTS_WSD_POWEROFF = &H00000008 ' // shutdown and power off (on
 ' // machines that support power
 ' // off through software)
%EQUATE `WTS_WSD_FASTREBOOT = &H00000010 ' // reboot without logging users
 ' // off or shutting down
%EQUATE `MAX_ELAPSED_TIME_LENGTH = 15
%EQUATE `MAX_DATE_TIME_LENGTH = 56
%EQUATE `WINSTATIONNAME_LENGTH = 32
%EQUATE `DOMAIN_LENGTH = 17
%EQUATE `WTS_DRIVE_LENGTH = 3
%EQUATE `WTS_LISTENER_NAME_LENGTH = 32
%EQUATE `WTS_COMMENT_LENGTH = 60
'/*
' * Flags for WTSCreateListener
' */
%EQUATE `WTS_LISTENER_CREATE = &H00000001
%EQUATE `WTS_LISTENER_UPDATE = &H00000010
'/*********************************
' * Listener access values
' *********************************/
%EQUATE `WTS_SECURITY_QUERY_INFORMATION = &H00000001
%EQUATE `WTS_SECURITY_SET_INFORMATION = &H00000002
%EQUATE `WTS_SECURITY_RESET = &H00000004
%EQUATE `WTS_SECURITY_VIRTUAL_CHANNELS = &H00000008
%EQUATE `WTS_SECURITY_REMOTE_CONTROL = &H00000010
%EQUATE `WTS_SECURITY_LOGON = &H00000020
%EQUATE `WTS_SECURITY_LOGOFF = &H00000040
%EQUATE `WTS_SECURITY_MESSAGE = &H00000080
%EQUATE `WTS_SECURITY_CONNECT = &H00000100
%EQUATE `WTS_SECURITY_DISCONNECT = &H00000200
%EQUATE `WTS_SECURITY_GUEST_ACCESS = %WTS_SECURITY_LOGON
%EQUATE `WTS_SECURITY_CURRENT_GUEST_ACCESS = %WTS_SECURITY_VIRTUAL_CHANNELS OR %WTS_SECURITY_LOGOFF
%EQUATE `WTS_SECURITY_USER_ACCESS = %WTS_SECURITY_CURRENT_GUEST_ACCESS OR %WTS_SECURITY_QUERY_INFORMATION OR %WTS_SECURITY_CONNECT
%EQUATE `WTS_SECURITY_CURRENT_USER_ACCESS = %WTS_SECURITY_SET_INFORMATION OR %WTS_SECURITY_RESET OR %WTS_SECURITY_VIRTUAL_CHANNELS OR %WTS_SECURITY_LOGOFF OR %WTS_SECURITY_DISCONNECT
%EQUATE `WTS_SECURITY_ALL_ACCESS = %STANDARD_RIGHTS_REQUIRED OR %WTS_SECURITY_QUERY_INFORMATION OR %WTS_SECURITY_SET_INFORMATION OR %WTS_SECURITY_RESET OR %WTS_SECURITY_VIRTUAL_CHANNELS OR %WTS_SECURITY_REMOTE_CONTROL OR %WTS_SECURITY_LOGON OR %WTS_SECURITY_MESSAGE OR %WTS_SECURITY_CONNECT OR %WTS_SECURITY_DISCONNECT
'/*===================================================================
'== WTS_CONNECTSTATE_CLASS - Session connect state
'=====================================================================*/
' enum WTS_CONNECTSTATE_CLASS
%EQUATE `WTSActive = 0 ' // User logged on to WinStation
%EQUATE `WTSConnected = 1 ' // WinStation connected to client
%EQUATE `WTSConnectQuery = 2 ' // In the process of connecting to client
%EQUATE `WTSShadow = 3 ' // Shadowing another WinStation
%EQUATE `WTSDisconnected = 4 ' // WinStation logged on without client
%EQUATE `WTSIdle = 5 ' // Waiting for client to connect
%EQUATE `WTSListen = 6 ' // WinStation is listening for connection
%EQUATE `WTSReset = 7 ' // WinStation is being reset
%EQUATE `WTSDown = 8 ' // WinStation is down due to error
%EQUATE `WTSInit = 9 ' // WinStation in initialization
'/*=====================================================================
'== WTS_SERVER_INFO - returned by WTSEnumerateServers (version 1)
'=====================================================================*/
'/*
' * WTSEnumerateServers() returns two variables: pServerInfo and Count.
' * The latter is the number of WTS_SERVER_INFO structures contained in
' * the former. In order to read each server, iterate i from 0 to
' * Count-1 and reference the server name as
' * pServerInfo[i].pServerName; for example:
' *
' * for ( i=0; i < Count; i++ ) {
' * _tprintf( TEXT("%s "), pServerInfo[i].pServerName );
' * }
' *
' * The memory returned looks like the following. P is a pServerInfo
' * pointer, and D is the string data for that pServerInfo:
' *
' * P1 P2 P3 P4 ... Pn D1 D2 D3 D4 ... Dn
' *
' * This makes it easier to iterate the servers, using code similar to
' * the above.
' */
' // Size = 4 bytes
TYPE WTS_SERVER_INFOW DWORD
 pServerName AS WSTRINGZ PTR ' LPWSTR // server name
END TYPE
' // Size = 4 bytes
TYPE WTS_SERVER_INFOA DWORD
 pServerName AS ASCIIZ PTR ' LPSTR // server name
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTS_SERVER_INFO = WTS_SERVER_INFOW
#ELSE
 MACRO WTS_SERVER_INFO = WTS_SERVER_INFOA
#ENDIF
''/*=====================================================================
''== WTS_SESSION_INFO - returned by WTSEnumerateSessions (version 1)
''=====================================================================*/
'/*
' * WTSEnumerateSessions() returns data in a similar format to the above
' * WTSEnumerateServers(). It returns two variables: pSessionInfo and
' * Count. The latter is the number of WTS_SESSION_INFO structures
' * contained in the former. Iteration is similar, except that there
' * are three parts to each entry, so it would look like this:
' *
' * for ( i=0; i < Count; i++ ) {
' * _tprintf( TEXT("%-5u %-20s %u\n"),
' pSessionInfo[i].SessionId,
' * pSessionInfo[i].pWinStationName,
' * pSessionInfo[i].State );
' * }
' *
' * The memory returned is also segmented as the above, with all the
' * structures allocated at the start and the string data at the end.
' * We'll use S for the SessionId, P for the pWinStationName pointer
' * and D for the string data, and C for the connect State:
' *
' * S1 P1 C1 S2 P2 C2 S3 P3 C3 S4 P4 C4 ... Sn Pn Cn D1 D2 D3 D4 ... Dn
' *
' * As above, this makes it easier to iterate the sessions.
' */
' // Size = 12 bytes
TYPE WTS_SESSION_INFOW DWORD
 SessionId AS DWORD ' DWORD // session id
 pWinStationName AS WSTRINGZ PTR ' LPWSTR // name of WinStation this session is connected to
 State AS LONG ' WTS_CONNECTSTATE_CLASS // connection state (see enum)
END TYPE
' // Size = 12 bytes
TYPE WTS_SESSION_INFOA DWORD
 SessionId AS DWORD ' DWORD // session id
 pWinStationName AS ASCIIZ PTR ' LPSTR // name of WinStation this session is connected to
 State AS LONG ' WTS_CONNECTSTATE_CLASS // connection state (see enum)
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTS_SESSION_INFO = WTS_SERVER_INFOW
#ELSE
 MACRO WTS_SESSION_INFO = WTS_SESSION_INFOA
#ENDIF
' // Size = 32 bytes
TYPE WTS_SESSION_INFO_1W DWORD
 ExecEnvId AS DWORD
 State AS LONG ' WTS_CONNECTSTATE_CLASS
 SessionId AS DWORD
 pSessionName AS WSTRINGZ PTR
 pHostName AS WSTRINGZ PTR
 pUserName AS WSTRINGZ PTR
 pDomainName AS WSTRINGZ PTR
 pFarmName AS WSTRINGZ PTR
END TYPE
' // Size = 32 bytes
TYPE WTS_SESSION_INFO_1A DWORD
 ExecEnvId AS DWORD
 State AS LONG ' WTS_CONNECTSTATE_CLASS
 SessionId AS DWORD
 pSessionName AS ASCIIZ PTR
 pHostName AS ASCIIZ PTR
 pUserName AS ASCIIZ PTR
 pDomainName AS ASCIIZ PTR
 pFarmName AS ASCIIZ PTR
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTS_SESSION_INFO_1 = WTS_SESSION_INFO_1W
#ELSE
 MACRO WTS_SESSION_INFO_1 = WTS_SESSION_INFO_1A
#ENDIF
'/*=====================================================================
'== WTS_PROCESS_INFO - returned by WTSEnumerateProcesses (version 1)
'=====================================================================*/
'/*
' * WTSEnumerateProcesses() also returns data similar to
' * WTSEnumerateServers(). It returns two variables: pProcessInfo and
' * Count. The latter is the number of WTS_PROCESS_INFO structures
' * contained in the former. Iteration is similar, except that there
' * are four parts to each entry, so it would look like this:
' *
' * for ( i=0; i < Count; i++ ) {
' * GetUserNameFromSid( pProcessInfo[i].pUserSid, UserName,
' * sizeof(UserName) );
' * _tprintf( TEXT("%-5u %-20s %-5u %s\n"),
' * pProcessInfo[i].SessionId,
' * UserName,
' * pProcessInfo[i].ProcessId,
' * pProcessInfo[i].pProcessName );
' * }
' *
' * The memory returned is also segmented as the above, with all the
' * structures allocated at the start and the string data at the end.
' * We'll use S for the SessionId, R for the ProcessId, P for the
' * pProcessName pointer and D for the string data, and U for pUserSid:
' *
' * S1 R1 P1 U1 S2 R2 P2 U2 S3 R3 P3 U3 ... Sn Rn Pn Un D1 D2 D3 ... Dn
' *
' * As above, this makes it easier to iterate the processes.
' */
' // Size = 16 bytes
TYPE WTS_PROCESS_INFOW DWORD
 SessionId AS DWORD ' DWORD // session id
 ProcessId AS DWORD ' DWORD // process id
 pProcessName AS WSTRINGZ PTR ' LPWSTR // name of process
 pUserSid AS SID PTR ' PSID // user's SID
END TYPE
' // Size = 16 bytes
TYPE WTS_PROCESS_INFOA DWORD
 SessionId AS DWORD ' DWORD // session id
 ProcessId AS DWORD ' DWORD // process id
 pProcessName AS ASCIIZ PTR ' LPSTR // name of process
 pUserSid AS SID PTR ' PSID // user's SID
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTS_PROCESS_INFO = WTS_PROCESS_INFOW
#ELSE
 MACRO WTS_PROCESS_INFO = WTS_PROCESS_INFOA
#ENDIF
'/*=====================================================================
'== WTS_INFO_CLASS - WTSQuerySessionInformation
'== (See additional typedefs for more info on structures)
'=====================================================================*/
%EQUATE `WTS_PROTOCOL_TYPE_CONSOLE = 0 ' // Console
%EQUATE `WTS_PROTOCOL_TYPE_ICA = 1 ' // ICA Protocol
%EQUATE `WTS_PROTOCOL_TYPE_RDP = 2 ' // RDP Protocol
' enum WTS_INFO_CLASS
%EQUATE `WTSInitialProgram = 0
%EQUATE `WTSApplicationName = 1
%EQUATE `WTSWorkingDirectory = 2
%EQUATE `WTSOEMId = 3
%EQUATE `WTSSessionId = 4
%EQUATE `WTSUserName = 5
%EQUATE `WTSWinStationName = 6
%EQUATE `WTSDomainName = 7
%EQUATE `WTSConnectState = 8
%EQUATE `WTSClientBuildNumber = 9
%EQUATE `WTSClientName = 10
%EQUATE `WTSClientDirectory = 11
%EQUATE `WTSClientProductId = 12
%EQUATE `WTSClientHardwareId = 13
%EQUATE `WTSClientAddress = 14
%EQUATE `WTSClientDisplay = 15
%EQUATE `WTSClientProtocolType = 16
%EQUATE `WTSIdleTime = 17
%EQUATE `WTSLogonTime = 18
%EQUATE `WTSIncomingBytes = 19
%EQUATE `WTSOutgoingBytes = 20
%EQUATE `WTSIncomingFrames = 21
%EQUATE `WTSOutgoingFrames = 22
%EQUATE `WTSClientInfo = 23
%EQUATE `WTSSessionInfo = 24
%EQUATE `WTSSessionInfoEx = 25
%EQUATE `WTSConfigInfo = 26
%EQUATE `WTSValidationInfo = 27 ' // Info Class value used to fetch Validation Information through the WTSQuerySessionInformation
%EQUATE `WTSSessionAddressV4 = 28
%EQUATE `WTSIsRemoteSession = 29
'/*=====================================================================
'== WTS Config Information
'=====================================================================*/
' // Size = 1668 bytes
TYPE WTSCONFIGINFOW BYTE
 version AS DWORD ' ULONG
 fConnectClientDrivesAtLogon AS DWORD ' ULONG
 fConnectPrinterAtLogon AS DWORD ' ULONG
 fDisablePrinterRedirection AS DWORD ' ULONG
 fDisableDefaultMainClientPrinter AS DWORD ' ULONG
 ShadowSettings AS DWORD ' ULONG
 LogonUserName AS WSTRINGZ * %USERNAME_LENGTH + 1 ' WCHAR
 LogonDomain AS WSTRINGZ * %DOMAIN_LENGTH + 1 ' WCHAR
 WorkDirectory AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 InitialProgram AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 ApplicationName AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
END TYPE
' // Size = 848 bytes
TYPE WTSCONFIGINFOA BYTE
 version AS DWORD ' ULONG
 fConnectClientDrivesAtLogon AS DWORD ' ULONG
 fConnectPrinterAtLogon AS DWORD ' ULONG
 fDisablePrinterRedirection AS DWORD ' ULONG
 fDisableDefaultMainClientPrinter AS DWORD ' ULONG
 ShadowSettings AS DWORD ' ULONG
 LogonUserName AS ASCIIZ * %USERNAME_LENGTH + 1 ' CHAR
 LogonDomain AS ASCIIZ * %DOMAIN_LENGTH + 1 ' CHAR
 WorkDirectory AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 InitialProgram AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 ApplicationName AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 alignment__ AS WORD ' // To keep DWORD alignment
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTSCONFIGINFO = WTSCONFIGINFOW
#ELSE
 MACRO WTSCONFIGINFO = WTSCONFIGINFOA
#ENDIF
'/*=====================================================================
'== WTS Session Information
'=====================================================================*/
' // Size = 216 bytes
TYPE WTSINFOW QWORD FILL ' Must be 8 byte aligned
 State AS LONG ' WTS_CONNECTSTATE_CLASS // connection state (see enum)
 SessionId AS DWORD ' DWORD // session id
 IncomingBytes AS DWORD
 OutgoingBytes AS DWORD
 IncomingFrames AS DWORD
 OutgoingFrames AS DWORD
 IncomingCompressedBytes AS DWORD
 OutgoingCompressedBytes AS DWORD
 WinStationName AS WSTRINGZ * %WINSTATIONNAME_LENGTH ' WCHAR
 Domain AS WSTRINGZ * %DOMAIN_LENGTH ' WCHAR
 UserName AS WSTRINGZ * %USERNAME_LENGTH + 1 ' WCHAR // name of WinStation this session is
 ' // connected to
 ConnectTime AS QUAD ' LARGE_INTEGER
 DisconnectTime AS QUAD ' LARGE_INTEGER
 LastInputTime AS QUAD ' LARGE_INTEGER
 LogonTime AS QUAD ' LARGE_INTEGER
 CurrentTime AS QUAD ' LARGE_INTEGER
END TYPE
'/*=====================================================================
'== WTS Session Information
'=====================================================================*/
' // Size = 144 bytes
TYPE WTSINFOA QWORD FILL
 State AS LONG ' WTS_CONNECTSTATE_CLASS // connection state (see enum)
 SessionId AS DWORD ' DWORD // session id
 IncomingBytes AS DWORD
 OutgoingBytes AS DWORD
 IncomingFrames AS DWORD
 OutgoingFrames AS DWORD
 IncomingCompressedBytes AS DWORD
 OutgoingCompressedBytes AS DWORD
 WinStationName AS ASCIIZ * %WINSTATIONNAME_LENGTH ' CHAR
 Domain AS ASCIIZ * %DOMAIN_LENGTH ' CHAR
 UserName AS ASCIIZ * %USERNAME_LENGTH + 1 ' CHAR // name of WinStation this session is
 ' // connected to
 ConnectTime AS QUAD ' LARGE_INTEGER
 DisconnectTime AS QUAD ' LARGE_INTEGER
 LastInputTime AS QUAD ' LARGE_INTEGER
 LogonTime AS QUAD ' LARGE_INTEGER
 CurrentTime AS QUAD ' LARGE_INTEGER
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTSINFO = WTSINFOW
#ELSE
 MACRO WTSINFO = WTSINFOA
#ENDIF
'/*=====================================================================
'== WTS Extended Session State Flags
'=====================================================================*/
%EQUATE `WTS_SESSIONSTATE_UNKNOWN = &HFFFFFFFF
%EQUATE `WTS_SESSIONSTATE_LOCK = &H00000000
%EQUATE `WTS_SESSIONSTATE_UNLOCK = &H00000001
'/*=====================================================================
'== WTS Extended Session Information
'=====================================================================*/
' // Size = 224 bytes
TYPE WTSINFOEX_LEVEL1_W QWORD FILL
 SessionId AS DWORD ' ULONG
 SessionState AS LONG ' WTS_CONNECTSTATE_CLASS
 SessionFlags AS LONG
 WinStationName AS WSTRINGZ * %WINSTATIONNAME_LENGTH + 1 ' WCHAR
 UserName AS WSTRINGZ * %USERNAME_LENGTH + 1 ' WCHAR
 DomainName AS WSTRINGZ * %DOMAIN_LENGTH + 1 ' WCHAR
 LogonTime AS QUAD ' LARGE_INTEGER
 ConnectTime AS QUAD ' LARGE_INTEGER
 DisconnectTime AS QUAD ' LARGE_INTEGER
 LastInputTime AS QUAD ' LARGE_INTEGER
 CurrentTime AS QUAD ' LARGE_INTEGER
 IncomingBytes AS DWORD
 OutgoingBytes AS DWORD
 IncomingFrames AS DWORD
 OutgoingFrames AS DWORD
 IncomingCompressedBytes AS DWORD
 OutgoingCompressedBytes AS DWORD
END TYPE
' // Size = 152 bytes
TYPE WTSINFOEX_LEVEL1_A QWORD FILL
 SessionId AS DWORD ' ULONG
 SessionState AS LONG ' WTS_CONNECTSTATE_CLASS
 SessionFlags AS LONG
 WinStationName AS ASCIIZ * %WINSTATIONNAME_LENGTH + 1 ' CHAR
 UserName AS ASCIIZ * %USERNAME_LENGTH + 1 ' CHAR
 DomainName AS ASCIIZ * %DOMAIN_LENGTH + 1 ' CHAR
 LogonTime AS QUAD ' LARGE_INTEGER
 ConnectTime AS QUAD ' LARGE_INTEGER
 DisconnectTime AS QUAD ' LARGE_INTEGER
 LastInputTime AS QUAD ' LARGE_INTEGER
 CurrentTime AS QUAD ' LARGE_INTEGER
 IncomingBytes AS DWORD
 OutgoingBytes AS DWORD
 IncomingFrames AS DWORD
 OutgoingFrames AS DWORD
 IncomingCompressedBytes AS DWORD
 OutgoingCompressedBytes AS DWORD
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTSINFOEX_LEVEL1 = WTSINFOEX_LEVEL1_W
#ELSE
 MACRO WTSINFOEX_LEVEL1 = WTSINFOEX_LEVEL1_A
#ENDIF
' // Size = 224 bytes
UNION WTSINFOEX_LEVEL_W
 WTSInfoExLevel1 AS WTSINFOEX_LEVEL1_W
END UNION
' // Size = 152 bytes
UNION WTSINFOEX_LEVEL_A
 WTSInfoExLevel1 AS WTSINFOEX_LEVEL1_A
END UNION
#IF %DEF(%UNICODE)
 MACRO WTSINFOEX_LEVEL = WTSINFOEX_LEVEL1_W
#ELSE
 MACRO WTSINFOEX_LEVEL = WTSINFOEX_LEVEL1_A
#ENDIF
' // Size = 232 bytes
TYPE WTSINFOEXW QWORD FILL
 Level AS DWORD
 Data AS WTSINFOEX_LEVEL_W
END TYPE
' // Size = 232 bytes
TYPE WTSINFOEXA QWORD FILL
 Level AS DWORD
 Data AS WTSINFOEX_LEVEL_A
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTSINFOEX = WTSINFOEXW
#ELSE
 MACRO WTSINFOEX = WTSINFOEXA
#ENDIF
'/*=====================================================================
'== WTS Client Information
'=====================================================================*/
' // Size = 2304 bytes
TYPE WTSCLIENTW DWORD FILL
 ClientName AS WSTRINGZ * %CLIENTNAME_LENGTH + 1 ' WCHAR
 Domain AS WSTRINGZ * %DOMAIN_LENGTH + 1 ' WCHAR
 UserName AS WSTRINGZ * %USERNAME_LENGTH + 1 ' WCHAR
 WorkDirectory AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 InitialProgram AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 EncryptionLevel AS BYTE ' BYTE // security level of encryption pd
 ClientAddressFamily AS DWORD ' ULONG
 ClientAddress(%CLIENTADDRESS_LENGTH) AS WORD ' USHORT
 HRes AS WORD ' USHORT
 VRes AS WORD ' USHORT
 ColorDepth AS WORD ' USHORT
 ClientDirectory AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 ClientBuildNumber AS DWORD ' ULONG
 ClientHardwareId AS DWORD ' ULONG // client software serial number
 ClientProductId AS WORD ' USHORT // client software product id
 OutBufCountHost AS WORD ' USHORT // number of outbufs on host
 OutBufCountClient AS WORD ' USHORT // number of outbufs on client
 OutBufLength AS WORD ' USHORT // length of outbufs in bytes
 DeviceId AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 alignment__ AS WORD ' // To keep DWORD alignment
END TYPE
'/*=====================================================================
'== WTS Client Information
'=====================================================================*/
' // Size = 1200 bytes
TYPE WTSCLIENTA DWORD FILL
 ClientName AS ASCIIZ * %CLIENTNAME_LENGTH + 1 ' CHAR
 Domain AS ASCIIZ * %DOMAIN_LENGTH + 1 ' CHAR
 UserName AS ASCIIZ * %USERNAME_LENGTH + 1 ' CHAR
 WorkDirectory AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 InitialProgram AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 EncryptionLevel AS BYTE ' BYTE // security level of encryption pd
 ClientAddressFamily AS DWORD ' ULONG
 ClientAddress(%CLIENTADDRESS_LENGTH) AS WORD ' USHORT
 HRes AS WORD ' USHORT
 VRes AS WORD ' USHORT
 ColorDepth AS WORD ' USHORT
 ClientDirectory AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 ClientBuildNumber AS DWORD ' ULONG
 ClientHardwareId AS DWORD ' ULONG // client software serial number
 ClientProductId AS WORD ' USHORT // client software product id
 OutBufCountHost AS WORD ' USHORT // number of outbufs on host
 OutBufCountClient AS WORD ' USHORT // number of outbufs on client
 OutBufLength AS WORD ' USHORT // length of outbufs in bytes
 DeviceId AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 alignment__(2) AS BYTE ' // To keep DWORD alignment
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTSCLIENT = WTSCLIENTW
#ELSE
 MACRO WTSCLIENT = WTSCLIENTA
#ENDIF
'/*=====================================================================
'== WTS License Validation Information - Product Information
'=====================================================================*/
%EQUATE `PRODUCTINFO_COMPANYNAME_LENGTH = 256
%EQUATE `PRODUCTINFO_PRODUCTID_LENGTH = 4
' // Size = 260 bytes
TYPE PRODUCT_INFOA BYTE
 CompanyName AS ASCIIZ * %PRODUCTINFO_COMPANYNAME_LENGTH ' CHAR
 ProductID AS ASCIIZ * %PRODUCTINFO_PRODUCTID_LENGTH ' CHAR
END TYPE
MACRO WTS_PRODUCT_INFOA = PRODUCT_INFOA
' // Size = 520 bytes
TYPE PRODUCT_INFOW BYTE
 CompanyName AS WSTRINGZ * %PRODUCTINFO_COMPANYNAME_LENGTH ' WCHAR
 ProductID AS WSTRINGZ * %PRODUCTINFO_PRODUCTID_LENGTH ' WCHAR
END TYPE
MACRO WTS_PRODUCT_INFOW = PRODUCT_INFOW
#IF %DEF(%UNICODE)
 MACRO PRODUCT_INFO = PRODUCT_INFOW
 MACRO WTS_PRODUCT_INFO = WTS_PRODUCT_INFOW
#ELSE
 MACRO PRODUCT_INFO = PRODUCT_INFOA
 MACRO WTS_PRODUCT_INFO = WTS_PRODUCT_INFOA
#ENDIF
'/*=====================================================================
' WTS License Validation Information
' This structure will be returned from WTSQuerySessionInformation when the user
' queries for license validation information.
'=====================================================================*/
%EQUATE `VALIDATIONINFORMATION_LICENSE_LENGTH = 16384 ' //16 Kb
%EQUATE `VALIDATIONINFORMATION_HARDWAREID_LENGTH = 20
UNION WTS_VALIDATION_INFORMATIONA_LICENSE_UNION
 License AS STRING * %VALIDATIONINFORMATION_LICENSE_LENGTH ' BYTE
 ' // For compatibility with the PB declares
 License(%VALIDATIONINFORMATION_LICENSE_LENGTH-1) AS BYTE
END UNION
UNION WTS_VALIDATION_INFORMATIONA_HARDWAREID_UNION
 HardwareID AS STRING * %VALIDATIONINFORMATION_HARDWAREID_LENGTH ' BYTE
 ' // For compatibility with the PB declares
 HardwareID(%VALIDATIONINFORMATION_HARDWAREID_LENGTH-1) AS BYTE
END UNION
' // Size = 16672 bytes
TYPE WTS_VALIDATION_INFORMATIONA BYTE
 ProductInfo AS PRODUCT_INFOA
 WTS_VALIDATION_INFORMATIONA_LICENSE_UNION
 LicenseLength AS DWORD
 WTS_VALIDATION_INFORMATIONA_HARDWAREID_UNION
 HardwareIDLength AS DWORD
END TYPE
UNION WTS_VALIDATION_INFORMATIONW_LICENSE_UNION
 License AS STRING * %VALIDATIONINFORMATION_LICENSE_LENGTH ' BYTE
 ' // For compatibility with the PB declares
 License(%VALIDATIONINFORMATION_LICENSE_LENGTH-1) AS BYTE
END UNION
UNION WTS_VALIDATION_INFORMATIONW_HARDWAREID_UNION
 HardwareID AS STRING * %VALIDATIONINFORMATION_HARDWAREID_LENGTH ' BYTE
 ' // For compatibility with the PB declares
 HardwareID(%VALIDATIONINFORMATION_HARDWAREID_LENGTH-1) AS BYTE
END UNION
' // Size = 16932 bytes
TYPE WTS_VALIDATION_INFORMATIONW BYTE
 ProductInfo AS PRODUCT_INFOW
 WTS_VALIDATION_INFORMATIONW_LICENSE_UNION
 LicenseLength AS DWORD
 WTS_VALIDATION_INFORMATIONW_HARDWAREID_UNION
 HardwareIDLength AS DWORD
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTS_VALIDATION_INFORMATION = WTS_VALIDATION_INFORMATIONW
#ELSE
 MACRO WTS_VALIDATION_INFORMATION = WTS_VALIDATION_INFORMATIONA
#ENDIF
'/*=====================================================================
'== WTSQuerySessionInformation - (WTSClientAddress)
'=====================================================================*/
UNION WTS_CLIENT_ADDRESS_UNION
 Address AS STRING * 20 ' BYTE [20] // client network address
 Address(19) AS BYTE ' client network address
END UNION
' // Size = 24 bytes
TYPE WTS_CLIENT_ADDRESS BYTE
 AddressFamily AS DWORD ' DWORD // AF_INET, AF_INET6, AF_IPX, AF_NETBIOS, AF_UNSPEC
 WTS_CLIENT_ADDRESS_UNION
END TYPE
'/*=====================================================================
'== WTSQuerySessionInformation - (WTSClientDisplay)
'=====================================================================*/
' // Size = 12 bytes
TYPE WTS_CLIENT_DISPLAY DWORD
 HorizontalResolution AS DWORD ' DWORD // horizontal dimensions, in pixels
 VerticalResolution AS DWORD ' DWORD // vertical dimensions, in pixels
 ColorDepth AS DWORD ' DWORD // 1=16, 2=256, 4=64K, 8=16M
END TYPE
'/*=====================================================================
'== WTS_CONFIG_CLASS - WTSQueryUserConfig/WTSSetUserConfig
'=====================================================================*/
' enum _WTS_CONFIG_CLASS
' //Initial program settings
%EQUATE `WTSUserConfigInitialProgram = 0 ' // string returned/expected
%EQUATE `WTSUserConfigWorkingDirectory = 1 ' // string returned/expected
%EQUATE `WTSUserConfigfInheritInitialProgram = 2 ' // DWORD returned/expected
' //
%EQUATE `WTSUserConfigfAllowLogonTerminalServer = 3 ' //DWORD returned/expected
' //Timeout settings
%EQUATE `WTSUserConfigTimeoutSettingsConnections = 4 ' //DWORD returned/expected
%EQUATE `WTSUserConfigTimeoutSettingsDisconnections = 5 ' //DWORD returned/expected
%EQUATE `WTSUserConfigTimeoutSettingsIdle = 6 ' //DWORD returned/expected
' //Client device settings
%EQUATE `WTSUserConfigfDeviceClientDrives = 7 ' //DWORD returned/expected
%EQUATE `WTSUserConfigfDeviceClientPrinters = 8 ' //DWORD returned/expected
%EQUATE `WTSUserConfigfDeviceClientDefaultPrinter = 9 ' //DWORD returned/expected
' //Connection settings
%EQUATE `WTSUserConfigBrokenTimeoutSettings = 10 ' //DWORD returned/expected
%EQUATE `WTSUserConfigReconnectSettings = 11 ' //DWORD returned/expected
' //Modem settings
%EQUATE `WTSUserConfigModemCallbackSettings = 12 ' //DWORD returned/expected
%EQUATE `WTSUserConfigModemCallbackPhoneNumber = 13 ' // string returned/expected
' //Shadow settings
%EQUATE `WTSUserConfigShadowingSettings = 14 ' //DWORD returned/expected
' //User Profile settings
%EQUATE `WTSUserConfigTerminalServerProfilePath = 15 ' // string returned/expected
' //Terminal Server home directory
%EQUATE `WTSUserConfigTerminalServerHomeDir = 16 ' // string returned/expected
%EQUATE `WTSUserConfigTerminalServerHomeDirDrive = 17 ' // string returned/expected
%EQUATE `WTSUserConfigfTerminalServerRemoteHomeDir = 18 ' // DWORD 0:LOCAL 1:REMOTE
%EQUATE `WTSUserConfigUser = 19 ' // returns WTSUSERCONFIG struct
' enum WTS_CONFIG_SOURCE
%EQUATE `WTSUserConfigSourceSAM = 0
' // Size = 1100 bytes
TYPE WTSUSERCONFIGA BYTE
 Source AS DWORD
 InheritInitialProgram AS DWORD
 AllowLogonTerminalServer AS DWORD
 TimeoutSettingsConnections AS DWORD
 TimeoutSettingsDisconnections AS DWORD
 TimeoutSettingsIdle AS DWORD
 DeviceClientDrives AS DWORD
 DeviceClientPrinters AS DWORD
 ClientDefaultPrinter AS DWORD
 BrokenTimeoutSettings AS DWORD
 ReconnectSettings AS DWORD
 ShadowingSettings AS DWORD
 TerminalServerRemoteHomeDir AS DWORD
 InitialProgram AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 WorkDirectory AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 TerminalServerProfilePath AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 TerminalServerHomeDir AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 TerminalServerHomeDirDrive AS ASCIIZ * %WTS_DRIVE_LENGTH + 1 ' CHAR
END TYPE
' // Size = 2148 bytes
TYPE WTSUSERCONFIGW BYTE
 Source AS DWORD
 InheritInitialProgram AS DWORD
 AllowLogonTerminalServer AS DWORD
 TimeoutSettingsConnections AS DWORD
 TimeoutSettingsDisconnections AS DWORD
 TimeoutSettingsIdle AS DWORD
 DeviceClientDrives AS DWORD
 DeviceClientPrinters AS DWORD
 ClientDefaultPrinter AS DWORD
 BrokenTimeoutSettings AS DWORD
 ReconnectSettings AS DWORD
 ShadowingSettings AS DWORD
 TerminalServerRemoteHomeDir AS DWORD
 InitialProgram AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 WorkDirectory AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 TerminalServerProfilePath AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 TerminalServerHomeDir AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 TerminalServerHomeDirDrive AS WSTRINGZ * %WTS_DRIVE_LENGTH + 1 ' WCHAR
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTSUSERCONFIG = WTSUSERCONFIGW
#ELSE
 MACRO WTSUSERCONFIG = WTSUSERCONFIGA
#ENDIF
'/*=====================================================================
'== WTS_EVENT - Event flags for WTSWaitSystemEvent
'=====================================================================*/
%EQUATE `WTS_EVENT_NONE = &H00000000 ' // return no event
%EQUATE `WTS_EVENT_CREATE = &H00000001 ' // new WinStation created
%EQUATE `WTS_EVENT_DELETE = &H00000002 ' // existing WinStation deleted
%EQUATE `WTS_EVENT_RENAME = &H00000004 ' // existing WinStation renamed
%EQUATE `WTS_EVENT_CONNECT = &H00000008 ' // WinStation connect to client
%EQUATE `WTS_EVENT_DISCONNECT = &H00000010 ' // WinStation logged on without client
%EQUATE `WTS_EVENT_LOGON = &H00000020 ' // user logged on to existing WinStation
%EQUATE `WTS_EVENT_LOGOFF = &H00000040 ' // user logged off from existing WinStation
%EQUATE `WTS_EVENT_STATECHANGE = &H00000080 ' // WinStation state change
%EQUATE `WTS_EVENT_LICENSE = &H00000100 ' // license state change
%EQUATE `WTS_EVENT_ALL = &H7fffffff ' // wait for all event types
%EQUATE `WTS_EVENT_FLUSH = &H80000000 ' // unblock all waiters
'/*=====================================================================
'== Flags for HotkeyModifiers in WTSStartRemoteControlSession
'=====================================================================*/
%EQUATE `REMOTECONTROL_KBDSHIFT_HOTKEY = &H1 ' // Shift key
%EQUATE `REMOTECONTROL_KBDCTRL_HOTKEY = &H2 ' // Ctrl key
%EQUATE `REMOTECONTROL_KBDALT_HOTKEY = &H4 ' // Alt key
'/*=====================================================================
'== WTS_VIRTUAL_CLASS - WTSVirtualChannelQuery
'=====================================================================*/
' enum _WTS_VIRTUAL_CLASS
%EQUATE `WTSVirtualClientData = 0 ' // Virtual channel client module data (C2H data)
%EQUATE `WTSVirtualFileHandle = 1
'/*=====================================================================
'== WTSQuerySessionInformation - (WTSSessionAddress)
'=====================================================================*/
UNION WTS_SESSION_ADDRESS_UNION
 Address AS STRING * 20 ' BYTE [20] // client network address
 Address(19) AS BYTE ' client network address
END UNION
' // Size = 24 bytes
TYPE WTS_SESSION_ADDRESS BYTE
 AddressFamily AS DWORD ' DWORD // AF_INET only.
 WTS_SESSION_ADDRESS_UNION
END TYPE
'/*=====================================================================
'== Windows Terminal Server public APIs
'=====================================================================*/
DECLARE FUNCTION WTSStopRemoteControlSessionA LIB "wtsapi32.dll" ALIAS "WTSStopRemoteControlSession" ( BYVAL LogonId AS QUAD ) AS LONG
DECLARE FUNCTION WTSStartRemoteControlSessionW LIB "wtsapi32.dll" ALIAS "WTSStartRemoteControlSessionW" ( BYREF pTargetServerName AS WSTRINGZ
 , BYVAL TargetLogonId AS DWORD
 , BYVAL HotkeyVk AS BYTE
 , BYVAL HotkeyModifiers AS WORD
 ) AS LONG
DECLARE FUNCTION WTSStartRemoteControlSessionA LIB "wtsapi32.dll" ALIAS "WTSStartRemoteControlSessionA" ( BYREF pTargetServerName AS ASCIIZ
 , BYVAL TargetLogonId AS DWORD
 , BYVAL HotkeyVk AS BYTE
 , BYVAL HotkeyModifiers AS WORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSStartRemoteControlSession = WTSStartRemoteControlSessionW
#ELSE
 MACRO WTSStartRemoteControlSession = WTSStartRemoteControlSessionA
#ENDIF
DECLARE FUNCTION WTSConnectSessionA LIB "wtsapi32.dll" ALIAS "WTSConnectSessionA" ( BYVAL LogonId AS QUAD , BYVAL TargetLogonId AS QUAD , BYREF pPassword AS ASCIIZ , BYVAL bWait AS LONG ) AS LONG
DECLARE FUNCTION WTSConnectSessionW LIB "wtsapi32.dll" ALIAS "WTSConnectSessionW" ( BYVAL LogonId AS QUAD
 , BYVAL TargetLogonId AS DWORD
 , BYREF pPassword AS WSTRINGZ
 , BYVAL bWait AS LONG
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSConnectSession = WTSConnectSessionW
#ELSE
 MACRO WTSConnectSession = WTSConnectSessionA
#ENDIF
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSEnumerateServersW LIB "WtsApi32.dll" ALIAS "WTSEnumerateServersW" ( pDomainName AS WSTRINGZ, BYVAL Reserved AS QUAD, BYVAL Version AS QUAD, ppServerInfo AS ANY, ' WTS_SERVER_INFOW PTR PTR
 pCount AS DWORD ) AS LONG
#ELSE
DECLARE FUNCTION WTSEnumerateServersW LIB "wtsapi32.dll" ALIAS "WTSEnumerateServersW" ( BYREF pDomainName AS WSTRINGZ , BYVAL Reserved AS QUAD , BYVAL Version AS QUAD , BYREF ppServerInfo AS WTS_SERVER_INFOW , BYREF pCount AS QUAD ) AS LONG
#ENDIF
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSEnumerateServersA LIB "WtsApi32.dll" ALIAS "WTSEnumerateServersA" ( pDomainName AS ASCIIZ, BYVAL Reserved AS QUAD, BYVAL Version AS QUAD, ppServerInfo AS ANY, ' WTS_SERVER_INFOA PTR PTR
 pCount AS DWORD ) AS LONG
#ELSE
DECLARE FUNCTION WTSEnumerateServersA LIB "wtsapi32.dll" ALIAS "WTSEnumerateServersA" ( BYREF pDomainName AS ASCIIZ , BYVAL Reserved AS QUAD , BYVAL Version AS QUAD , BYREF ppServerInfo AS WTS_SERVER_INFOA , BYREF pCount AS QUAD ) AS LONG
#ENDIF
#IF %DEF(%UNICODE)
 MACRO WTSEnumerateServers = WTSEnumerateServersW
#ELSE
 MACRO WTSEnumerateServers = WTSEnumerateServersA
#ENDIF
'/*------------------------------------------------*/
DECLARE FUNCTION WTSOpenServerW LIB "wtsapi32.dll" ALIAS "WTSOpenServerW" ( BYREF pServerName AS WSTRINGZ ) AS QUAD
DECLARE FUNCTION WTSOpenServerA LIB "wtsapi32.dll" ALIAS "WTSOpenServerA" ( BYREF pServerName AS ASCIIZ
 ) AS DWORD
#IF %DEF(%UNICODE)
 MACRO WTSOpenServer = WTSOpenServerW
#ELSE
 MACRO WTSOpenServer = WTSOpenServerA
#ENDIF
DECLARE FUNCTION WTSOpenServerExW LIB "wtsapi32.dll" ALIAS "WTSOpenServerExW" ( BYREF pServerName AS WSTRINGZ ) AS QUAD
DECLARE FUNCTION WTSOpenServerExA LIB "wtsapi32.dll" ALIAS "WTSOpenServerExA" ( BYREF pServerName AS ASCIIZ
 ) AS DWORD
#IF %DEF(%UNICODE)
 MACRO WTSOpenServerEx = WTSOpenServerExW
#ELSE
 MACRO WTSOpenServerEx = WTSOpenServerExA
#ENDIF
'/*------------------------------------------------*/
DECLARE SUB WTSCloseServer LIB "wtsapi32.dll" ALIAS "WTSCloseServer" ( BYVAL hServer AS QUAD ) ' void
'/*------------------------------------------------*/
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSEnumerateSessionsW LIB "WtsApi32.dll" ALIAS "WTSEnumerateSessionsW" ( BYVAL hServer AS QUAD,
 BYVAL Reserved AS QUAD, BYVAL Version AS QUAD, ppSessionInfo AS ANY, ' WTS_SESSION_INFOW PTR PTR
 pCount AS DWORD ) AS LONG
#ELSE
DECLARE FUNCTION WTSEnumerateSessionsW LIB "wtsapi32.dll" ALIAS "WTSEnumerateSessionsW" ( BYVAL hServer AS QUAD , BYVAL Reserved AS QUAD , BYVAL Version AS QUAD , BYREF ppSessionInfo AS WTS_SESSION_INFOW , BYREF pCount AS QUAD ) AS LONG
#ENDIF
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSEnumerateSessionsA LIB "WtsApi32.dll" ALIAS "WTSEnumerateSessionsA" ( BYVAL hServer AS QUAD,
 BYVAL Reserved AS QUAD, BYVAL Version AS QUAD, ppSessionInfo AS ANY, ' WTS_SESSION_INFOA PTR PTR
 pCount AS DWORD ) AS LONG
#ELSE
DECLARE FUNCTION WTSEnumerateSessionsA LIB "wtsapi32.dll" ALIAS "WTSEnumerateSessionsA" ( BYVAL hServer AS QUAD , BYVAL Reserved AS QUAD , BYVAL Version AS QUAD , BYREF ppSessionInfo AS WTS_SESSION_INFOA , BYREF pCount AS QUAD ) AS LONG
#ENDIF
#IF %DEF(%UNICODE)
 MACRO WTSEnumerateSessions = WTSEnumerateSessionsW
#ELSE
 MACRO WTSEnumerateSessions = WTSEnumerateSessionsA
#ENDIF
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSEnumerateSessionsExW LIB "WtsApi32.dll" ALIAS "WTSEnumerateSessionsExW" ( BYVAL hServer AS QUAD,
 pLevel AS QUAD, BYVAL Filter AS QUAD, ppSessionInfo AS ANY, ' WTS_SESSION_INFO_1W PTR PTR
 pCount AS DWORD ) AS LONG
#ELSE
DECLARE FUNCTION WTSEnumerateSessionsExW LIB "wtsapi32.dll" ALIAS "WTSEnumerateSessionsExW" ( BYVAL hServer AS QUAD , BYREF pLevel AS QUAD , BYVAL Filter AS QUAD , BYREF ppSessionInfo AS WTS_SESSION_INFO_1W , BYREF pCount AS QUAD ) AS LONG
#ENDIF
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSEnumerateSessionsExA LIB "WtsApi32.dll" ALIAS "WTSEnumerateSessionsExA" ( BYVAL hServer AS QUAD,
 pLevel AS QUAD, BYVAL Filter AS QUAD, ppSessionInfo AS ANY, ' WTS_SESSION_INFO_1A PTR PTR
 pCount AS DWORD ) AS LONG
#ELSE
DECLARE FUNCTION WTSEnumerateSessionsExA LIB "wtsapi32.dll" ALIAS "WTSEnumerateSessionsExA" ( BYVAL hServer AS QUAD , BYREF pLevel AS QUAD , BYVAL Filter AS QUAD , BYREF ppSessionInfo AS WTS_SESSION_INFO_1A , BYREF pCount AS QUAD ) AS LONG
#ENDIF
#IF %DEF(%UNICODE)
 MACRO WTSEnumerateSessionsEx = WTSEnumerateSessionsExW
#ELSE
 MACRO WTSEnumerateSessionsEx = WTSEnumerateSessionsExA
#ENDIF
'/*------------------------------------------------*/
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSEnumerateProcessesW LIB "WtsApi32.dll" ALIAS "WTSEnumerateProcessesW" ( BYVAL hServer AS QUAD,
 BYVAL Reserved AS QUAD, BYVAL Version AS QUAD, ppProcessInfo AS ANY, ' WTS_PROCESS_INFOW PTR PTR
 pCount AS DWORD ) AS LONG
#ELSE
DECLARE FUNCTION WTSEnumerateProcessesW LIB "wtsapi32.dll" ALIAS "WTSEnumerateProcessesW" ( BYVAL hServer AS QUAD , BYVAL Reserved AS QUAD , BYVAL Version AS QUAD , BYREF ppProcessInfo AS WTS_PROCESS_INFOW , BYREF pCount AS QUAD ) AS LONG
#ENDIF
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSEnumerateProcessesA LIB "WtsApi32.dll" ALIAS "WTSEnumerateProcessesA" ( BYVAL hServer AS QUAD,
 BYVAL Reserved AS QUAD, BYVAL Version AS QUAD, ppProcessInfo AS ANY, ' WTS_PROCESS_INFOA PTR PTR
 pCount AS DWORD ) AS LONG
#ELSE
DECLARE FUNCTION WTSEnumerateProcessesA LIB "wtsapi32.dll" ALIAS "WTSEnumerateProcessesA" ( BYVAL hServer AS QUAD , BYVAL Reserved AS QUAD , BYVAL Version AS QUAD , BYREF ppProcessInfo AS WTS_PROCESS_INFOA , BYREF pCount AS QUAD ) AS LONG
#ENDIF
#IF %DEF(%UNICODE)
 MACRO WTSEnumerateProcesses = WTSEnumerateProcessesW
#ELSE
 MACRO WTSEnumerateProcesses = WTSEnumerateProcessesA
#ENDIF
'/*------------------------------------------------*/
DECLARE FUNCTION WTSTerminateProcess LIB "wtsapi32.dll" ALIAS "WTSTerminateProcess" ( BYVAL hServer AS QUAD , BYVAL ProcessId AS QUAD , BYVAL ExitCode AS QUAD ) AS LONG
'/*------------------------------------------------*/
DECLARE FUNCTION WTSQuerySessionInformationW LIB "wtsapi32.dll" ALIAS "WTSQuerySessionInformationW" ( BYVAL hServer AS QUAD , BYVAL SessionId AS QUAD , BYVAL WTSInfoClass AS LONG , BYREF ppBuffer AS QUAD , BYREF pBytesReturned AS QUAD ) AS LONG
DECLARE FUNCTION WTSQuerySessionInformationA LIB "wtsapi32.dll" ALIAS "WTSQuerySessionInformationA" ( BYVAL hServer AS QUAD
 , BYVAL SessionId AS DWORD
 , BYVAL WTSInfoClass AS LONG
 , BYREF ppBuffer AS DWORD
 , BYREF pBytesReturned AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSQuerySessionInformation = WTSQuerySessionInformationW
#ELSE
 MACRO WTSQuerySessionInformation = WTSQuerySessionInformationA
#ENDIF
'/*------------------------------------------------*/
DECLARE FUNCTION WTSQueryUserConfigW LIB "wtsapi32.dll" ALIAS "WTSQueryUserConfigW" ( BYREF pServerName AS WSTRINGZ , BYREF pUserName AS WSTRINGZ , BYVAL WTSConfigClass AS LONG , BYREF ppBuffer AS QUAD , BYREF pBytesReturned AS QUAD ) AS LONG
DECLARE FUNCTION WTSQueryUserConfigA LIB "wtsapi32.dll" ALIAS "WTSQueryUserConfigA" ( BYREF pServerName AS ASCIIZ
 , BYREF pUserName AS ASCIIZ
 , BYVAL WTSConfigClass AS LONG
 , BYREF ppBuffer AS DWORD
 , BYREF pBytesReturned AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSQueryUserConfig = WTSQueryUserConfigW
#ELSE
 MACRO WTSQueryUserConfig = WTSQueryUserConfigA
#ENDIF
'/*------------------------------------------------*/
DECLARE FUNCTION WTSSetUserConfigW LIB "wtsapi32.dll" ALIAS "WTSSetUserConfigW" ( BYREF pServerName AS WSTRINGZ , BYREF pUserName AS WSTRINGZ , BYVAL WTSConfigClass AS LONG , BYREF pBuffer AS WSTRINGZ , BYVAL DataLength AS QUAD ) AS LONG
DECLARE FUNCTION WTSSetUserConfigA LIB "wtsapi32.dll" ALIAS "WTSSetUserConfigA" ( BYREF pServerName AS ASCIIZ
 , BYREF pUserName AS ASCIIZ
 , BYVAL WTSConfigClass AS LONG
 , BYREF pBuffer AS ASCIIZ
 , BYVAL DataLength AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSSetUserConfig = WTSSetUserConfigW
#ELSE
 MACRO WTSSetUserConfig = WTSSetUserConfigA
#ENDIF
'/*------------------------------------------------*/
DECLARE FUNCTION WTSSendMessageW LIB "wtsapi32.dll" ALIAS "WTSSendMessageW" ( BYVAL hServer AS QUAD , BYVAL SessionId AS QUAD , BYREF pTitle AS WSTRINGZ , BYVAL TitleLength AS QUAD , BYREF pMessage AS WSTRINGZ , BYVAL MessageLength AS QUAD , BYVAL Style AS QUAD , BYVAL Timeout AS QUAD , BYREF pResponse AS QUAD , BYVAL bWait AS LONG ) AS LONG
DECLARE FUNCTION WTSSendMessageA LIB "wtsapi32.dll" ALIAS "WTSSendMessageA" ( BYVAL hServer AS QUAD
 , BYVAL SessionId AS DWORD
 , BYREF pTitle AS ASCIIZ
 , BYVAL TitleLength AS DWORD
 , BYREF pMessage AS ASCIIZ
 , BYVAL MessageLength AS DWORD
 , BYVAL Style AS DWORD
 , BYVAL Timeout AS DWORD
 , BYREF pResponse AS DWORD
 , BYVAL bWait AS LONG
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSSendMessage = WTSSendMessageW
#ELSE
 MACRO WTSSendMessage = WTSSendMessageA
#ENDIF
'/*------------------------------------------------*/
DECLARE FUNCTION WTSDisconnectSession LIB "wtsapi32.dll" ALIAS "WTSDisconnectSession" ( BYVAL hServer AS QUAD , BYVAL SessionId AS QUAD , BYVAL bWait AS LONG ) AS LONG
'/*------------------------------------------------*/
DECLARE FUNCTION WTSLogoffSession LIB "wtsapi32.dll" ALIAS "WTSLogoffSession" ( BYVAL hServer AS QUAD , BYVAL SessionId AS QUAD , BYVAL bWait AS LONG ) AS LONG
'/*------------------------------------------------*/
DECLARE FUNCTION WTSShutdownSystem LIB "wtsapi32.dll" ALIAS "WTSShutdownSystem" ( BYVAL hServer AS QUAD , BYVAL ShutdownFlag AS QUAD ) AS LONG
'/*------------------------------------------------*/
DECLARE FUNCTION WTSWaitSystemEvent LIB "wtsapi32.dll" ALIAS "WTSWaitSystemEvent" ( BYVAL hServer AS QUAD , BYVAL EventMask AS QUAD , BYREF pEventFlags AS QUAD ) AS LONG
'/*------------------------------------------------*/
DECLARE FUNCTION WTSVirtualChannelOpen LIB "wtsapi32.dll" ALIAS "WTSVirtualChannelOpen" ( BYVAL hServer AS QUAD , BYVAL SessionId AS QUAD , BYREF pVirtualName AS ASCIIZ ) AS QUAD
%EQUATE `WTS_CHANNEL_OPTION_DYNAMIC = &H00000001 ' // dynamic channel
%EQUATE `WTS_CHANNEL_OPTION_DYNAMIC_PRI_LOW = &H00000000 ' // priorities
%EQUATE `WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED = &H00000002
%EQUATE `WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH = &H00000004
%EQUATE `WTS_CHANNEL_OPTION_DYNAMIC_PRI_REAL = &H00000006
%EQUATE `WTS_CHANNEL_OPTION_DYNAMIC_NO_COMPRESS = &H00000008
DECLARE FUNCTION WTSVirtualChannelOpenEx LIB "wtsapi32.dll" ALIAS "WTSVirtualChannelOpenEx" ( BYVAL SessionId AS QUAD , BYREF pVirtualName AS ASCIIZ , BYVAL flags AS QUAD ) AS QUAD
DECLARE FUNCTION WTSVirtualChannelClose LIB "wtsapi32.dll" ALIAS "WTSVirtualChannelClose" ( BYVAL hChannelHandle AS QUAD
 ) AS LONG
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSVirtualChannelRead LIB "WtsApi32.dll" ALIAS "WTSVirtualChannelRead" ( BYVAL hChannelHandle AS QUAD,
 BYVAL TimeOut AS QUAD, BYVAL Buffer AS BYTE PTR, BYVAL BufferSize AS QUAD, pBytesRead AS QUAD ) AS LONG
#ELSE
DECLARE FUNCTION WTSVirtualChannelRead LIB "wtsapi32.dll" ALIAS "WTSVirtualChannelRead" ( BYVAL hChannelHandle AS QUAD , BYVAL TimeOut AS QUAD , BYREF Buffer AS ANY , BYVAL BufferSize AS QUAD , BYREF pBytesRead AS QUAD ) AS LONG
#ENDIF
DECLARE FUNCTION WTSVirtualChannelWrite LIB "wtsapi32.dll" ALIAS "WTSVirtualChannelWrite" ( BYVAL hChannelHandle AS QUAD , BYVAL Buffer AS BYTE PTR , BYVAL Length AS QUAD , BYREF pBytesWritten AS QUAD ) AS LONG
DECLARE FUNCTION WTSVirtualChannelPurgeInput LIB "wtsapi32.dll" ALIAS "WTSVirtualChannelPurgeInput" ( BYVAL hChannelHandle AS QUAD
 ) AS LONG
DECLARE FUNCTION WTSVirtualChannelPurgeOutput LIB "wtsapi32.dll" ALIAS "WTSVirtualChannelPurgeOutput" ( BYVAL hChannelHandle AS DWORD
 ) AS LONG
DECLARE FUNCTION WTSVirtualChannelQuery LIB "wtsapi32.dll" ALIAS "WTSVirtualChannelQuery" ( BYVAL hChannelHandle AS DWORD
 , BYVAL WtsVirtualClass AS LONG
 , BYREF ppBuffer AS ANY
 , BYREF pBytesReturned AS DWORD
 ) AS LONG
'/*------------------------------------------------*/
DECLARE SUB WTSFreeMemory LIB "wtsapi32.dll" ALIAS "WTSFreeMemory" ( BYVAL pMemory AS QUAD ) ' void
'/* Flags for Console Notification */
%EQUATE `NOTIFY_FOR_ALL_SESSIONS = 1
%EQUATE `NOTIFY_FOR_THIS_SESSION = 0
DECLARE FUNCTION WTSRegisterSessionNotification LIB "wtsapi32.dll" ALIAS "WTSRegisterSessionNotification" ( BYVAL hWnd AS QUAD , BYVAL dwFlags AS QUAD ) AS LONG
DECLARE FUNCTION WTSUnRegisterSessionNotification LIB "wtsapi32.dll" ALIAS "WTSUnRegisterSessionNotification" ( BYVAL hWnd AS QUAD
 ) AS LONG
DECLARE FUNCTION WTSRegisterSessionNotificationEx LIB "wtsapi32.dll" ALIAS "WTSRegisterSessionNotificationEx" ( BYVAL hServer AS DWORD
 , BYVAL hWnd AS DWORD
 , BYVAL dwFlags AS DWORD
 ) AS LONG
DECLARE FUNCTION WTSUnRegisterSessionNotificationEx LIB "wtsapi32.dll" ALIAS "WTSUnRegisterSessionNotificationEx" ( BYVAL hServer AS DWORD
 , BYVAL hWnd AS DWORD
 ) AS LONG
DECLARE FUNCTION WTSQueryUserToken LIB "wtsapi32.dll" ALIAS "WTSQueryUserToken" ( BYVAL SessionId AS DWORD
 , BYREF phToken AS DWORD
 ) AS LONG
%EQUATE `WTS_PROCESS_INFO_LEVEL_0 = 0
%EQUATE `WTS_PROCESS_INFO_LEVEL_1 = 1
'/*
'== WTS_PROCESS_INFO_EX - returned by WTSEnumerateProcessesEX
'*/
' // Size = 56 bytes
TYPE WTS_PROCESS_INFO_EXW QWORD FILL ' Must be 8 byte aligned
 SessionId AS DWORD
 ProcessId AS DWORD
 pProcessName AS WSTRINGZ PTR
 pUserSid AS SID PTR
 NumberOfThreads AS DWORD
 HandleCount AS DWORD
 PagefileUsage AS DWORD
 PeakPagefileUsage AS DWORD
 WorkingSetSize AS DWORD
 PeakWorkingSetSize AS DWORD
 UserTime AS QUAD ' LARGE_INTEGER
 KernelTime AS QUAD ' LARGE_INTEGER
END TYPE
' // Size = 56 bytes
TYPE WTS_PROCESS_INFO_EXA QWORD FILL
 SessionId AS DWORD
 ProcessId AS DWORD
 pProcessName AS ASCIIZ PTR
 pUserSid AS SID PTR
 NumberOfThreads AS DWORD
 HandleCount AS DWORD
 PagefileUsage AS DWORD
 PeakPagefileUsage AS DWORD
 WorkingSetSize AS DWORD
 PeakWorkingSetSize AS DWORD
 UserTime AS QUAD ' LARGE_INTEGER
 KernelTime AS QUAD ' LARGE_INTEGER
END TYPE
MACRO WTS_PROCESS_INFO_EX = WTS_PROCESS_INFO_EXA
'/*------------------------------------------------*/
' enum _WTS_TYPE_CLASS
%EQUATE `WTSTypeProcessInfoLevel0 = 0
%EQUATE `WTSTypeProcessInfoLevel1 = 1
%EQUATE `WTSTypeSessionInfoLevel1 = 2
DECLARE FUNCTION WTSFreeMemoryExW LIB "wtsapi32.dll" ALIAS "WTSFreeMemoryExW" ( BYVAL WTSTypeClass AS LONG , BYVAL pMemory AS QUAD , BYVAL NumberOfEntries AS QUAD ) AS LONG
DECLARE FUNCTION WTSFreeMemoryExA LIB "wtsapi32.dll" ALIAS "WTSFreeMemoryExA" ( BYVAL WTSTypeClass AS LONG
 , BYVAL pMemory AS DWORD
 , BYVAL NumberOfEntries AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSFreeMemoryEx = WTSFreeMemoryExW
#ELSE
 MACRO WTSFreeMemoryEx = WTSFreeMemoryExA
#ENDIF
'/*------------------------------------------------*/
DECLARE FUNCTION WTSEnumerateProcessesExW LIB "wtsapi32.dll" ALIAS "WTSEnumerateProcessesExW" ( BYVAL hServer AS QUAD , BYREF pLevel AS QUAD , BYVAL SessionId AS QUAD , BYREF ppProcessInfo AS QUAD , BYREF pCount AS QUAD ) AS LONG
DECLARE FUNCTION WTSEnumerateProcessesExA LIB "wtsapi32.dll" ALIAS "WTSEnumerateProcessesExA" ( BYVAL hServer AS QUAD
 , BYREF pLevel AS DWORD
 , BYVAL SessionId AS DWORD
 , BYREF ppProcessInfo AS DWORD
 , BYREF pCount AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSEnumerateProcessesEx = WTSEnumerateProcessesExW
#ELSE
 MACRO WTSEnumerateProcessesEx = WTSEnumerateProcessesExA
#ENDIF
'/*------------------------------------------------*/
'// Listener management APIs
'typedef WCHAR WTSLISTENERNAMEW[WTS_LISTENER_NAME_LENGTH + 1 ];
'typedef WTSLISTENERNAMEW *PWTSLISTENERNAMEW;
'typedef CHAR WTSLISTENERNAMEA[WTS_LISTENER_NAME_LENGTH + 1 ];
'typedef WTSLISTENERNAMEA *PWTSLISTENERNAMEA;
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSEnumerateListenersW LIB "WtsApi32.dll" ALIAS "WTSEnumerateListenersW" ( BYVAL hServer AS QUAD,
 BYVAL pReserved AS QUAD,
 BYVAL Reserved AS QUAD, BYVAL pListeners AS QUAD, ' WTSLISTENERNAMEW PTR
 pCount AS DWORD ) AS LONG
#ELSE
DECLARE FUNCTION WTSEnumerateListenersW LIB "wtsapi32.dll" ALIAS "WTSEnumerateListenersW" ( BYVAL hServer AS QUAD , BYVAL pReserved AS QUAD , BYVAL Reserved AS QUAD , BYREF pListeners AS ANY , BYREF pCount AS QUAD ) AS LONG
#ENDIF
#IF %DEF(%USEPBDECL)
DECLARE FUNCTION WTSEnumerateListenersA LIB "WtsApi32.dll" ALIAS "WTSEnumerateListenersA" ( BYVAL hServer AS QUAD,
 BYVAL pReserved AS QUAD,
 BYVAL Reserved AS QUAD, BYVAL pListeners AS QUAD, ' WTSLISTENERNAMEA PTR
 pCount AS DWORD ) AS LONG
#ELSE
DECLARE FUNCTION WTSEnumerateListenersA LIB "wtsapi32.dll" ALIAS "WTSEnumerateListenersA" ( BYVAL hServer AS QUAD , BYVAL pReserved AS QUAD , BYVAL Reserved AS QUAD , BYREF pListeners AS ANY , BYREF pCount AS QUAD ) AS LONG
#ENDIF
#IF %DEF(%UNICODE)
 MACRO WTSEnumerateListeners = WTSEnumerateListenersW
#ELSE
 MACRO WTSEnumerateListeners = WTSEnumerateListenersA
#ENDIF
'/*------------------------------------------------*/
'// Listener Config, used by WTSQueryListenerConfig and WTSCreateListener
' // Size = 1348 bytes
TYPE WTSLISTENERCONFIGW BYTE
 version AS DWORD ' ULONG
 fEnableListener AS DWORD ' ULONG
 MaxConnectionCount AS DWORD ' ULONG
 fPromptForPassword AS DWORD ' ULONG
 fInheritColorDepth AS DWORD ' ULONG
 ColorDepth AS DWORD ' ULONG
 fInheritBrokenTimeoutSettings AS DWORD ' ULONG
 BrokenTimeoutSettings AS DWORD ' ULONG
 fDisablePrinterRedirection AS DWORD ' ULONG
 fDisableDriveRedirection AS DWORD ' ULONG
 fDisableComPortRedirection AS DWORD ' ULONG
 fDisableLPTPortRedirection AS DWORD ' ULONG
 fDisableClipboardRedirection AS DWORD ' ULONG
 fDisableAudioRedirection AS DWORD ' ULONG
 fDisablePNPRedirection AS DWORD ' ULONG
 fDisableDefaultMainClientPrinter AS DWORD ' ULONG
 LanAdapter AS DWORD ' ULONG
 PortNumber AS DWORD ' ULONG
 fInheritShadowSettings AS DWORD ' ULONG
 ShadowSettings AS DWORD ' ULONG
 TimeoutSettingsConnection AS DWORD ' ULONG
 TimeoutSettingsDisconnection AS DWORD ' ULONG
 TimeoutSettingsIdle AS DWORD ' ULONG
 SecurityLayer AS DWORD ' ULONG
 MinEncryptionLevel AS DWORD ' ULONG
 UserAuthentication AS DWORD ' ULONG
 Comment AS WSTRINGZ * %WTS_COMMENT_LENGTH + 1 ' WCHAR
 LogonUserName AS WSTRINGZ * %USERNAME_LENGTH + 1 ' WCHAR
 LogonDomain AS WSTRINGZ * %DOMAIN_LENGTH + 1 ' WCHAR
 WorkDirectory AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
 InitialProgram AS WSTRINGZ * %MAX_PATH + 1 ' WCHAR
END TYPE
' // Size = 728 bytes
TYPE WTSLISTENERCONFIGA BYTE
 version AS DWORD ' ULONG
 fEnableListener AS DWORD ' ULONG
 MaxConnectionCount AS DWORD ' ULONG
 fPromptForPassword AS DWORD ' ULONG
 fInheritColorDepth AS DWORD ' ULONG
 ColorDepth AS DWORD ' ULONG
 fInheritBrokenTimeoutSettings AS DWORD ' ULONG
 BrokenTimeoutSettings AS DWORD ' ULONG
 fDisablePrinterRedirection AS DWORD ' ULONG
 fDisableDriveRedirection AS DWORD ' ULONG
 fDisableComPortRedirection AS DWORD ' ULONG
 fDisableLPTPortRedirection AS DWORD ' ULONG
 fDisableClipboardRedirection AS DWORD ' ULONG
 fDisableAudioRedirection AS DWORD ' ULONG
 fDisablePNPRedirection AS DWORD ' ULONG
 fDisableDefaultMainClientPrinter AS DWORD ' ULONG
 LanAdapter AS DWORD ' ULONG
 PortNumber AS DWORD ' ULONG
 fInheritShadowSettings AS DWORD ' ULONG
 ShadowSettings AS DWORD ' ULONG
 TimeoutSettingsConnection AS DWORD ' ULONG
 TimeoutSettingsDisconnection AS DWORD ' ULONG
 TimeoutSettingsIdle AS DWORD ' ULONG
 SecurityLayer AS DWORD ' ULONG
 MinEncryptionLevel AS DWORD ' ULONG
 UserAuthentication AS DWORD ' ULONG
 Comment AS ASCIIZ * %WTS_COMMENT_LENGTH + 1 ' CHAR
 LogonUserName AS ASCIIZ * %USERNAME_LENGTH + 1 ' CHAR
 LogonDomain AS ASCIIZ * %DOMAIN_LENGTH + 1 ' CHAR
 WorkDirectory AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 InitialProgram AS ASCIIZ * %MAX_PATH + 1 ' CHAR
 alignment__ AS WORD ' // To keep DWORD alignment
END TYPE
#IF %DEF(%UNICODE)
 MACRO WTSLISTENERCONFIG = WTSLISTENERCONFIGW
#ELSE
 MACRO WTSLISTENERCONFIG = WTSLISTENERCONFIGA
#ENDIF
DECLARE FUNCTION WTSQueryListenerConfigW LIB "wtsapi32.dll" ALIAS "WTSQueryListenerConfigW" ( BYVAL hServer AS QUAD , BYVAL pReserved AS QUAD , BYVAL Reserved AS QUAD , BYREF pListenerName AS WSTRINGZ , BYREF pBuffer AS WTSLISTENERCONFIGW ) AS LONG
DECLARE FUNCTION WTSQueryListenerConfigA LIB "wtsapi32.dll" ALIAS "WTSQueryListenerConfigA" ( BYVAL hServer AS QUAD
 , BYVAL pReserved AS DWORD
 , BYVAL Reserved AS DWORD
 , BYREF pListenerName AS ASCIIZ
 , BYREF pBuffer AS WTSLISTENERCONFIGA
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSQueryListenerConfig = WTSQueryListenerConfigW
#ELSE
 MACRO WTSQueryListenerConfig = WTSQueryListenerConfigA
#ENDIF
DECLARE FUNCTION WTSCreateListenerW LIB "wtsapi32.dll" ALIAS "WTSCreateListenerW" ( BYVAL hServer AS QUAD , BYVAL pReserved AS QUAD , BYVAL Reserved AS QUAD , BYREF pListenerName AS WSTRINGZ , BYREF pBuffer AS WTSLISTENERCONFIGW , BYVAL flag AS QUAD ) AS LONG
DECLARE FUNCTION WTSCreateListenerA LIB "wtsapi32.dll" ALIAS "WTSCreateListenerA" ( BYVAL hServer AS QUAD
 , BYVAL pReserved AS DWORD
 , BYVAL Reserved AS DWORD
 , BYREF pListenerName AS ASCIIZ
 , BYREF pBuffer AS WTSLISTENERCONFIGA
 , BYVAL flag AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSCreateListener = WTSCreateListenerW
#ELSE
 MACRO WTSCreateListener = WTSCreateListenerA
#ENDIF
DECLARE FUNCTION WTSSetListenerSecurityW LIB "wtsapi32.dll" ALIAS "WTSSetListenerSecurityW" ( BYVAL hServer AS QUAD , BYVAL pReserved AS QUAD , BYVAL Reserved AS QUAD , BYREF pListenerName AS WSTRINGZ , BYVAL SecurityInformation AS SECURITY_INFORMATION , BYREF pSecurityDescriptor AS SECURITY_DESCRIPTOR ) AS LONG
DECLARE FUNCTION WTSSetListenerSecurityA LIB "wtsapi32.dll" ALIAS "WTSSetListenerSecurityA" ( BYVAL hServer AS QUAD
 , BYVAL pReserved AS DWORD
 , BYVAL Reserved AS DWORD
 , BYREF pListenerName AS ASCIIZ
 , BYVAL SecurityInformation AS SECURITY_INFORMATION
 , BYREF pSecurityDescriptor AS SECURITY_DESCRIPTOR
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSSetListenerSecurity = WTSSetListenerSecurityW
#ELSE
 MACRO WTSSetListenerSecurity = WTSSetListenerSecurityA
#ENDIF
DECLARE FUNCTION WTSGetListenerSecurityW LIB "wtsapi32.dll" ALIAS "WTSGetListenerSecurityW" ( BYVAL hServer AS QUAD , BYVAL pReserved AS QUAD , BYVAL Reserved AS QUAD , BYREF pListenerName AS WSTRINGZ , BYVAL SecurityInformation AS SECURITY_INFORMATION , BYREF pSecurityDescriptor AS SECURITY_DESCRIPTOR , BYVAL nLength AS QUAD , BYREF lpnLengthNeeded AS QUAD ) AS LONG
DECLARE FUNCTION WTSGetListenerSecurityA LIB "wtsapi32.dll" ALIAS "WTSGetListenerSecurityA" ( BYVAL hServer AS QUAD
 , BYVAL pReserved AS DWORD
 , BYVAL Reserved AS DWORD
 , BYREF pListenerName AS ASCIIZ
 , BYVAL SecurityInformation AS SECURITY_INFORMATION
 , BYREF pSecurityDescriptor AS SECURITY_DESCRIPTOR
 , BYVAL nLength AS DWORD
 , BYREF lpnLengthNeeded AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
 MACRO WTSGetListenerSecurity = WTSGetListenerSecurityW
#ELSE
 MACRO WTSGetListenerSecurity = WTSGetListenerSecurityA
#ENDIF
#ENDIF
