12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409 |
- {******************************************************************}
- { 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}
|