Hi,
I have a big problem.
I have a service that monitors sessions on a PC/Server.
If I develop the application in 32 bit and it works, but if I develop the application in 64 bit it goes into error (but not always!!):
Error 87 : The Parameter is incorrect
This is my code:
Unit Wtsapi32:
unit UN_Wtsapi32;
interface
uses
Windows;
const
WINSTATIONNAME_LENGTH = 32;
DOMAIN_LENGTH = 17;
USERNAME_LENGTH = 20;
CLIENTNAME_LENGTH = 20;
CLIENTADDRESS_LENGTH = 30;
type
WTS_INFO_CLASS = (
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType,
WTSIdleTime,
WTSLogonTime,
WTSIncomingBytes,
WTSOutgoingBytes,
WTSIncomingFrames,
WTSOutgoingFrames,
WTSClientInfo,
WTSSessionInfo,
WTSSessionInfoEx,
WTSConfigInfo,
WTSValidationInfo,
WTSSessionAddressV4,
WTSIsRemoteSession
);
WTS_CONNECTSTATE_CLASS = (
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
);
{$IFDEF UNICODE}
PWTS_INFO = ^WTS_INFO;
WTS_INFO = record
State:WTS_CONNECTSTATE_CLASS ;
SessionId: DWORD;
IncomingBytes :DWORD;
OutgoingBytes :DWORD;
IncomingFrames:DWORD;
OutgoingFrames:DWORD;
IncomingCompressedBytes:DWORD;
OutgoingCompressedBytes:DWORD;
WinStationName: array[0..WINSTATIONNAME_LENGTH - 1] of WCHAR;
Domain: array[0..DOMAIN_LENGTH - 1] of WCHAR;
UserName:array[0..USERNAME_LENGTH - 1] of WCHAR;
ConnectTime:LARGE_INTEGER;
DisconnectTime:LARGE_INTEGER;
LastInputTime:LARGE_INTEGER;
LogonTime:LARGE_INTEGER;
CurrentTime:LARGE_INTEGER;
end;
{$ENDIF}
function WTSEnumerateSessions(
hServer: THandle;
Reserved: DWORD;
Version: DWORD;
var ppSessionInfo:PWTS_SESSION_INFO;
var pCount: DWORD
): BOOL; stdcall; external 'Wtsapi32.dll' name {$IFDEF UNICODE}'WTSEnumerateSessionsW'{$ELSE}'WTSEnumerateSessionsA'{$ENDIF};
function WTSQuerySessionInformation(
hServer: NativeUInt;
SessionId: DWORD;
WTSInfoClass: WTS_INFO_CLASS;
var ppBuffer: PLPWSTR;
var pBytesReturned: PDWORD): BOOL; stdcall; external 'Wtsapi32.dll' name {$IFDEF UNICODE}'WTSQuerySessionInformationW'{$ELSE}'WTSQuerySessionInformationA'{$ENDIF};
unit test:
//...
function GetSessionInfo(id:DWORD):TSessionInfo;
var
wpSessionInfo:PWTS_INFO;
pSessionInfo:PLPWSTR;
pBytesReturned:PDWORD;
iderr:integer;
begin
Result.ID:=-1;
if id >0 then
begin
try
if (WTSQuerySessionInformation (
WTS_CURRENT_SERVER_HANDLE,
id,
WTS_INFO_CLASS.WTSSessionInfo,
pSessionInfo,
pBytesReturned) ) then
begin
Result.ID := id;
wpSessionInfo:=PWTS_INFO(pSessionInfo);
//user name
Result.user:= wpSessionInfo.UserName;
//station name
Result.StationName:= wpSessionInfo.WinStationName;
//domain name
Result.domain:=wpSessionInfo.Domain;
//connection status
Result.ConnectState:=wpSessionInfo.State;
end
else begin
idErr:=GetLastError;
GV_TxtFileLog.Log('[GetSessionInfo] id '+intTostr(id)+' ERR : '+ intToStr(idErr)+' '+SysErrorMessage(idErr),true);
end;
except
on e:exception do
GV_TxtFileLog.Log('[GetSessionInfo] id '+intTostr(id)+' EX : '+ e.Message,true);
end;
end;
end;
function SF_GetOpenedSessions(var codeErr:integer) :TSessionsInfo;
var
Sessions, Session: PWTS_SESSION_INFO;
NumSessions:DWORD;
I:DWORD;
SessionInfo:TSessionInfo;
pSessionInfo:PLPWSTR;
pBytesReturned:PDWORD;
wpSessionInfo:PWTS_INFO;
id:DWORD;
begin
SetLength(result,0);
codeErr:=0;
if WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, Sessions, NumSessions) then
begin
try
if NumSessions > 0 then
begin
Session := Sessions;
for i := 0 to NumSessions do
begin
id:=Session.SessionId;
if id > 0 then
begin
GV_TxtFileLog.Log('[SF_GetOpenedSessions] GetSessionInfo '+ intToStr(id) );
SessionInfo := GetSessionInfo(id);
if SessionInfo.ID>0 then
begin
SetLength(result, length(Result)+1);
Result[length(Result)-1]:= SessionInfo;
end;
end;
Inc(Session);
end;
end;
except
codeErr:=GetLastError;
GV_TxtFileLog.Log('[SF_GetOpenedSessions] WTSQuerySessionInformation err : '+IntToStr(codeErr)+' '+SysErrorMessage(codeErr), true);
end;
WTSFreeMemory(Sessions);
end
else begin
codeErr:=GetLastError;
GV_TxtFileLog.Log('[SF_GetOpenedSessions] WTSEnumerateSessions err : '+IntToStr(codeErr)+' '+SysErrorMessage(codeErr), true);
end;
end;
When I call the "SF_GetOpenedSessions" function I get error 87 when this function then calls the "GetSessionInfo" function.
While if I use "GetSessionInfo" passing it the SID of the program it works perfectly... does anyone have an idea why? (I'm going crazy about it!)
Compiling in 32 Bit, however, I have no problem.