Detect source of remote desktop connection
Solution 1
Since it's in windows use netstat to check which machines you are connected to and on which ports and just parse out the address for the one that uses the port that remote desktop uses.
Solution 2
@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;
Solution 3
For me, this worked, it gets the name of the machine connected.
Environment.GetEnvironmentVariable("CLIENTNAME")
Solution 4
WTSQuerySessionInformation returns the client IP as the client reports it, this will probably be (one) of it's local IP Address. If you want to know the REAL ip address and port that is connected you can use WinStationQueryInformationW with information class WinStationRemoteAddress. You will need my unit JwaWinsta from the Jedi Apilib.
I have provided a simple wrapper in the same unit as well:
function WinStationGetRemoteIPAddress(hServer: HANDLE; SessionId: DWORD;
var RemoteIPAddress: WideString; var Port: WORD): Boolean;
Solution 5
try running qwinsta
Comments
-
Vegar almost 2 years
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 about 14 yearsAnd since remote desktop always uses port 3389, this will work. Thanks!
-
Ritsaert Hornstra about 14 yearsThis would only work if you have a single remote connection else you cannot see which sessions connects to which remote machine.
-
Rob Kennedy about 14 yearsIs it even necessary to use
WTSEnumerateSessions
? I think usingwts_Current_Session
for the session ID would be sufficient. -
Rob Kennedy about 14 yearsIs the output of
netstat
affected by the current locale? That can make string parsing much more complicated. Prefer an API solution over one that relies on external programs and variable output formats. -
Ritsaert Hornstra about 14 yearsTo get you own session, use ProcessIdToSessionId
-
RRUZ about 14 years@Rob you are right the WTSEnumerateSessions function is to get the info for all sessions, i posted an example using wts_Current_Session and WTSEnumerateSessions. ;)
-
RRUZ about 14 years+1 @Remko you are right the WTSClientAddress can report the local ip instead of the real ip. i update my answer. p.s : thanks very much for you great work in the Jedi Api Headers. ;)
-
Vegar about 14 yearsI'm trying the WinStationGetRemoteIPaddress( ) now. I'm at home with a RDC to my office computer. When I call this method, it returns the ip address of my router, not my local machine. Btw, netstat returns WORKGROUP in this case. Not too useful...
-
Remko about 14 years@Vegar: yes of course it does, you make the connection with your external ip which in most cases is the ip that your router or modem has. WinStationGetRemoteIPAddress returns the IP address as reported by Terminal Server and it will match output of netstat on the server.
-
AFK about 14 yearsyea, I agree it's a nasty a solution, but it's a fast one.
-
Mark Robinson about 14 yearsremote desktop doesn't always use port 3389, this can be user defined, and often is for security if a vpn isn't being used