I use some of Windows Terminal Services APIs in my app.
The is an API function which enumerates sessions on a terminal server.
It uses a pointer from another API function to know on which exactly server
to operate.
But whatever I do the function always get sessions on my local WinXP
machine, not the required server.
Can someone have a look?
TIA
Here is the code:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Private Structure WTS_SESSION_INFO
Dim SessionID As Int32 'DWORD integer
Dim pWinStationName As String ' integer LPTSTR - Pointer to a
null-terminated string containing the name of the WinStation for this
session
Dim State As WTS_CONNECTSTATE_CLASS
End Structure
Friend Structure strSessionsInfo
Dim SessionID As Integer
Dim StationName As String
Dim ConnectionState As String
End Structure
Private Enum WTS_CONNECTSTATE_CLASS
WTSActive
WTSConnected
WTSConnectQuery
WTSShadow
WTSDisconnected
WTSIdle
WTSListen
WTSReset
WTSDown
WTSInit
End Enum
<DllImport("wtsapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function WTSOpenServer(ByVal pServerName As String) As
IntPtr
End Function
<DllImport("wtsapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Sub WTSCloseServer(ByVal hServer As IntPtr)
End Sub
<DllImport("wtsapi32.dll")> _
Private Shared Sub WTSFreeMemory(ByVal pMemory As IntPtr)
End Sub
<DllImport("wtsapi32.dll", _
bestfitmapping:=True, _
CallingConvention:=CallingConvention.StdCall, _
CharSet:=CharSet.Auto, _
EntryPoint:="WTSEnumerateSessions", _
setlasterror:=True, _
ThrowOnUnmappableChar:=True)> _
Private Shared Function WTSEnumerateSessions( _
ByVal hServer As IntPtr, _
<MarshalAs(UnmanagedType.U4)> _
ByVal Reserved As Int32, _
<MarshalAs(UnmanagedType.U4)> _
ByVal Vesrion As Int32, _
ByRef ppSessionInfo As IntPtr, _
<MarshalAs(UnmanagedType.U4)> _
ByRef pCount As Int32) As Int32
End Function
Friend Function GetSessions(ByVal ServerName As String) As
strSessionsInfo()
Dim ptrOpenedServer As IntPtr
Dim RetVal As strSessionsInfo()
Try
ptrOpenedServer = WTSOpenServer(ServerName)
Dim FRetVal As Int32
Dim ppSessionInfo As IntPtr = IntPtr.Zero
Dim Count As Int32 = 0
Try
FRetVal = WTSEnumerateSessions(ptrOpenedServer, 0, 1,
ppSessionInfo, Count)
If FRetVal <> 0 Then
Dim sessionInfo() As WTS_SESSION_INFO = New
WTS_SESSION_INFO(Count) {}
Dim i As Integer
For i = 0 To Count - 1
sessionInfo(i) =
CType(Marshal.PtrToStructure(ppSessionInfo, GetType(WTS_SESSION_INFO)),
WTS_SESSION_INFO)
Next
WTSFreeMemory(ppSessionInfo)
Dim tmpArr(sessionInfo.GetUpperBound(0)) As
strSessionsInfo
For i = 0 To tmpArr.GetUpperBound(0)
tmpArr(i).SessionID = sessionInfo(i).SessionID
tmpArr(i).StationName =
sessionInfo(i).pWinStationName
tmpArr(i).ConnectionState =
GetConnectionState(sessionInfo(i).State)
Next
ReDim sessionInfo(-1)
RetVal = tmpArr
Else
Throw New ApplicationException("No data retruned")
End If
Catch ex As Exception
Throw New Exception(ex.Message & vbCrLf &
System.Runtime.InteropServices.Marshal.GetLastWin3 2Error)
End Try
Catch ex As Exception
Throw New Exception(ex.Message)
Exit Function
Finally
WTSCloseServer(ptrOpenedServer)
End Try
Return RetVal
End Function
Private Function GetConnectionState(ByVal State As
WTS_CONNECTSTATE_CLASS) As String
Dim RetVal As String
Select Case State
Case WTS_CONNECTSTATE_CLASS.WTSActive
RetVal = "Active"
Case WTS_CONNECTSTATE_CLASS.WTSConnected
RetVal = "Connected"
Case WTS_CONNECTSTATE_CLASS.WTSConnectQuery
RetVal = "Query"
Case WTS_CONNECTSTATE_CLASS.WTSDisconnected
RetVal = "Disconnected"
Case WTS_CONNECTSTATE_CLASS.WTSDown
RetVal = "Down"
Case WTS_CONNECTSTATE_CLASS.WTSIdle
RetVal = "Idle"
Case WTS_CONNECTSTATE_CLASS.WTSInit
RetVal = "Initializing."
Case WTS_CONNECTSTATE_CLASS.WTSListen
RetVal = "Listen"
Case WTS_CONNECTSTATE_CLASS.WTSReset
RetVal = "reset"
Case WTS_CONNECTSTATE_CLASS.WTSShadow
RetVal = "Shadowing"
Case Else
RetVal = "Unknown connect state"
End Select
Return RetVal
End Function