Unpacking _WTS_CLIENT_ADDRESS.Address in vb.net (Get IP Address from Terminal Services Client)
I have the following structure:
<StructLayout(LayoutKind.Sequential)> _
Public Structure _WTS_CLIENT_ADDRESS
Public AddressFamily As Integer
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)> _
Public Address() As Byte
End Structure
Filled in with the following call:
Dim _ClientIPAddress As New _WTS_CLIENT_ADDRESS
Dim rtnPtr As IntPtr
Dim rtncount As Int32
NativeMethods.WTSQuerySessionInformation(CInt(NativeMethods.WTS_CURRENT_SERVER_HANDLE), NativeMethods.WTS_CURRENT_SESSION, NativeMethods.WTS_INFO_CLASS.WTSClientAddress, rtnPtr, rtncount)
'_ClientIPAddress()
_ClientIPAddress = _
CType(System.Runtime.InteropServices.Marshal.PtrToStructure(rtnPtr, GetType(_WTS_CLIENT_ADDRESS)), _WTS_CLIENT_ADDRESS)
The address byte mask is being filled in, but I have no idea how to convert it to a usable string or integer values. MDSN documentation is sparse: http://msdn.microsoft.com/en-us/library/aa383857(VS.85).aspx
source to share
You're almost with your code. I agree with you, MSDN isn't quite clear on what's inside this byte array, but here's what you can do:
IPAddress address = new IPAddress(_ClientIPAddress.Address.Skip(2).Take(4).ToArray());
The first two bytes don't seem to be used, but in the case of AF_INET (which is IPv4 or 2), the next four bytes are the client's IPv4 address.
You can also make sure your code will handle IPv6 (AF_INET6) correctly, or handle the fact that AF_INET6 is a likely value. You will probably need to read 16 bytes instead of 4 for this protocol.
source to share
The real answer can be found here. http://www.tech-archive.net/Archive/Windows/microsoft.public.windows.terminal_services/2007-03/msg00474.html
source to share