|
@@ -1,1409 +0,0 @@
|
|
|
-{******************************************************************}
|
|
|
-{ This Unit provides Delphi translations of some functions from }
|
|
|
-{ WinSta.dll and Utildll. }
|
|
|
-{ Most functions are undocumented and somehow related to }
|
|
|
-{ Terminal Server }
|
|
|
-{ }
|
|
|
-{ Author: Remko Weijnen (r dot weijnen at gmail dot com) }
|
|
|
-{ Documentation can be found at www.remkoweijnen.nl }
|
|
|
-{ }
|
|
|
-{ The contents of this file are subject to }
|
|
|
-{ the Mozilla Public License Version 1.1 (the "License"); you may }
|
|
|
-{ not use this file except in compliance with the License. You may }
|
|
|
-{ obtain a copy of the License at }
|
|
|
-{ http://www.mozilla.org/MPL/MPL-1.1.html }
|
|
|
-{ }
|
|
|
-{ Software distributed under the License is distributed on an }
|
|
|
-{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
|
|
|
-{ implied. See the License for the specific language governing }
|
|
|
-{ rights and limitations under the License. }
|
|
|
-{******************************************************************}
|
|
|
-
|
|
|
-{$IFNDEF JWA_OMIT_SECTIONS}
|
|
|
-
|
|
|
-unit JwaWinSta;
|
|
|
-
|
|
|
-
|
|
|
-interface
|
|
|
-
|
|
|
-{$I jediapilib.inc}
|
|
|
-
|
|
|
-uses
|
|
|
- DateUtils, SysUtils, JwaWinType, // JwaWinType must be declared before JwaWinBase because of duplicate declaration of FILETIME
|
|
|
- JwaWinBase, JwaWinError, JwaNTStatus, JwaWinNT, JwaWinsock2,
|
|
|
- JwaWinSvc, JwaWtsApi32, JwaNative;
|
|
|
-{$ENDIF JWA_OMIT_SECTIONS}
|
|
|
-
|
|
|
-
|
|
|
-{$IFNDEF JWA_IMPLEMENTATIONSECTION}
|
|
|
-
|
|
|
-//==============================================================================
|
|
|
-// Defines
|
|
|
-//==============================================================================
|
|
|
-const
|
|
|
- SERVERNAME_CURRENT = 0;
|
|
|
-
|
|
|
- // constants used for WinStationGetTermSrvCounters
|
|
|
- TOTAL_SESSIONS_CREATED_COUNTER = 1;
|
|
|
- TOTAL_SESSIONS_DISCONNECTED_COUNTER = 2;
|
|
|
- TOTAL_SESSIONS_RECONNECTED_COUNTER = 3;
|
|
|
- TOTAL_SESSIONS_TOTAL_CONNECTED_NOW_COUNTER = 4;
|
|
|
- TOTAL_SESSIONS_TOTAL_DISCONNECTED_NOW_COUNTER = 5;
|
|
|
- TOTAL_SESSIONS_TOTAL_CONNECTED_NOW_COUNTER_2 = 6; //TermSrvSuccLocalLogons;
|
|
|
- TOTAL_SESSIONS_TOTAL_DISCONNECTED_NOW_COUNTER_2 = 7;
|
|
|
-
|
|
|
- // Max lenght for ElapsedTimeString (server 2008 version of utildll
|
|
|
- // fixes size at 15, so that's assumed to be safe
|
|
|
- ELAPSED_TIME_STRING_LENGTH = 15;
|
|
|
-
|
|
|
- // WdFlag = WinStation Driver Flag, it is returned in class 3 (WdConfig)
|
|
|
- // of WinStationQueryInformation and has a different value which
|
|
|
- // depends on the protocol. WdFlag is also returned by QueryCurrentWinStation
|
|
|
- WD_FLAG_CONSOLE_XP = $24; // XP
|
|
|
- WD_FLAG_CONSOLE = $34; // 2003/2008
|
|
|
- WD_FLAG_RDP = $36; // XP/2003/2008
|
|
|
- WD_FLAG_ICA = $6E; // Citrix Presentation Server
|
|
|
-// (value from Citrix PS4, other versions could be different!)
|
|
|
-
|
|
|
- // Class constants for WinStationQueryInformationW
|
|
|
- // These names were found in winsta.dll because they have
|
|
|
- // corresponding unicode 2 ansi conversion functions.
|
|
|
- // Unknown: AsyncConfig, NasiConfig, OemTdConfig, PdConfig, PdConfig2
|
|
|
- // PdParams UserConfig, WinStationCreate, WinStationPrinter
|
|
|
- //
|
|
|
- // The structures below are currently defined, constant names were
|
|
|
- // mapped on best guess:
|
|
|
-
|
|
|
- WdConfig = 3;
|
|
|
- WinStationClient = 1;
|
|
|
- WinStationConfig = 6;
|
|
|
- WinStationInformation = 8;
|
|
|
- WinStationProductId = 27;
|
|
|
- WinStationRemoteAddress = 29;
|
|
|
-
|
|
|
- // Constants for WinStationSetInformation
|
|
|
- WinStationBeep = 10; // Calls MessageBeep
|
|
|
-
|
|
|
- // This class is used to query the user's primary access token
|
|
|
- // Only System account is allowed to retrieve this!
|
|
|
- WinStationToken = 14;
|
|
|
-
|
|
|
- // WinStationLocks plays the lock or unlock sound
|
|
|
- // functionality not yet confirmed
|
|
|
- WinStationLock = 28; // Locks or Unlocks the WinStation
|
|
|
-
|
|
|
- SECONDS_PER_DAY = 86400;
|
|
|
- SECONDS_PER_HOUR = 3600;
|
|
|
- SECONDS_PER_MINUTE = 60;
|
|
|
-type
|
|
|
- // This type is used for ElapsedTimeString
|
|
|
- TDiffTime = record
|
|
|
- wDays: Word;
|
|
|
- wHours: Word;
|
|
|
- wMinutes: Word;
|
|
|
- wSeconds: Word;
|
|
|
- wMilliseconds: Word;
|
|
|
- end;
|
|
|
- PDiffTime = ^TDiffTime;
|
|
|
-
|
|
|
- // This type is used for WinStationQueryLogonCredentialsW
|
|
|
- // dwType can be one of the types defined in JwaWinWlx
|
|
|
- // WLX_CREDENTIAL_TYPE_V1_0 or WLX_CREDENTIAL_TYPE_V2_0 = 2
|
|
|
- _LOGON_CREDENTIALSW = record
|
|
|
- dwType: DWORD;
|
|
|
- pUsername: PWideChar;
|
|
|
- pDomain: PWideChar;
|
|
|
- pPassword: PWideChar;
|
|
|
- Unknown2 : DWORD;
|
|
|
- Unknown3 : DWORD;
|
|
|
- Unknown4: DWORD;
|
|
|
- end;
|
|
|
- PLOGON_CREDENTIALSW = ^_LOGON_CREDENTIALSW;
|
|
|
- TLogonCredentialsW = _LOGON_CREDENTIALSW;
|
|
|
- PLogonCredentialsW = PLOGON_CREDENTIALSW;
|
|
|
-
|
|
|
- _WINSTA_USER_TOKEN = record
|
|
|
- ProcessId : DWORD;
|
|
|
- ThreadId : DWORD;
|
|
|
- TokenHandle : THandle;
|
|
|
- end;
|
|
|
- PWINSTA_USER_TOKEN = ^_WINSTA_USER_TOKEN;
|
|
|
- TWinstaUserToken = _WINSTA_USER_TOKEN;
|
|
|
- PWinstaUserToken = ^TWinstaUserToken;
|
|
|
-
|
|
|
- // this type is used for WinStationGetTemSrvCounters
|
|
|
- _TERM_SRV_COUNTER = record
|
|
|
- dwIndex: DWORD;
|
|
|
- bSuccess: BOOL;
|
|
|
- dwValue: DWORD;
|
|
|
- Reserved2: DWORD;
|
|
|
- Reserved3: DWORD;
|
|
|
- Reserved4: DWORD;
|
|
|
- end;
|
|
|
- PTERM_SRV_COUNTER = ^_TERM_SRV_COUNTER;
|
|
|
- TTermSrvCounter = _TERM_SRV_COUNTER;
|
|
|
- PTermSrvCounter = ^TTermSrvCounter;
|
|
|
-
|
|
|
- TERM_SRV_COUNTER_ARRAY = array [1..7] of _TERM_SRV_COUNTER;
|
|
|
- PTERM_SRV_COUNTER_ARRAY = ^TERM_SRV_COUNTER_ARRAY;
|
|
|
- TTermSrvCounterArray = TERM_SRV_COUNTER_ARRAY;
|
|
|
- PTermSrvCounterArray = PTERM_SRV_COUNTER_ARRAY;
|
|
|
-
|
|
|
- // The following types are used for WinStationGetAllProcesses
|
|
|
- // _WINSTA_PROCESS_INFO
|
|
|
- _WINSTA_PROCESS_INFO = record
|
|
|
- ExtendedInfo: PSYSTEM_PROCESSES;
|
|
|
- dwSidLength: DWORD;
|
|
|
- pUserSid: PSID;
|
|
|
- end;
|
|
|
- PWINSTA_PROCESS_INFO = ^_WINSTA_PROCESS_INFO;
|
|
|
- TWinstaProcessInfo = _WINSTA_PROCESS_INFO;
|
|
|
- PWinstaProcessInfo = PWINSTA_PROCESS_INFO;
|
|
|
-
|
|
|
- // Array of _WINSTA_PROCESS_INFO
|
|
|
- _WINSTA_PROCESS_INFO_ARRAY = array [0..ANYSIZE_ARRAY-1] of _WINSTA_PROCESS_INFO;
|
|
|
- PWINSTA_PROCESS_INFO_ARRAY= ^_WINSTA_PROCESS_INFO_ARRAY;
|
|
|
- TWinstaProcessInfoArray = _WINSTA_PROCESS_INFO_ARRAY;
|
|
|
- PWinstaProcessInfoArray = PWINSTA_PROCESS_INFO_ARRAY;
|
|
|
-
|
|
|
- // The following types are used for WinStationQueryInformationW
|
|
|
-
|
|
|
- // WinStationClient, returns information as provided by the
|
|
|
- // Terminal Server client (mstsc).
|
|
|
- _WINSTATION_CLIENTW = record
|
|
|
- Comment: array[0..59] of WCHAR;
|
|
|
- Reserved1: array[0..2] of DWORD;
|
|
|
- ClientUsername: array[0..20] of WCHAR;
|
|
|
- ClientDomain: array[0..17] of WCHAR;
|
|
|
- ClientPassword: array[0..255] of WCHAR; // this was fixec win2000 SP4
|
|
|
- Reserved2: array[0..1635] of BYTE;
|
|
|
- Reserved3: array[0..6] of DWORD;
|
|
|
- Reserved4: array[0..275] of BYTE;
|
|
|
- end;
|
|
|
- PWINSTATION_CLIENTW = ^_WINSTATION_CLIENTW;
|
|
|
- TWinStationClientW = _WINSTATION_CLIENTW;
|
|
|
- PWinStationClientW = PWINSTATION_CLIENTW;
|
|
|
-
|
|
|
- // WdConfig class, returns information about the WinStationDriver
|
|
|
- _WD_CONFIGW = record
|
|
|
- WdName: array[0..32] of WCHAR;
|
|
|
- WdDLL: array[0..32] of WCHAR;
|
|
|
- WsxDLL: array[0..33] of WCHAR;
|
|
|
- WdFlag: DWORD;
|
|
|
- InputBufferLength: DWORD;
|
|
|
- CfgDLL: array[0..32] of WCHAR;
|
|
|
- WdPrefix: array[0..12] of WCHAR;
|
|
|
- end;
|
|
|
- PWD_CONFIGW = ^_WD_CONFIGW;
|
|
|
- TWdConfigW = _WD_CONFIGW;
|
|
|
- PWdConfigW = PWD_CONFIGW;
|
|
|
-
|
|
|
- // WinStationConfig class, returns information about the client's
|
|
|
- // configuration such as network, time(zone) settings and such
|
|
|
- _WINSTATION_CONFIGW = record
|
|
|
- Reserved1: DWORD;
|
|
|
- ClientName: array[0..20] of WCHAR;
|
|
|
- Domain: array[0..17] of WCHAR;
|
|
|
- Username: array[0..35] of WCHAR;
|
|
|
- CurrentDirectory: array[0..256] of WCHAR;
|
|
|
- ApplicationName:array[0..259] of WCHAR;
|
|
|
- Reserved2: DWORD;
|
|
|
- AddressFamily: DWORD; // AF_INET, AF_IPX, AF_NETBIOS, AF_UNSPEC
|
|
|
- ClientAddress: array[0..27] of WCHAR;
|
|
|
- Reserved3: array[0..7] of BYTE;
|
|
|
- Reserved4: array[0..4] of DWORD;
|
|
|
- Reserved5: array[0..69] of BYTE;
|
|
|
- ClientDLLName: array[0..330] of WCHAR;
|
|
|
- Reserved6: array[0..1] of FILETIME;
|
|
|
- AudioDriver: array[0..9] of WCHAR;
|
|
|
- TZBias: DWORD;
|
|
|
- TZStandardName: array[0..31] of WCHAR;
|
|
|
- Reserved7: DWORD; // Standard Bias??
|
|
|
- TZDaylightName: array[0..31] of WCHAR;
|
|
|
- TZDayLightStart: array[0..15] of BYTE;
|
|
|
- TZDayLightBias: DWORD;
|
|
|
- Reserved8: DWORD; // Daylight offset?
|
|
|
- TSInstanceID: array[0..33] of WCHAR; // sometimes windows license key(s)
|
|
|
- Reserved9: DWORD; // related to license key or instanceid?
|
|
|
- end;
|
|
|
- PWINSTATION_CONFIGW = ^_WINSTATION_CONFIGW;
|
|
|
- TWinStationConfigW = _WINSTATION_CONFIGW;
|
|
|
- PWinStationConfigW = PWINSTATION_CONFIGW;
|
|
|
-
|
|
|
- // class WinStationInformationClass
|
|
|
- // provides information about the current state of the client such as
|
|
|
- // idletime, sessionstatus and transferred/received bytes
|
|
|
- _WINSTATION_INFORMATIONW = record
|
|
|
- State: DWORD;
|
|
|
- WinStationName: array[0..10] of WideChar;
|
|
|
- Unknown1: array[0..10] of byte;
|
|
|
- Unknown3: array[0..10] of WideChar;
|
|
|
- Unknown2: array[0..8] of byte;
|
|
|
- SessionId: DWORD;
|
|
|
- Reserved2: array[0..3] of byte;
|
|
|
- ConnectTime: FILETIME;
|
|
|
- DisconnectTime: FILETIME;
|
|
|
- LastInputTime: FILETIME;
|
|
|
- LogonTime: FILETIME;
|
|
|
- Unknown4: array[0..11] of byte;
|
|
|
- OutgoingFrames: DWORD;
|
|
|
- OutgoingBytes: DWORD;
|
|
|
- OutgoingCompressBytes: DWORD;
|
|
|
- Unknown5: array[0..435] of byte;
|
|
|
- IncomingCompressedBytes: DWORD;
|
|
|
- Unknown6: array[0..7] of byte;
|
|
|
- IncomingFrames: DWORD;
|
|
|
- IncomingBytes: DWORD;
|
|
|
- Unknown7: array[0..3] of byte;
|
|
|
- Reserved3: array[0..528] of byte;
|
|
|
- Domain: array[0..17] of WideChar;
|
|
|
- Username: array[0..22] of WideChar;
|
|
|
- CurrentTime: FILETIME;
|
|
|
- end;
|
|
|
- PWINSTATION_INFORMATIONW = ^_WINSTATION_INFORMATIONW;
|
|
|
- TWinStationInformationExW = _WINSTATION_INFORMATIONW;
|
|
|
- PWinStationInformationExW = PWINSTATION_INFORMATIONW;
|
|
|
-
|
|
|
- // WinStationRemoteAddress (class 29)
|
|
|
- // Definition is preliminary
|
|
|
- // AddressFamily can be AF_INET, AF_IPX, AF_NETBIOS, AF_UNSPEC
|
|
|
- // Port is the remote port number (local port number is 3389 by default)
|
|
|
- // Address (for type AF_INET it start's at a 2 byte offset)
|
|
|
- // You can format IP Address to string like this:
|
|
|
- // Format('%d.%d.%d.%d', [WinStationAddress.Address[2],
|
|
|
- // WinStationRemoteAddress.[3], WinStationRemoteAddress.Address[4],
|
|
|
- // WinStationRemoteAddress..Address[5]]);
|
|
|
- //
|
|
|
- // Be sure to fill the structure with zeroes before query!
|
|
|
- _WINSTATION_REMOTE_ADDRESS = record
|
|
|
- AddressFamily: DWORD;
|
|
|
- Port: WORD;
|
|
|
- Address: array [0..19] of BYTE;
|
|
|
- Reserved: array[0..5] of BYTE;
|
|
|
- end;
|
|
|
- PWINSTATION_REMOTE_ADDRESS = ^_WINSTATION_REMOTE_ADDRESS;
|
|
|
- TWinStationRemoteAddress = _WINSTATION_REMOTE_ADDRESS;
|
|
|
- PWinStationRemoteAddress = PWINSTATION_REMOTE_ADDRESS;
|
|
|
-
|
|
|
-
|
|
|
-function AreWeRunningTerminalServices: Boolean;
|
|
|
-
|
|
|
-procedure CachedGetUserFromSid(pSid: PSID; pUserName: LPWSTR;
|
|
|
- var cbUserName: DWORD); stdcall;
|
|
|
-
|
|
|
-function CalculateDiffTime(TimeLow: INT64; TimeHigh: INT64): INT64;
|
|
|
- stdcall;
|
|
|
-
|
|
|
-// Calculate Elapsed time from a Filetime (UTC time) to DiffTime structure
|
|
|
-function CalculateElapsedTime(lpFileTime: PFILETIME; var DiffTime: TDiffTime):
|
|
|
- Boolean; stdcall;
|
|
|
-
|
|
|
-function CpuTime2Str(ACPUTime: LARGE_INTEGER): string;
|
|
|
-
|
|
|
-function CurrentDateTimeString(out lpBuffer: PWideChar): Boolean; stdcall;
|
|
|
-
|
|
|
-// This is the version for NT Terminal Server, 2000, XP/2003 and Server 2008
|
|
|
-function DateTimeString(DateTime: PFILETIME; lpBuffer: PWideChar): PWideChar;
|
|
|
- stdcall;
|
|
|
-
|
|
|
-// This is a wrapped for all OS versions
|
|
|
-function DateTimeStringSafe(DateTime: PFILETIME; lpBuffer: PWideChar;
|
|
|
- cchDest: SIZE_T): PWideChar; stdcall;
|
|
|
-
|
|
|
-// This is the Vista version which takes an additional parameter with
|
|
|
-// maximum buffer size (you have to set it)
|
|
|
-function DateTimeStringVista(DateTime: PFILETIME; lpBuffer: PWideChar;
|
|
|
- cchDest: SIZE_T): PWideChar; stdcall;
|
|
|
-
|
|
|
-function DiffTimeString(FTLow: FILETIME; FTHigh: FILETIME;
|
|
|
- out pwElapsedTime: PWideChar): Integer;
|
|
|
-
|
|
|
-// This is the version for NT Terminal Server, 2000, XP/2003 and Server 2008
|
|
|
-function ElapsedTimeString(DiffTime: PDiffTime; bShowSeconds: Boolean;
|
|
|
- lpElapsedTime: PWideChar): Integer; stdcall;
|
|
|
-
|
|
|
-// This is a wrapped for all OS versions
|
|
|
-function ElapsedTimeStringSafe(DiffTime: PDiffTime; bShowSeconds: Boolean;
|
|
|
- lpElapsedTime: PWideChar; cchDest: SIZE_T): Integer;
|
|
|
-
|
|
|
-// This is the Vista version of ElapsedTimeString which takes an additional
|
|
|
-// parameter with the count of characters for lpElapsedTime (you have to set it)
|
|
|
-function ElapsedTimeStringEx(DiffTime: PDiffTime; bShowSeconds: Boolean;
|
|
|
- lpElapsedTime: PWideChar; cchDest: SIZE_T): HRESULT; stdcall;
|
|
|
-
|
|
|
-function FileTime2DateTime(FileTime: TFileTime): TDateTime;
|
|
|
-
|
|
|
-function GetUnknownString: PWideChar; stdcall;
|
|
|
-
|
|
|
-function GetWTSLogonIdleTime(hServer: Handle; SessionId: DWORD;
|
|
|
- var sLogonTime: string; var sIdleTime: string): Boolean;
|
|
|
-
|
|
|
-// Helper function that inits the structure for you!
|
|
|
-procedure InitTermSrvCounterArray(
|
|
|
- var ATermSrvCounterArray: TTermSrvCounterArray);
|
|
|
-
|
|
|
-function IsTerminalServiceRunning: boolean;
|
|
|
-
|
|
|
-// Tested and working on Windows XP but doesn't seem to work on
|
|
|
-// Windows Vista/2008. Better use W version to be sure!
|
|
|
-function LogonIdFromWinStationNameA(hServer: HANDLE; pWinStationName: LPSTR;
|
|
|
- var SessionId: DWORD): BOOL; stdcall;
|
|
|
-
|
|
|
-// Tested and working on XP, 2003 and 2008
|
|
|
-function LogonIdFromWinStationNameW(hServer: HANDLE; pWinStationName: LPWSTR;
|
|
|
- var SessionId: DWORD): BOOL; stdcall;
|
|
|
-
|
|
|
-// This is the version for NT Terminal Server, 2000, XP/2003 and Server 2008
|
|
|
-// Reserve 66 bytes for pWinStationName and 21 for pUserName
|
|
|
-function QueryCurrentWinStation(pWinStationName: LPWSTR;
|
|
|
- pUserName: LPWSTR; var SessionId: DWORD; var WdFlag: DWORD): Boolean;
|
|
|
- stdcall;
|
|
|
-
|
|
|
-// This is the Vista version of QueryCurrentWinStation which takes an
|
|
|
-// additional parameter with the count of characters for pUserName
|
|
|
-// note that pWinStationname is Fixed Size!
|
|
|
-function QueryCurrentWinStationEx(pWinStationName: LPWSTR;
|
|
|
- pUserName: PWideChar; cchDest: DWORD; var SessionId: DWORD;
|
|
|
- var WdFlag: DWORD): Boolean; stdcall;
|
|
|
-
|
|
|
-function QueryCurrentWinStationSafe(pWinStationName: LPWSTR;
|
|
|
- pUserName: PWideChar; cchDest: DWORD; var SessionId: DWORD;
|
|
|
- var WdFlag: DWORD): Boolean; stdcall;
|
|
|
-
|
|
|
-function StrConnectState(ConnectState: WTS_CONNECTSTATE_CLASS;
|
|
|
- bShortString: BOOL): PWideChar; stdcall;
|
|
|
-
|
|
|
-function WinStationBroadcastSystemMessage(hServer: HANDLE;
|
|
|
- SendToAllWinstations: BOOL; SessionId: DWORD; TimeOut: DWORD;
|
|
|
- dwFlags: DWORD; lpdwRecipients: DWORD; uiMessage: ULONG; wParam: WPARAM;
|
|
|
- lParam: LPARAM; pResponse: LONGINT): LONGINT; stdcall;
|
|
|
-
|
|
|
-function WinStationCallBack(hServer:HANDLE; SessionId: DWORD;
|
|
|
- pPhoneNumber: LPWSTR): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationConnectW(hServer: Handle; SessionId: DWORD;
|
|
|
- TargetSessionId: DWORD; pPassword: LPWSTR;
|
|
|
- bWait: BOOL): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationDisconnect(hServer: THandle; SessionId: DWORD;
|
|
|
- bWait: BOOL): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationEnumerateA(hServer: HANDLE;
|
|
|
- var ppSessionInfo: PWTS_SESSION_INFOA; var pCount: DWORD): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationEnumerateW(hServer: HANDLE;
|
|
|
- var ppSessionInfo: PWTS_SESSION_INFOW; var pCount: DWORD): BOOL; stdcall;
|
|
|
-
|
|
|
-// Used to release memory allocated by WinStationGetAllProcesses
|
|
|
-function WinStationFreeGAPMemory(ClassIndex: DWORD;
|
|
|
- pProcessInfo: PWINSTA_PROCESS_INFO_ARRAY; Count: Integer): BOOL; stdcall;
|
|
|
-
|
|
|
-// Important! pProcessInfo must be nil before calling this function
|
|
|
-// by using Out parameter Delphi takes care of this for us
|
|
|
-function WinStationGetAllProcesses(hServer: HANDLE; ClassIndex: DWORD;
|
|
|
- var Count: Integer; out pProcessInfo: PWINSTA_PROCESS_INFO_ARRAY):
|
|
|
- BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationGetLanAdapterNameW(hServer: HANDLE; LanaId: DWORD;
|
|
|
- ProtocolTypeLength: DWORD; ProtocolType: PWideChar;
|
|
|
- var ResultLength: DWORD; var LanAdapterName: PWideChar): DWORD; stdcall;
|
|
|
-
|
|
|
-function WinStationGetProcessSid(hServer: Handle; dwPID: DWORD;
|
|
|
- ProcessStartTime: FILETIME; pProcessUserSid: PSID; var dwSidSize: DWORD):
|
|
|
- BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationGetRemoteIPAddress(hServer: HANDLE; SessionId: DWORD;
|
|
|
- var RemoteIPAddress: string; var Port: WORD): Boolean;
|
|
|
-
|
|
|
-function WinStationGetTermSrvCountersValue(hServer: Handle;
|
|
|
- dwArraySize: DWORD; PCountersArray: PTERM_SRV_COUNTER_ARRAY): BOOL;
|
|
|
- stdcall;
|
|
|
-
|
|
|
-function WinStationNameFromLogonIdA(hServer: HANDLE; SessionId: ULONG;
|
|
|
- pWinStationName: LPSTR): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationNameFromLogonIdW(hServer: HANDLE; SessionId: ULONG;
|
|
|
- pWinStationName: LPWSTR): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationQueryInformationW(hServer: HANDLE; SessionId: DWORD;
|
|
|
- WinStationInformationClass: Cardinal; pWinStationInformation: PVOID;
|
|
|
- WinStationInformationLength: DWORD; var pReturnLength: DWORD):
|
|
|
- Boolean; stdcall;
|
|
|
-
|
|
|
-function WinStationQueryLogonCredentialsW(
|
|
|
- var LogonCredentials: _LOGON_CREDENTIALSW): HRESULT; stdcall;
|
|
|
-
|
|
|
-function WinstationQueryUserToken(hServer: HANDLE; SessionId: DWORD;
|
|
|
- var hToken: HANDLE): BOOL;
|
|
|
-
|
|
|
-// WinStationRename needs Admin rights and always returns true
|
|
|
-// need to check GetLastError
|
|
|
-// Duplicate names are not allowed
|
|
|
-// Renaming a WinStation gives errors on Remote Connections:
|
|
|
-// the windowstation is busy processing connect, disconnect, reset
|
|
|
-// or login request
|
|
|
-
|
|
|
-// A version untested
|
|
|
-function WinStationRenameA(hServer: HANDLE; pOldWinStationName: LPSTR;
|
|
|
- pNewWinStationName: LPSTR): BOOL; stdcall;
|
|
|
-
|
|
|
-// W version was tested
|
|
|
-function WinStationRenameW(hServer: HANDLE; pOldWinStationName: LPWSTR;
|
|
|
- pNewWinStationName: LPWSTR): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationSendMessageA(hServer: HANDLE; SessionId: DWORD;
|
|
|
- pTitle: LPSTR; TitleLength: DWORD; pMessage: LPSTR; MessageLength: DWORD;
|
|
|
- Style: DWORD; Timeout: DWORD; var pResponse: DWORD;
|
|
|
- bWait: BOOL): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationSendMessageW(hServer: HANDLE; SessionId: DWORD;
|
|
|
- pTitle: LPWSTR; TitleLength: DWORD; pMessage: LPWSTR; MessageLength: DWORD;
|
|
|
- Style: DWORD; Timeout: DWORD; var pResponse: DWORD;
|
|
|
- bWait: BOOL): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationSetInformationA(hServer: HANDLE; SessionID: DWORD;
|
|
|
- InformationClass: DWORD; InformationClassDATA: PVOID;
|
|
|
- DataSize: DWORD): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationSetInformationW(hServer: HANDLE; SessionID: DWORD;
|
|
|
- InformationClass: DWORD; InformationClassDATA: PVOID;
|
|
|
- DataSize: DWORD): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationShadow(hServer: Handle; pServerName: LPWSTR;
|
|
|
- SessionId: DWORD; HotKey: DWORD; HKModifier: DWORD): BOOL; stdcall;
|
|
|
-
|
|
|
-// Admin can stop a shadowed session. SessionId is the targetsession
|
|
|
-// so the "victim" and not the one who is shadowing
|
|
|
-function WinStationShadowStop(hServer: Handle; SessionId: DWORD;
|
|
|
- bWait: BOOL): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationShutDownSystem(hSERVER: HANDLE;
|
|
|
- ShutdownFlags: DWORD): BOOL; stdcall;
|
|
|
-
|
|
|
-function WinStationTerminateProcess(hServer: Handle; dwPID: DWORD;
|
|
|
- dwExitCode: DWORD): BOOL; stdcall;
|
|
|
-
|
|
|
-{$ENDIF JWA_IMPLEMENTATIONSECTION}
|
|
|
-
|
|
|
-{$IFNDEF JWA_OMIT_SECTIONS}
|
|
|
-implementation
|
|
|
-
|
|
|
-uses
|
|
|
- JwaWinDLLNames;
|
|
|
-{$ENDIF JWA_OMIT_SECTIONS}
|
|
|
-
|
|
|
-{$IFNDEF JWA_INCLUDEMODE}
|
|
|
-const
|
|
|
- winstadll = 'winsta.dll';
|
|
|
- utildll = 'utildll.dll';
|
|
|
-{$ENDIF JWA_INCLUDEMODE}
|
|
|
-
|
|
|
-{$IFNDEF JWA_INTERFACESECTION}
|
|
|
-
|
|
|
-
|
|
|
-{$IFNDEF DYNAMIC_LINK}
|
|
|
-procedure CachedGetUserFromSid; external utildll name 'CachedGetUserFromSid';
|
|
|
-function CalculateDiffTime; external utildll name 'CalculateDiffTime';
|
|
|
-function CalculateElapsedTime; external utildll name 'CalculateElapsedTime';
|
|
|
-function CurrentDateTimeString; external utildll name 'CurrentDateTimeString';
|
|
|
-function DateTimeString; external utildll name 'DateTimeString';
|
|
|
-function DateTimeStringVista; external utildll name 'DateTimeString';
|
|
|
-function ElapsedTimeString; external utildll name 'ElapsedTimeString';
|
|
|
-// Vista version of ElapsedTimeString, exported name is ElapsedTimeString
|
|
|
-function ElapsedTimeStringEx; external utildll name 'ElapsedTimeString';
|
|
|
-function GetUnknownString; external utildll name 'GetUnknownString';
|
|
|
-function LogonIdFromWinStationNameA; external winstadll name 'LogonIdFromWinStationNameA';
|
|
|
-function LogonIdFromWinStationNameW; external winstadll name 'LogonIdFromWinStationNameW';
|
|
|
-function QueryCurrentWinStation; external utildll name 'QueryCurrentWinStation';
|
|
|
-function QueryCurrentWinStationEx; external utildll name 'QueryCurrentWinStation';
|
|
|
-function StrConnectState; external utildll name 'StrConnectState';
|
|
|
-function WinStationBroadcastSystemMessage; external winstadll name 'WinStationBroadcastSystemMessage';
|
|
|
-function WinStationCallBack; external winstadll name 'WinStationCallBack';
|
|
|
-function WinStationConnectW; external winstadll name 'WinStationConnectW';
|
|
|
-function WinStationDisconnect; external winstadll name 'WinStationDisconnect';
|
|
|
-function WinStationEnumerateA; external winstadll name 'WinStationEnumerateA';
|
|
|
-function WinStationEnumerateW; external winstadll name 'WinStationEnumerateW';
|
|
|
-function WinStationFreeGAPMemory; external winstadll name 'WinStationFreeGAPMemory';
|
|
|
-function WinStationGetAllProcesses; external winstadll name 'WinStationGetAllProcesses';
|
|
|
-function WinStationGetLanAdapterNameW; external winstadll name 'WinStationGetLanAdapterNameW';
|
|
|
-function WinStationGetProcessSid; external winstadll name 'WinStationGetProcessSid';
|
|
|
-function WinStationGetTermSrvCountersValue; external winstadll name 'WinStationGetTermSrvCountersValue';
|
|
|
-function WinStationNameFromLogonIdA; external winstadll name 'WinStationNameFromLogonIdA';
|
|
|
-function WinStationNameFromLogonIdW; external winstadll name 'WinStationNameFromLogonIdW';
|
|
|
-function WinStationQueryLogonCredentialsW; external winstadll name 'WinStationQueryLogonCredentialsW';
|
|
|
-function WinStationRenameA; external winstadll name 'WinStationRenameA';
|
|
|
-function WinStationRenameW; external winstadll name 'WinStationRenameW';
|
|
|
-function WinStationSendMessageA; external winstadll name 'WinStationSendMessageA';
|
|
|
-function WinStationSendMessageW; external winstadll name 'WinStationSendMessageW';
|
|
|
-function WinStationSetInformationA; external winstadll name 'WinStationSetInformationA';
|
|
|
-function WinStationSetInformationW; external winstadll name 'WinStationSetInformationW';
|
|
|
-function WinStationShadow; external winstadll name 'WinStationShadow';
|
|
|
-function WinStationShadowStop; external winstadll name 'WinStationShadowStop';
|
|
|
-function WinStationShutDownSystem; external winstadll name 'WinStationShutDownSystem';
|
|
|
-function WinStationQueryInformationW; external winstadll name 'WinStationQueryInformationW';
|
|
|
-function WinStationTerminateProcess; external winstadll name 'WinStationTerminateProcess';
|
|
|
-{$ELSE}
|
|
|
-
|
|
|
-var
|
|
|
- __CachedGetUserFromSid: Pointer;
|
|
|
-
|
|
|
-procedure CachedGetUserFromSid;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__CachedGetUserFromSid, utildll, 'CachedGetUserFromSid');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__CachedGetUserFromSid]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __CalculateDiffTime: Pointer;
|
|
|
-
|
|
|
-function CalculateDiffTime;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__CalculateDiffTime, utildll, 'CalculateDiffTime');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__CalculateDiffTime]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __CalculateElapsedTime: Pointer;
|
|
|
-
|
|
|
-function CalculateElapsedTime;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__CalculateElapsedTime, utildll, 'CalculateElapsedTime');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__CalculateElapsedTime]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __CurrentDateTimeString: Pointer;
|
|
|
-
|
|
|
-function CurrentDateTimeString;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__CurrentDateTimeString, utildll, 'CurrentDateTimeString');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__CurrentDateTimeString]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __DateTimeString: Pointer;
|
|
|
-
|
|
|
-function DateTimeString;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__DateTimeString, utildll, 'DateTimeString');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__DateTimeString]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __DateTimeStringVista: Pointer;
|
|
|
-
|
|
|
-function DateTimeStringVista;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__DateTimeStringVista, utildll, 'DateTimeString');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__DateTimeStringVista]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __ElapsedTimeString: Pointer;
|
|
|
-
|
|
|
-function ElapsedTimeString;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__ElapsedTimeString, utildll, 'ElapsedTimeString');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__ElapsedTimeString]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __ElapsedTimeStringEx: Pointer;
|
|
|
-
|
|
|
-function ElapsedTimeStringEx;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__ElapsedTimeStringEx, utildll, 'ElapsedTimeString');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__ElapsedTimeStringEx]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-var
|
|
|
- __GetUnknownString: Pointer;
|
|
|
-
|
|
|
-function GetUnknownString;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__GetUnknownString, utildll, 'GetUnknownString');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__GetUnknownString]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __LogonIdFromWinStationNameA: Pointer;
|
|
|
-
|
|
|
-function LogonIdFromWinStationNameA;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__LogonIdFromWinStationNameA, winstadll, 'LogonIdFromWinStationNameA');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__LogonIdFromWinStationNameA]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __LogonIdFromWinStationNameW: Pointer;
|
|
|
-
|
|
|
-function LogonIdFromWinStationNameW;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__LogonIdFromWinStationNameW, winstadll, 'LogonIdFromWinStationNameW');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__LogonIdFromWinStationNameW]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __QueryCurrentWinStation: Pointer;
|
|
|
-
|
|
|
-function QueryCurrentWinStation;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__QueryCurrentWinStation, utildll, 'QueryCurrentWinStation');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__QueryCurrentWinStation]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __QueryCurrentWinStationEx: Pointer;
|
|
|
-
|
|
|
-function QueryCurrentWinStationEx;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__QueryCurrentWinStationEx, utildll, 'QueryCurrentWinStation');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__QueryCurrentWinStationEx]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __StrConnectState: Pointer;
|
|
|
-
|
|
|
-function StrConnectState;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__StrConnectState, utildll, 'StrConnectState');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__StrConnectState]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationBroadcastSystemMessage: Pointer;
|
|
|
-
|
|
|
-function WinStationBroadcastSystemMessage;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationBroadcastSystemMessage, winstadll, 'WinStationBroadcastSystemMessage');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationBroadcastSystemMessage]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationCallBack: Pointer;
|
|
|
-
|
|
|
-function WinStationCallBack;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationCallBack, winstadll, 'WinStationCallBack');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationCallBack]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationConnectW: Pointer;
|
|
|
-
|
|
|
-function WinStationConnectW;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationConnectW, winstadll, 'WinStationConnectW');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationConnectW]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationDisconnect: Pointer;
|
|
|
-
|
|
|
-function WinStationDisconnect;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationDisconnect, winstadll, 'WinStationDisconnect');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationDisconnect]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationEnumerateA: Pointer;
|
|
|
-
|
|
|
-function WinStationEnumerateA;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationEnumerateA, winstadll, 'WinStationEnumerateA');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationEnumerateA]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationEnumerateW: Pointer;
|
|
|
-
|
|
|
-function WinStationEnumerateW;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationEnumerateW, winstadll, 'WinStationEnumerateW');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationEnumerateW]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationFreeGAPMemory: Pointer;
|
|
|
-
|
|
|
-function WinStationFreeGAPMemory;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationFreeGAPMemory, winstadll, 'WinStationFreeGAPMemory');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationFreeGAPMemory]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationGetAllProcesses: Pointer;
|
|
|
-
|
|
|
-function WinStationGetAllProcesses;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationGetAllProcesses, winstadll, 'WinStationGetAllProcesses');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationGetAllProcesses]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationGetLanAdapterNameW: Pointer;
|
|
|
-
|
|
|
-function WinStationGetLanAdapterNameW;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationGetLanAdapterNameW, winstadll, 'WinStationGetLanAdapterNameW');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationGetLanAdapterNameW]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationGetProcessSid: Pointer;
|
|
|
-
|
|
|
-function WinStationGetProcessSid;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationGetProcessSid, winstadll, 'WinStationGetProcessSid');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationGetProcessSid]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationGetTermSrvCountersValue: Pointer;
|
|
|
-
|
|
|
-function WinStationGetTermSrvCountersValue;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationGetTermSrvCountersValue, winstadll, 'WinStationGetTermSrvCountersValue');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationGetTermSrvCountersValue]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationNameFromLogonIdA: Pointer;
|
|
|
-
|
|
|
-function WinStationNameFromLogonIdA;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationNameFromLogonIdA, winstadll, 'WinStationNameFromLogonIdA');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationNameFromLogonIdA]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationNameFromLogonIdW: Pointer;
|
|
|
-
|
|
|
-function WinStationNameFromLogonIdW;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationNameFromLogonIdW, winstadll, 'WinStationNameFromLogonIdW');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationNameFromLogonIdW]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationQueryLogonCredentialsW: Pointer;
|
|
|
-
|
|
|
-function WinStationQueryLogonCredentialsW;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationQueryLogonCredentialsW, winstadll, 'WinStationQueryLogonCredentialsW');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationQueryLogonCredentialsW]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationRenameA: Pointer;
|
|
|
-
|
|
|
-function WinStationRenameA;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationRenameA, winstadll, 'WinStationRenameA');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationRenameA]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationRenameW: Pointer;
|
|
|
-
|
|
|
-function WinStationRenameW;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationRenameW, winstadll, 'WinStationRenameW');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationRenameW]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationQueryInformationW: Pointer;
|
|
|
-
|
|
|
-function WinStationQueryInformationW;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationQueryInformationW, winstadll, 'WinStationQueryInformationW');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationQueryInformationW]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationSendMessageA: Pointer;
|
|
|
-
|
|
|
-function WinStationSendMessageA;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationSendMessageA, winstadll, 'WinStationSendMessageA');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationSendMessageA]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationSendMessageW: Pointer;
|
|
|
-
|
|
|
-function WinStationSendMessageW;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationSendMessageW, winstadll, 'WinStationSendMessageW');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationSendMessageW]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationSetInformationA: Pointer;
|
|
|
-
|
|
|
-function WinStationSetInformationA;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationSetInformationA, winstadll, 'WinStationSetInformationA');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationSetInformationA]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationSetInformationW: Pointer;
|
|
|
-
|
|
|
-function WinStationSetInformationW;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationSetInformationW, winstadll, 'WinStationSetInformationW');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationSetInformationW]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationShadow: Pointer;
|
|
|
-
|
|
|
-function WinStationShadow;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationShadow, winstadll, 'WinStationShadow');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationShadow]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationShadowStop : Pointer;
|
|
|
-
|
|
|
-function WinStationShadowStop;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationShadowStop, winstadll, 'WinStationShadowStop');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationShadowStop]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationShutDownSystem : Pointer;
|
|
|
-
|
|
|
-function WinStationShutDownSystem;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationShutDownSystem, winstadll, 'WinStationShutDownSystem');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationShutDownSystem]
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-var
|
|
|
- __WinStationTerminateProcess: Pointer;
|
|
|
-
|
|
|
-function WinStationTerminateProcess;
|
|
|
-begin
|
|
|
- GetProcedureAddress(__WinStationTerminateProcess, winstadll, 'WinStationTerminateProcess');
|
|
|
- asm
|
|
|
- MOV ESP, EBP
|
|
|
- POP EBP
|
|
|
- JMP [__WinStationTerminateProcess]
|
|
|
- end;
|
|
|
-end;
|
|
|
-{$ENDIF DYNAMIC_LINK}
|
|
|
-
|
|
|
-// This function is not exported
|
|
|
-function IsVista: boolean;
|
|
|
-var VersionInfo: TOSVersionInfoEx;
|
|
|
-begin
|
|
|
- // Zero Memory and set structure size
|
|
|
- ZeroMemory(@VersionInfo, SizeOf(VersionInfo));
|
|
|
- VersionInfo.dwOSVersionInfoSize := SizeOf(VersionInfo);
|
|
|
- GetVersionEx(@VersionInfo);
|
|
|
-
|
|
|
- // Are we running Vista?
|
|
|
- Result := (VersionInfo.dwMajorVersion = 6) and
|
|
|
- (VersionInfo.dwMinorVersion = 0) and
|
|
|
- (VersionInfo.wProductType = VER_NT_WORKSTATION);
|
|
|
-end;
|
|
|
-
|
|
|
-// This the way QWinsta checks if Terminal Services is active:
|
|
|
-function AreWeRunningTerminalServices: Boolean;
|
|
|
-var VersionInfo: TOSVersionInfoEx;
|
|
|
- dwlConditionMask: Int64;
|
|
|
-begin
|
|
|
- // Zero Memory and set structure size
|
|
|
- ZeroMemory(@VersionInfo, SizeOf(VersionInfo));
|
|
|
- VersionInfo.dwOSVersionInfoSize := SizeOf(VersionInfo);
|
|
|
-
|
|
|
- // We are either Terminal Server or Personal Terminal Server
|
|
|
- VersionInfo.wSuiteMask := VER_SUITE_TERMINAL or VER_SUITE_SINGLEUSERTS;
|
|
|
- dwlConditionMask := VerSetConditionMask(0, VER_SUITENAME, VER_OR);
|
|
|
-
|
|
|
- // Test it
|
|
|
- Result := VerifyVersionInfo(VersionInfo, VER_SUITENAME, dwlConditionMask);
|
|
|
-end;
|
|
|
-
|
|
|
-// This functions converts CPU times as returned by
|
|
|
-// TSystemProcesses structure to a string
|
|
|
-function CpuTime2Str(ACPUTime: LARGE_INTEGER): String;
|
|
|
-var SystemTime: TSystemTime;
|
|
|
-{$IFDEF COMPILER7_UP}
|
|
|
- FS: TFormatSettings;
|
|
|
-{$ENDIF COMPILER7_UP}
|
|
|
-begin
|
|
|
- FileTimeToSystemTime(FILETIME(ACPUTime), SystemTime);
|
|
|
-{$IFDEF COMPILER7_UP}
|
|
|
- GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FS);
|
|
|
- Result := TimeToStr(SystemTimeToDateTime(SystemTime), FS);
|
|
|
-{$ELSE}
|
|
|
- Result := TimeToStr(SystemTimeToDateTime(SystemTime));
|
|
|
-{$ENDIF COMPILER7_UP}
|
|
|
-end;
|
|
|
-
|
|
|
-function DateTimeStringSafe(DateTime: PFILETIME; lpBuffer: PWideChar;
|
|
|
- cchDest: SIZE_T): PWideChar; stdcall;
|
|
|
-begin
|
|
|
- // Zero Memory
|
|
|
- ZeroMemory(lpBuffer, cchDest * SizeOf(WCHAR));
|
|
|
-
|
|
|
- // Are we running Vista?
|
|
|
- if IsVista then
|
|
|
- begin
|
|
|
- // Vista version
|
|
|
- Result := DateTimeStringVista(DateTime, lpBuffer, cchDest);
|
|
|
- end
|
|
|
- else begin
|
|
|
- // Other OS's (including server 2008!)
|
|
|
- Result := DateTimeString(DateTime, lpBuffer);
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-// DiffTimeString is a helper function that returns a formatted
|
|
|
-// Elapsed time string (the way Idle Time is displayed in TSAdmin)
|
|
|
-// Return value is the string length
|
|
|
-function DiffTimeString(FTLow: FILETIME; FTHigh: FILETIME;
|
|
|
- out pwElapsedTime: PWideChar): Integer;
|
|
|
-var
|
|
|
- DiffSecs: INT64;
|
|
|
- DiffTime: TDiffTime;
|
|
|
- NumChars: DWORD;
|
|
|
-begin
|
|
|
- // Get the Difftime where Time1 is the "oldest" time
|
|
|
- // Return value is the difference in seconds
|
|
|
- DiffSecs := CalculateDiffTime(Int64(FTLow), Int64(FTHigh));
|
|
|
- // Recalc DiffTime to TDiffTime
|
|
|
- ZeroMemory(@DiffTime, SizeOf(DiffTime));
|
|
|
- // Calculate no of whole days
|
|
|
- DiffTime.wDays := DiffSecs DIV SECONDS_PER_DAY;
|
|
|
- // Calculate no of whole hours
|
|
|
- DiffTime.wHours := DiffSecs MOD SECONDS_PER_DAY DIV SECONDS_PER_HOUR;
|
|
|
- // Calculate no of whole minutes
|
|
|
- DiffTime.wMinutes := DiffSecs MOD SECONDS_PER_DAY MOD SECONDS_PER_HOUR
|
|
|
- DIV SECONDS_PER_MINUTE; // Result = No of whole minutes
|
|
|
- // Calculate no of whole seconds
|
|
|
- DiffTime.wSeconds := DiffSecs MOD SECONDS_PER_DAY MOD SECONDS_PER_HOUR
|
|
|
- MOD SECONDS_PER_MINUTE; // Result = No of seconds
|
|
|
- // Note that Milliseconds are not used and therefore not calculated
|
|
|
-
|
|
|
- // Reserve Memory
|
|
|
- GetMem(pwElapsedTime, ELAPSED_TIME_STRING_LENGTH * SizeOf(WCHAR));
|
|
|
- // Format Elapsed TimeString in minutes (bShowSeconds = False)
|
|
|
- NumChars := ElapsedTimeStringSafe(@DiffTime, False, pwElapsedTime,
|
|
|
- ELAPSED_TIME_STRING_LENGTH);
|
|
|
- Result := NumChars;
|
|
|
- // Caller has to free memory when done
|
|
|
-end;
|
|
|
-
|
|
|
-function ElapsedTimeStringSafe(DiffTime: PDiffTime; bShowSeconds: Boolean;
|
|
|
- lpElapsedTime: PWideChar; cchDest: SIZE_T): Integer;
|
|
|
-var
|
|
|
- hr: HRESULT;
|
|
|
-begin
|
|
|
- // Zero Memory
|
|
|
- ZeroMemory(lpElapsedTime, cchDest * SizeOf(WCHAR));
|
|
|
-
|
|
|
- // Are we running Vista?
|
|
|
- if IsVista then
|
|
|
- begin
|
|
|
- hr := ElapsedTimeStringEx(DiffTime, bShowSeconds, lpElapsedTime,
|
|
|
- cchDest);
|
|
|
- if Succeeded(hr) then
|
|
|
- begin
|
|
|
- Result := cchDest;
|
|
|
- end
|
|
|
- else begin
|
|
|
- Result := 0;
|
|
|
- end;
|
|
|
-
|
|
|
- end
|
|
|
- else begin
|
|
|
- Result := ElapsedTimeString(DiffTime, bShowSeconds, lpElapsedTime);
|
|
|
- end;
|
|
|
- // Caller has to free memory when done
|
|
|
-end;
|
|
|
-
|
|
|
-function FileTime2DateTime(FileTime: TFileTime): TDateTime;
|
|
|
-var LocalFileTime: TFileTime;
|
|
|
- SystemTime: TSystemTime;
|
|
|
-begin
|
|
|
- FileTimeToLocalFileTime(FileTime, LocalFileTime);
|
|
|
- FileTimeToSystemTime(LocalFileTime, SystemTime);
|
|
|
- Result := SystemTimeToDateTime(SystemTime);
|
|
|
-end;
|
|
|
-
|
|
|
-function GetWTSLogonIdleTime(hServer: HANDLE; SessionId: DWORD;
|
|
|
- var sLogonTime: string; var sIdleTime: string): Boolean;
|
|
|
-var
|
|
|
- uReturnLength: DWORD;
|
|
|
- Info: _WINSTATION_INFORMATIONW;
|
|
|
- CurrentTime: TDateTime;
|
|
|
- LastInputTime: TDateTime;
|
|
|
- IdleTime: TDateTime;
|
|
|
- LogonTime: TDateTime;
|
|
|
- Days, Hours, Minutes: Word;
|
|
|
- {$IFDEF COMPILER7_UP}
|
|
|
- FS: TFormatSettings;
|
|
|
- {$ENDIF COMPILER7_UP}
|
|
|
-begin
|
|
|
- {$IFDEF COMPILER7_UP}
|
|
|
- GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FS);
|
|
|
- {$ENDIF COMPILER7_UP}
|
|
|
- uReturnLength := 0;
|
|
|
- try
|
|
|
- Result := WinStationQueryInformationW(hServer, SessionId, 8, @Info, SizeOf(Info), uReturnLength);
|
|
|
- if Result then
|
|
|
- begin
|
|
|
- LogonTime := FileTime2DateTime(Info.LogonTime);
|
|
|
- if YearOf(LogonTime) = 1601 then
|
|
|
- sLogonTime := ''
|
|
|
- else
|
|
|
- {$IFDEF COMPILER7_UP}
|
|
|
- sLogonTime := DateTimeToStr(LogonTime, FS);
|
|
|
- {$ELSE}
|
|
|
- sLogonTime := DateTimeToStr(LogonTime);
|
|
|
- {$ENDIF COMPILER7_UP}
|
|
|
- { from Usenet post by Chuck Chopp
|
|
|
- http://groups.google.com/group/microsoft.public.win32.programmer.kernel/browse_thread/thread/c6dd86e7df6d26e4/3cf53e12a3246e25?lnk=st&q=WinStationQueryInformationa+group:microsoft.public.*&rnum=1&hl=en#3cf53e12a3246e25
|
|
|
- 2) The system console session cannot go into an idle/disconnected state.
|
|
|
- As such, the LastInputTime value will always math CurrentTime for the
|
|
|
- console session.
|
|
|
- 3) The LastInputTime value will be zero if the session has gone
|
|
|
- disconnected. In that case, use the DisconnectTime value in place of
|
|
|
- LastInputTime when calculating the current idle time for a disconnected session.
|
|
|
- 4) All of these time values are GMT time values.
|
|
|
- 5) The disconnect time value will be zero if the sesson has never been
|
|
|
- disconnected.}
|
|
|
- CurrentTime := FileTime2DateTime(Info.CurrentTime);
|
|
|
- LastInputTime := FileTime2DateTime(Info.LastInputTime);
|
|
|
-
|
|
|
- // Disconnected session = idle since DisconnectTime
|
|
|
- if YearOf(LastInputTime) = 1601 then
|
|
|
- LastInputTime := FileTime2DateTime(Info.DisconnectTime);
|
|
|
-
|
|
|
- IdleTime := LastInputTime - CurrentTime;
|
|
|
- Days := Trunc(IdleTime);
|
|
|
- Hours := HourOf(IdleTime);
|
|
|
- Minutes := MinuteOf(IdleTime);
|
|
|
- if Days > 0 then
|
|
|
- sIdleTime := Format('%dd %d:%1.2d', [Days, Hours, Minutes])
|
|
|
- else
|
|
|
- if Hours > 0 then
|
|
|
- sIdleTime := Format('%d:%1.2d', [Hours, Minutes])
|
|
|
- else
|
|
|
- if Minutes > 0 then
|
|
|
- sIdleTime := IntToStr(Minutes)
|
|
|
- else
|
|
|
- sIdleTime := '-';
|
|
|
- end;
|
|
|
- except
|
|
|
- Result := False;
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-procedure InitTermSrvCounterArray(var ATermSrvCounterArray: TTermSrvCounterArray);
|
|
|
-begin
|
|
|
- ATermSrvCounterArray[1].dwIndex := TOTAL_SESSIONS_CREATED_COUNTER;
|
|
|
- ATermSrvCounterArray[2].dwIndex := TOTAL_SESSIONS_DISCONNECTED_COUNTER;
|
|
|
- ATermSrvCounterArray[3].dwIndex := TOTAL_SESSIONS_RECONNECTED_COUNTER;
|
|
|
- ATermSrvCounterArray[4].dwIndex := TOTAL_SESSIONS_TOTAL_CONNECTED_NOW_COUNTER;
|
|
|
- ATermSrvCounterArray[5].dwIndex := TOTAL_SESSIONS_TOTAL_DISCONNECTED_NOW_COUNTER;
|
|
|
- ATermSrvCounterArray[6].dwIndex := TOTAL_SESSIONS_TOTAL_CONNECTED_NOW_COUNTER_2;
|
|
|
- ATermSrvCounterArray[7].dwIndex := TOTAL_SESSIONS_TOTAL_DISCONNECTED_NOW_COUNTER_2;
|
|
|
-end;
|
|
|
-
|
|
|
-// This is the way WTSApi32.dll checks if Terminal Service is running
|
|
|
-function IsTerminalServiceRunning: boolean;
|
|
|
-var hSCM: HANDLE;
|
|
|
- hService: HANDLE;
|
|
|
- ServiceStatus: SERVICE_STATUS;
|
|
|
-begin
|
|
|
- Result := False;
|
|
|
- // Open handle to Service Control Manager
|
|
|
- hSCM := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, GENERIC_READ);
|
|
|
- if hSCM > 0 then
|
|
|
- begin
|
|
|
- // Open handle to Terminal Server Service
|
|
|
- hService := OpenService(hSCM, 'TermService', GENERIC_READ);
|
|
|
- if hService > 0 then
|
|
|
- begin
|
|
|
- // Check if the service is running
|
|
|
- QueryServiceStatus(hService, ServiceStatus);
|
|
|
- Result := ServiceStatus.dwCurrentState = SERVICE_RUNNING;
|
|
|
- // Close the handle
|
|
|
- CloseServiceHandle(hService);
|
|
|
- end;
|
|
|
- // Close the handle
|
|
|
- CloseServiceHandle(hSCM);
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-function QueryCurrentWinStationSafe(pWinStationName: LPWSTR;
|
|
|
- pUserName: PWideChar; cchDest: DWORD; var SessionId: DWORD;
|
|
|
- var WdFlag: DWORD): Boolean;
|
|
|
-begin
|
|
|
- // Zero Memory
|
|
|
- ZeroMemory(pWinStationName, 66);
|
|
|
- ZeroMemory(pUserName, cchDest * SizeOf(WCHAR));
|
|
|
-
|
|
|
- // Are we running Vista?
|
|
|
- if IsVista then
|
|
|
- begin
|
|
|
- Result := QueryCurrentWinStationEx(pWinStationName, pUserName, cchDest,
|
|
|
- SessionId, WdFlag);
|
|
|
- end
|
|
|
- else begin
|
|
|
- Result := QueryCurrentWinStation(pWinStationName, pUserName, SessionId,
|
|
|
- WdFlag);
|
|
|
- end;
|
|
|
-
|
|
|
-end;
|
|
|
-
|
|
|
-function WinStationGetRemoteIPAddress(hServer: HANDLE; SessionId: DWORD;
|
|
|
- var RemoteIPAddress: string; var Port: WORD): Boolean;
|
|
|
-var WinStationRemoteIPAddress: TWinStationRemoteAddress;
|
|
|
- pReturnLength: DWORD;
|
|
|
-begin
|
|
|
- // Zero Memory
|
|
|
- ZeroMemory(@WinStationRemoteIPAddress, SizeOf(WinStationRemoteIPAddress));
|
|
|
- // Query Remote Address
|
|
|
- Result := WinStationQueryInformationW(hServer, SessionId,
|
|
|
- WinStationRemoteAddress, @WinStationRemoteIPAddress,
|
|
|
- SizeOf(WinStationRemoteIPAddress), pReturnLength);
|
|
|
- if Result then
|
|
|
- begin
|
|
|
- // If the AddressFamily is IPv4
|
|
|
- if WinStationRemoteIPAddress.AddressFamily = AF_INET then
|
|
|
- begin
|
|
|
- // The ntohs function converts a u_short from TCP/IP network byte order
|
|
|
- // to host byte order (which is little-endian on Intel processors).
|
|
|
- Port := ntohs(WinStationRemoteIPAddress.Port);
|
|
|
- with WinStationRemoteIPAddress do
|
|
|
- begin
|
|
|
- // format the IP Address as string
|
|
|
- RemoteIPAddress := Format('%d.%d.%d.%d', [Address[2], Address[3],
|
|
|
- Address[4], Address[5]]);
|
|
|
- // If you want to convert the to a sockaddr structure you could
|
|
|
- // user WSAStringToAddress
|
|
|
- end;
|
|
|
- end
|
|
|
- else begin
|
|
|
- Result := False;
|
|
|
- Port := 0;
|
|
|
- RemoteIPAddress := '';
|
|
|
- // SetLastError to give the user a clue as to why we failed..
|
|
|
- // An address incompatible with the requested protocol was used.
|
|
|
- // (An address incompatible with the requested protocol was used.)
|
|
|
- SetLastError(WSAEAFNOSUPPORT);
|
|
|
- end;
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-function WinStationQueryUserToken(hServer: HANDLE; SessionId: DWORD;
|
|
|
- var hToken: HANDLE): BOOL;
|
|
|
-var WinstaUserToken: _WINSTA_USER_TOKEN;
|
|
|
- dwReturnLength: DWORD;
|
|
|
- LUID: _LUID;
|
|
|
- bWasPrivEnabled: Boolean;
|
|
|
- Res: NTSTATUS;
|
|
|
-begin
|
|
|
- // Enable SeTcbPrivilege (system account has this enabled by default)
|
|
|
- LookupPrivilegeValue(nil, SE_TCB_NAME, LUID);
|
|
|
- Res := RtlAdjustPrivilege(LUID.LowPart, True, False, @bWasPrivEnabled);
|
|
|
-
|
|
|
- // Initialize structure
|
|
|
- WinstaUserToken.ProcessId := GetCurrentProcessId; // Current Process Id
|
|
|
- WinstaUserToken.ThreadId := GetCurrentThreadId; // Current Thread Id
|
|
|
- WinstaUserToken.TokenHandle := 0;
|
|
|
-
|
|
|
- if Res = STATUS_SUCCESS then
|
|
|
- begin
|
|
|
- // Query for the token, we are only allowed to do this if we are the
|
|
|
- // System account (else ACCESS_DENIED is returned)
|
|
|
- Result := WinStationQueryInformationW(hServer, SessionId, WinStationToken,
|
|
|
- @WinstaUserToken, SizeOf(WinstaUserToken), dwReturnLength);
|
|
|
- hToken := WinStaUserToken.TokenHandle;
|
|
|
-
|
|
|
- // Restore state of SeTcbPrivilege
|
|
|
- RtlAdjustPrivilege(LUID.LowPart, bWasPrivEnabled, False, @bWasPrivEnabled);
|
|
|
- end
|
|
|
- else begin
|
|
|
- Result := False;
|
|
|
- // Convert NTStatus to WinError and SetLastError
|
|
|
- SetLastError(RtlNtStatusToDosError(Res));
|
|
|
- end;
|
|
|
-
|
|
|
-end;
|
|
|
-
|
|
|
-{$ENDIF JWA_INTERFACESECTION}
|
|
|
-
|
|
|
-{$IFNDEF JWA_OMIT_SECTIONS}
|
|
|
-end.
|
|
|
-{$ENDIF JWA_OMIT_SECTIONS}
|
|
|
-
|