This question tells me how to detect a remote desktop session.
Do anybody know if it's possible to find out from where the remote connection was initialized?
@Vegar, you can use the WTSEnumerateSessions and WTSQuerySessionInformation functions to retrieve this info.
check this link for an example using the Jedi Api Headers.
check this code.
program ProjectTsInfo;
{$APPTYPE CONSOLE}
Uses
Windows,
JwaWinType,
JwaWtsApi32,
JwaWinsock2,
SysUtils,
TypInfo;
type
PWtsSessionInfoAArray = ^TWtsSessionInfoAArray;
TWtsSessionInfoAArray = array[0..ANYSIZE_ARRAY-1] of WTS_SESSION_INFOA;
//Get the info for all clients connected
procedure GetAll_TSClientsInfo;
var
SessionInfoAArray: PWtsSessionInfoAArray;
ClientAddr : PWtsClientAddress;
ClientName : PAnsiChar;
//ClientInfo : PWTSCLIENT;
RetBytes : Cardinal;
IPAddr : String;
i : integer;
pCount : Cardinal;
SessionId : Cardinal;
begin
if WtsEnumerateSessions(WTS_CURRENT_SERVER, 0, 1, PWTS_SESSION_INFO(SessionInfoAArray), pCount) then
begin
for i := 0 to pCount - 1 do
begin
SessionId:=SessionInfoAArray^[i].SessionId;
WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientAddress, Pointer(ClientAddr), RetBytes);
WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientName, Pointer(ClientName), RetBytes);
//WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientInfo, Pointer(ClientInfo), RetBytes); //This value is supported for Windows Server 2008 and Windows Vista with SP1.
try
case ClientAddr^.AddressFamily of
AF_INET:
IPAddr:= Format('%d.%d.%d.%d', [
ClientAddr^.Address[2],
ClientAddr^.Address[3],
ClientAddr^.Address[4],
ClientAddr^.Address[5]
]);
else
IPAddr:= '<unknow>';
end;
WriteLn(Format('Session Id : %d ', [SessionId]));
WriteLn(Format('Client Name : %s ', [ClientName]));
WriteLn(Format('Station Name: %s ', [SessionInfoAArray^[i].pWinStationName]));
WriteLn(Format('State : %s ', [GetEnumName(TypeInfo(WTS_CONNECTSTATE_CLASS),integer(SessionInfoAArray^[i].State))]));
WriteLn(Format('IP : %s ', [IPAddr]));
//supported for Windows Server 2008 and Windows Vista with SP1.
{
WriteLn(Format('ClientName : %s ', [ClientInfo^.ClientName]));
WriteLn(Format('Domain : %s ', [ClientInfo^.Domain]));
WriteLn(Format('UserName : %s ', [ClientInfo^.UserName]));
WriteLn(Format('WorkDirectory : %s ', [ClientInfo^.WorkDirectory]));
WriteLn(Format('InitialProgram : %s ', [ClientInfo^.InitialProgram]));
WriteLn(Format('EncryptionLevel : %d ', [ClientInfo^.EncryptionLevel]));
WriteLn(Format('HRes : %d ', [ClientInfo^.HRes]));
WriteLn(Format('VRes : %d ', [ClientInfo^.VRes]));
WriteLn(Format('ColorDepth : %d ', [ClientInfo^.ColorDepth]));
WriteLn(Format('ClientDirectory : %s ', [ClientInfo^.ClientDirectory]));
}
Writeln('');
finally
WTSFreeMemory(ClientAddr);
WTSFreeMemory(ClientName);
end;
end;
end;
WtsFreeMemory(SessionInfoAArray);
end;
//Get the ip address of the actual connected client
function GetIpActualClient : string;
var
ClientAddr : PWtsClientAddress;
RetBytes : Cardinal;
IPAddr : String;
SessionId : Cardinal;
begin
SessionId:=WTS_CURRENT_SESSION;
WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientAddress, Pointer(ClientAddr), RetBytes);
try
case ClientAddr^.AddressFamily of
AF_INET:
IPAddr:= Format('%d.%d.%d.%d', [
ClientAddr^.Address[2],
ClientAddr^.Address[3],
ClientAddr^.Address[4],
ClientAddr^.Address[5]
]);
else
IPAddr:= '<unknow>';
end;
Result:=IPAddr;
finally
WTSFreeMemory(ClientAddr);
end;
end;
begin
Writeln('IP Actual client '+GetIpActualClient);
Writeln('-----------------------------------');
GetAll_TSClientsInfo;
Readln;
end.
UPDATE
As @Remko says, the WTSQuerySessionInformation function with the WTSClientAddress type, can return the local IP of the client. if you wanna get the real ip you can use the WinStationGetRemoteIPAddress helper function located in the JwaWinSta unit.
Var
Port : Word;
IpAddr : WideString;
Begin
WinStationGetRemoteIPAddress(WTS_CURRENT_SERVER,WTS_CURRENT_SESSION,IpAddr,Port);
End;