views:

582

answers:

2

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

Which is populated by 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 array is being populated, but I have no idea how to convert it into a useful string or integer values. The MDSN documentation is sparse: http://msdn.microsoft.com/en-us/library/aa383857(VS.85).aspx

+1  A: 

You're almost there with your code. I agree with you, the MSDN is not quite explicit on what's inside that byte array, but here's what you can do :

IPAddress address = new IPAddress(_ClientIPAddress.Address.Skip(2).Take(4).ToArray());

The first two bytes do not seem to be used, but in the case of AF_INET (which is IPv4, or 2) the next four bytes are the IPv4 address of the client.

You might also want to make sure that your code will handle IPv6 (AF_INET6) properly, or handle the fact that AF_INET6 is a likely value. You'll probably need to read 16 bytes instead of 4 for this protocol.

Jerome Laban