Click here to Skip to main content
15,881,027 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to get the incoming and outgoing bytes using WTSQuerySessionInformation

running the below "Query"

VB
If WTSQuerySessionInformation(pServer, oSessionInfo.iSessionID, WTS_INFO_CLASS.WTSIncomingBytes, pAddress, iReturned) = True Then
    Dim inBytes As String = Marshal.PtrToStringAuto(pAddress)
End If


this is always returning false and there for never setting the value. Does anyone have any experience with this they can share?

I am new to using this and with it was already able to get user name, ip address and so but when it comes to the session traffic i have had no luck.

Any information would be a great help,

Thanks

[edit]code block fixed[/edit]
Posted
Updated 14-Nov-12 10:31am
v2
Comments
Dave Kreskowiak 14-Nov-12 16:31pm    
Without seeing your code that Declares the WTSQuerySessionInformation function and the code that sets the values you're passing into it, it's pretty much impossible to disagnose what's going wrong.
DinoRondelly 14-Nov-12 17:03pm    
Sorry didnt think to post it all,


#Region "Constants"
Public Const WTS_CURRENT_SESSION As Integer = -1
#End Region

#Region "Dll Imports"

<DllImport("wtsapi32.dll")> _
Private Shared Function WTSEnumerateSessions(pServer As IntPtr, <marshalas(unmanagedtype.u4)> iReserved As Integer, <marshalas(unmanagedtype.u4)> iVersion As Integer, ByRef pSessionInfo As IntPtr, <marshalas(unmanagedtype.u4)> ByRef iCount As Integer) As Integer
End Function

<DllImport("wtsapi32.dll")> _
Public Shared Function WTSQuerySessionInformation(pServer As System.IntPtr, iSessionID As Integer, oInfoClass As WTS_INFO_CLASS, ByRef pBuffer As System.IntPtr, ByRef iBytesReturned As UInteger) As Boolean
End Function

<DllImport("wtsapi32.dll")> _
Private Shared Sub WTSFreeMemory(pMemory As IntPtr)
End Sub

#End Region

#Region "Structures"
'Structure for Terminal Service Client IP Address
<structlayout(layoutkind.sequential)> _
Private Structure WTS_CLIENT_ADDRESS
Public iAddressFamily As Integer
<marshalas(unmanagedtype.byvalarray, sizeconst:="20)"> _
Public bAddress As Byte()
End Structure

'Structure for Terminal Service Session Info
<structlayout(layoutkind.sequential)> _
Private Structure WTS_SESSION_INFO
Public iSessionID As Integer
<marshalas(unmanagedtype.lpstr)> _
Public sWinsWorkstationName As String
Public oState As WTS_CONNECTSTATE_CLASS
End Structure

'Structure for Terminal Service Session Client Display
<structlayout(layoutkind.sequential)> _
Private Structure WTS_CLIENT_DISPLAY
Public iHorizontalResolution As Integer
Public iVerticalResolution As Integer
'1 = The display uses 4 bits per pixel for a maximum of 16 colors.
'2 = The display uses 8 bits per pixel for a maximum of 256 colors.
'4 = The display uses 16 bits per pixel for a maximum of 2^16 colors.
'8 = The display uses 3-byte RGB values for a maximum of 2^24 colors.
'16 = The display uses 15 bits per pixel for a maximum of 2^15 colors.
Public iColorDepth As Integer
End Structure
#End Region

#Region "Enumurations"
Public Enum WTS_CONNECTSTATE_CLASS
WTSActive
WTSConnected
WTSConnectQuery
WTSShadow
WTSDisconnected
WTSIdle
WTSListen
WTSReset
WTSDown
WTSInit
End Enum

Public Enum 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
WTSConfigInfo
WTSValidationInfo
WTSSessionAddressV4
WTSIsRemoteSession
End Enum
#End Region

Public Shared Function GetUsers() As List(Of Users)

Dim myAPI As New UsersAPI
Dim UserList As New List(Of Users)

Dim pServer As IntPtr = IntPtr.Zero
Dim sUserName As String = String.Empty
Dim workStation As String = String.Empty

Dim sDomain As String = String.Empty
Dim sClientApplicationDirectory As String = String.Empty
Dim sIPAddress As String = String.Empty

Dim oClientAddres As New WTS_CLIENT_ADDRESS()
Dim oClientDisplay As New WTS_CLIENT_DISPLAY()
Dim pSessionInfo As IntPtr = IntPtr.Zero
Dim iCount As Integer = 0

Dim iReturnValue As Integer = WTSEnumerateSessions(pServer, 0, 1, pSessionInfo, iCount)
Dim iDataSize As Integer = Marshal.SizeO

1 solution

First, when you check the return value for WTSQuerySessionInformation, you're not doing anything when the return value is False. Call GetLastError[^] to find out what it's complaining about.

Second, don't rely on Enum to correctly assign type and values to its members. Specifically assign a type to the Enum and every value. This makes the code very explicit so no assumptions are made and also makes it easier to maintain the code.
 
Share this answer
 
Comments
DinoRondelly 15-Nov-12 10:30am    
I did what you suggested using the GetLastError, put vs complained about it so after some research i used Win32Exception(Marshal.GetLastWin32Error()).Message
<pre>
Dim errorMessage As String = New Win32Exception(Marshal.GetLastWin32Error()).Message
</pre>

Returns,
WTS_INFO_CLASS.WTSIncomingBytes - Returns operation completed successfully but the value is null

WTS_INFO_CLASS.WTSOutgoingBytes - returns request not supported
WTS_INFO_CLASS.WTSIncomingFrames - returns request not supported
WTS_INFO_CLASS.WTSOutgoingFrames - returns request not supported

So that brings me back to the original problem.
I have been banging my head off my desk trying to figure this out.

The program I created is useless with out this user information, Also I have looked into a packet sniffer but unless its constantly running on the servers the results it gives me arent going to reflect the users session its just going to reflect since the sniffer started.

I have been all over the internet trying to figure this out and with no luck. I find it hard to believe that no one has ever had to so something like this before.

Is there any other way to get this information?

Windows displays this information in the remote desktop service manager when you right click on a user and select status. Is there away to tap into that and pull the values?
Dave Kreskowiak 15-Nov-12 17:04pm    
OK, the code that's calling WTSQuerySessionInformation is missing from the above posts.
DinoRondelly 15-Nov-12 17:07pm    
Here it is, this includes the ones that are working

<pre lang="vb">

If iReturnValue <> 0 Then
'Go to all sessions
For i As Integer = 0 To iCount - 1

oClientDisplay = Nothing

Dim oSessionInfo As WTS_SESSION_INFO = CType(Marshal.PtrToStructure(CType(iCurrent, System.IntPtr), GetType(WTS_SESSION_INFO)), WTS_SESSION_INFO)
iCurrent += iDataSize

Dim iReturned As UInteger = 0

'Get the IP address of the Terminal Services User
Dim pAddress As IntPtr = IntPtr.Zero
If WTSQuerySessionInformation(pServer, oSessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientAddress, pAddress, iReturned) = True Then
oClientAddres = CType(Marshal.PtrToStructure(pAddress, oClientAddres.[GetType]()), WTS_CLIENT_ADDRESS)
sIPAddress = oClientAddres.bAddress(2) & "." & oClientAddres.bAddress(3) & "." & oClientAddres.bAddress(4) & "." & oClientAddres.bAddress(5)
End If

'Get the User Name of the Terminal Services User
If WTSQuerySessionInformation(pServer, oSessionInfo.iSessionID, WTS_INFO_CLASS.WTSUserName, pAddress, iReturned) = True Then
sUserName = Marshal.PtrToStringAnsi(pAddress)
End If

'Get the Domain Name of the Terminal Services User
If WTSQuerySessionInformation(pServer, oSessionInfo.iSessionID, WTS_INFO_CLASS.WTSDomainName, pAddress, iReturned) = True Then
sDomain = Marshal.PtrToStringAnsi(pAddress)
End If

'Get the Display Information of the Terminal Services User
If WTSQuerySessionInformation(pServer, oSessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientDisplay, pAddress, iReturned) = True Then
oClientDisplay = CType(Marshal.PtrToStructure(pAddress, oClientDisplay.[GetType]()), WTS_CLIENT_DISPLAY)
End If

'Get the Application Directory of the Terminal Services User
If WTSQuerySessionInformation(pServer, oSessionInfo.iSessionID, WTS_INFO_CLASS.WTSClientDirectory, pAddress, iReturned) = True Then
sClientApplicationDirectory = Marshal.PtrToStringAnsi(pAddress)
End If

'test
If WTSQuerySessionInformation(pServer, oSessionInfo.iSessionID, WTS_INFO_CLASS.WTSIncomingBytes, pAddress, iReturned) = True Then
inBytes = Marshal.PtrToStringAuto(pAddress)
MessageBox.Show("In bytes" & inBytes)
Else
errorMessage = New Win32Exception(Marshal.GetLastWin32Error()).Message
End If

If WTSQuerySessionInformation(pServer, oSessionInfo.iSessionID, WTS_INFO_CLASS.WTSOutgoingBytes, pAddress, iReturned) = True Then
outBytes = Marshal.PtrToStringAuto(pAddress)
MessageBox.Show("Out Bytes" & outBytes)
Else
errorMessage = New Win32Exception(Marshal.GetLastWin32Error()).Message
End If

If WTSQuerySessionInformation(pServer, oSessionInfo.iSessionID, WTS_INFO_CLASS.WTSIncomingFrames, pAddress, iReturned) = True Then
inFrames = Marshal.PtrToStringAuto(pAddress)
MessageBox.Show("In Frames " & inFrames & Environment.NewLine & errorMessage)
Else
errorMessage = New Win32Exception(Marshal.GetLastWin32Error()).Message
End If

If WTSQuerySessionInformation(pServer, oSessionInfo.iSessionID, WTS_INFO_CLASS.WTSOutgoingFrames, pAddress, iReturned) = True Then
outFra

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900