i´m not sure how WMI will work on remote PC ...
i do have a Email System where User get Update after Timeout.
so i can identify which User is Online ... but not which Process User is running
Code: Select all | Expand
// DEFINES FOR GetTSInfo
#define WTS_CURRENT_SERVER_HANDLE 0
#define WTS_CURRENT_SESSION -1
#define SM_REMOTESESSION 0x1000
#define PROCESS_QUERY_INFORMATION 0x400
#define PROCESS_VM_READ 0x10
//Public Enum WTS_INFO_CLASS
#define WTSInitialProgram 0
#define WTSApplicationName 1
#define WTSWorkingDirectory 2
#define WTSOEMId 3
#define WTSSessionId 4
#define WTSUserName 5
#define WTSWinStationName 6
#define WTSDomainName 7
#define WTSConnectState 8
#define WTSClientBuildNumber 9
#define WTSClientName 10
#define WTSClientDirectory 11
#define WTSClientProductId 12
#define WTSClientHardwareId 13
#define WTSClientAddress 14
#define WTSClientDisplay 15
#define WTSClientProtocolType 16
// GetTSInfo
****************************************************************************
*********************
FUNCTION GetTSInfo()
LOCAL cTSInfo := ""
LOCAL cNewLine := (CHR(13)+CHR(10))
LOCAL Success
LOCAL pBuffer := 0
LOCAL BytesReturned := 0
LOCAL nDll
LOCAL nSessionID := 0
LOCAL xWTSInitialProgram := SPACE(100)+CHR(0)
LOCAL xWTSApplicationName := ""+CHR(0)
LOCAL xWTSWorkingDirectory := ""+CHR(0)
LOCAL xWTSOEMId := 0
LOCAL xWTSSessionId := 0
LOCAL xWTSUserName := SPACE(20)+CHR(0)
LOCAL xWTSWinStationName := ""+CHR(0)
LOCAL xWTSDomainName := ""+CHR(0)
LOCAL xWTSConnectState := 0
LOCAL xWTSClientBuildNumber := 0
LOCAL xWTSClientName := ""+CHR(0)
LOCAL xWTSClientDirectory := ""+CHR(0)
LOCAL xWTSClientProductId := 0
LOCAL xWTSClientHardwareId := 0
LOCAL xWTSClientAddress
LOCAL xWTSClientDisplay
LOCAL xWTSClientProtocolType := 0
LOCAL a_WTS_CLIENT_DISPLAY
LOCAL a_WTS_CLIENT_ADDRESS
LOCAL cStationName := ""
LOCAL cAddressStr := "", oSocket
/***************************************************
typedef struct _WTS_CLIENT_ADDRESS {
DWORD AddressFamily;
BYTE Address[20];
} WTS_CLIENT_ADDRESS, *PWTS_CLIENT_ADDRESS;
***************************************************/
a_WTS_CLIENT_ADDRESS := BaInit(2)
BaStruct(a_WTS_CLIENT_ADDRESS, 0)
BaStruct(a_WTS_CLIENT_ADDRESS, SPACE(20))
xWTSClientAddress := BaAccess(a_WTS_CLIENT_ADDRESS)
/***************************************************
typedef struct _WTS_CLIENT_DISPLAY {
DWORD HorizontalResolution;
DWORD VerticalResolution;
DWORD ColorDepth;
} WTS_CLIENT_DISPLAY, *PWTS_CLIENT_DISPLAY;
***************************************************/
a_WTS_CLIENT_DISPLAY := BaInit(3)
BaStruct(a_WTS_CLIENT_DISPLAY, 0)
BaStruct(a_WTS_CLIENT_DISPLAY, 0)
BaStruct(a_WTS_CLIENT_DISPLAY, 0)
xWTSClientDisplay := BaAccess(a_WTS_CLIENT_DISPLAY)
nDll := DllLoad("WTSAPI32.DLL")
IF nDll != 0
// Server Name
cTSInfo += "Server Name|"+sy_netname+cNewLine
// WTSInitialProgram -- not working
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSInitialProgram , @pBuffer, @BytesReturned)
IF Success == 1
xWTSInitialProgram := SPACE(BytesReturned)+CHR(0)
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSInitialProgram, @pBuffer, BytesReturned)
xWTSInitialProgram := TruncateNull(xWTSInitialProgram)
cTSInfo += "Initial Program|"+xWTSInitialProgram+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSApplicationName -- works
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSApplicationName , @pBuffer, @BytesReturned)
IF Success == 1
xWTSApplicationName := SPACE(BytesReturned)+CHR(0)
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSApplicationName, pBuffer, BytesReturned)
xWTSApplicationName := TruncateNull(xWTSApplicationName)
cTSInfo += "Application Name|"+xWTSApplicationName+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSWorkingDirectory -- works
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSWorkingDirectory , @pBuffer, @BytesReturned)
IF Success == 1
xWTSWorkingDirectory := SPACE(BytesReturned)+CHR(0)
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSWorkingDirectory, pBuffer, BytesReturned)
xWTSWorkingDirectory := TruncateNull(xWTSWorkingDirectory)
cTSInfo += "Working Directory|"+xWTSWorkingDirectory+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSSessionId - WORKS
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSSessionId , @pBuffer, @BytesReturned)
IF Success == 1
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSSessionId, pBuffer, BytesReturned)
sy_sessionid := xWTSSessionId
cTSInfo += "Session ID|"+ALLTRIM(TOSTRVAL(xWTSSessionId))+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSUserName -- works but returns nil?
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName , @pBuffer, @BytesReturned)
IF Success == 1
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSUserName, pBuffer, BytesReturned)
xWTSUserName := TruncateNull(xWTSUserName)
cTSInfo += "User Name|"+xWTSUserName+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSWinStationName -- not working
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSWinStationName , @pBuffer, @BytesReturned)
IF Success == 1
xWTSWinStationName := SPACE(BytesReturned)+CHR(0)
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSWinStationName, pBuffer, BytesReturned)
xWTSWinStationName := TruncateNull(xWTSWinStationName)
cTSInfo += "Win Station Name|"+xWTSWinStationName+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSDomainName -- not working
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSDomainName , @pBuffer, @BytesReturned)
IF Success == 1
xWTSDomainName := SPACE(BytesReturned)+CHR(0)
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSDomainName, pBuffer, BytesReturned)
xWTSDomainName := TruncateNull(xWTSDomainName)
cTSInfo += "Domain Name|"+xWTSDomainName+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSConnectState -- works
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSConnectState , @pBuffer, @BytesReturned)
IF Success == 1
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSConnectState, pBuffer, BytesReturned)
cTSInfo += "ConnectState|"+ALLTRIM(TOSTRVAL(xWTSConnectState))+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSClientBuildNumber -- works
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientBuildNumber , @pBuffer, @BytesReturned)
IF Success == 1
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSClientBuildNumber, pBuffer, BytesReturned)
cTSInfo += "Client BuildNumber|"+ALLTRIM(TOSTRVAL(xWTSClientBuildNumber))+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSClientName -- not working, ugh.
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientName , @pBuffer, @BytesReturned)
IF Success == 1
xWTSClientName := SPACE(BytesReturned)+CHR(0)
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSClientName, pBuffer, BytesReturned)
xWTSClientName := TruncateNull(xWTSClientName)
cTSInfo += "Client Name|"+xWTSClientName+cNewLine
IF sy_sessionid == 0
cStationName := sy_netname
ELSE
cStationName := xWTSClientName
ENDIF
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSClientDirectory -- not working either
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientDirectory , @pBuffer, @BytesReturned)
IF Success == 1
xWTSClientDirectory := SPACE(BytesReturned)+CHR(0)
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSClientDirectory, pBuffer, BytesReturned)
xWTSClientDirectory := TruncateNull(xWTSClientDirectory)
cTSInfo += "Client Directory|"+xWTSClientDirectory+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSClientProductId -- works
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientProductId , @pBuffer, @BytesReturned)
IF Success == 1
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSClientProductId, pBuffer, BytesReturned)
cTSInfo += "Client ProductId|"+ALLTRIM(TOSTRVAL(xWTSClientProductId))+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSClientHardwareId -- works
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientHardwareId , @pBuffer, @BytesReturned)
IF Success == 1
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSClientHardwareId, pBuffer, BytesReturned)
cTSInfo += "Client HardwareId|"+ALLTRIM(TOSTRVAL(xWTSClientHardwareId))+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSClientAddress -- works, need to figure out address format though
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientAddress , @pBuffer, @BytesReturned)
IF Success == 1
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSClientAddress, pBuffer, BytesReturned)
cTSInfo += "AddressFamily|"+ALLTRIM(TOSTRVAL(BaExtract(a_WTS_CLIENT_ADDRESS,xWTSClientAddress)))+cNewLine
cAddressStr := BaExtract(a_WTS_CLIENT_ADDRESS)
cTSInfo += "Len|"+FSTR(LEN(cAddressStr))+cNewLine
oSocket := xbSocket():New(AF_INET, SOCK_STREAM, IPPROTO_IP)
cTSInfo +="Address|"+oSocket:InetNtoA(Bin2U(RIGHT(cAddressStr,18)))+cNewLine
oSocket:Destroy()
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSClientDisplay -- works
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientDisplay , @pBuffer, @BytesReturned)
IF Success == 1
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSClientDisplay, pBuffer, BytesReturned)
cTSInfo += "HorizontalRes|"+ALLTRIM(TOSTRVAL(BaExtract(a_WTS_CLIENT_DISPLAY,xWTSClientDisplay)))+cNewLine
cTSInfo += "VerticalRes|"+ALLTRIM(TOSTRVAL(BaExtract(a_WTS_CLIENT_DISPLAY)))+cNewLine
cTSInfo += "ColorDepth|"+ALLTRIM(TOSTRVAL(BaExtract(a_WTS_CLIENT_DISPLAY)))+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
// WTSClientProtocolType -- works
Success := DLLCALL(nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientProtocolType, @pBuffer, @BytesReturned)
IF Success == 1
DLLCALL("kernel32.dll", DLL_STDCALL, "RtlMoveMemory", @xWTSClientProtocolType, pBuffer, BytesReturned)
cTSInfo += "Client ProtocolType|"+ALLTRIM(TOSTRVAL(xWTSClientProtocolType))+cNewLine
DLLCALL(nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer)
ENDIF
ELSE
PopMess("no wtsapi32.dll")
ENDIF
RETURN ({cStationName,cTSInfo})
// GetTSInfo
Code: Select all | Expand
#include "Appevent.ch"
#include "Common.ch"
#include "Xbp.ch"
#include "dll.ch"
#include "wts.ch"
#include "c:\ot4xb\ot4xb.ch"
***************************
CLASS WTSsessionInformation
***************************
PROTECTED:
VAR _aWTSSessionInformation
EXPORTED
VAR lLoadClientDirectory
VAR lLoadWorkingDirectory
VAR lIsRemoteSession
INLINE METHOD init
******************
::lLoadClientDirectory := .F.
::lLoadWorkingDirectory:= .F.
RETURN self
INLINE METHOD create
********************
::lIsRemoteSession:= ( GetSystemMetrics( SM_REMOTESESSION ) > 0 )
RETURN self
INLINE METHOD destroy
*********************
::_aWTSSessionInformation:= ::lLoadClientDirectory:= ::lLoadWorkingDirectory:= ::lIsRemoteSession:= nil
RETURN self
*****************************
INLINE METHOD loadInformation
*****************************
LOCAL aDatos, nDll
LOCAL pBuffer := 0
LOCAL BytesReturned:= 0
IF ::lIsRemoteSession
nDll:= DllLoad("WTSAPI32.DLL")
IF nDll != 0
::_aWTSSessionInformation:= Array( WTSClientProtocolType + 1 )
IF DLLCALL( nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, ;
WTS_CURRENT_SESSION, WTSSessionId, @pBuffer, @BytesReturned ) = 1
IF Valtype( ( aDatos:= PeekByte( pBuffer, 0, BytesReturned ) ) ) = 'A' .AND. Len( aDatos ) > 0
::_aWTSSessionInformation[ WTSSessionId + 1 ]:= Ltrim( Str( aDatos[ 1 ] ) )
ENDIF
DLLCALL( nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer )
ENDIF
IF DLLCALL( nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, ;
WTS_CURRENT_SESSION, WTSClientAddress, @pbuffer, @BytesReturned ) = 1
IF Valtype( ( aDatos:= PeekByte( pBuffer, 0, BytesReturned ) ) ) = 'A' .AND. Len( aDatos ) > 10
// cAddressFamily:= aDatos[ 1 ]
::_aWTSSessionInformation[ WTSClientAddress + 1 ]:= Ltrim( Str( aDatos[ 7 ] ) ) + '.' + Ltrim( Str( aDatos[ 8 ] ) )+ '.' + ;
Ltrim( Str( aDatos[ 9 ] ) ) + '.' + Ltrim( Str( aDatos[ 10 ] ) )
ENDIF
DLLCALL( nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer )
ENDIF
IF ::lLoadClientDirectory .AND. DLLCALL( nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, ;
WTS_CURRENT_SESSION, WTSClientDirectory, @pBuffer, @BytesReturned ) = 1
::_aWTSSessionInformation[ WTSClientDirectory + 1 ]:= Space( BytesReturned )
PeekStr( pBuffer, 0, @::_aWTSSessionInformation[ WTSClientDirectory + 1 ] )
DLLCALL( nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer )
ENDIF
IF ::lLoadWorkingDirectory .AND. DLLCALL( nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, ;
WTS_CURRENT_SESSION, WTSWorkingDirectory, @pBuffer, @BytesReturned ) = 1
::_aWTSSessionInformation[ WTSWorkingDirectory + 1 ]:= Space( BytesReturned )
PeekStr( pBuffer, 0, @::_aWTSSessionInformation[ WTSWorkingDirectory + 1 ] )
DLLCALL( nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer )
ENDIF
DllUnLoad( nDll )
ENDIF
ENDIF
RETURN self
INLINE METHOD clientAddress
***************************
IF ! ::lIsRemoteSession
RETURN ''
ELSEIF ::_aWTSSessionInformation = nil
::loadInformation()
ENDIF
RETURN ::_aWTSSessionInformation[ WTSClientAddress + 1 ]
INLINE METHOD sessionId
***********************
IF ! ::lIsRemoteSession
RETURN 0
ELSEIF ::_aWTSSessionInformation = nil
::loadInformation()
ENDIF
RETURN ::_aWTSSessionInformation[ WTSSessionId + 1 ]
INLINE METHOD clientDirectory
*****************************
IF ! ::lIsRemoteSession
RETURN ''
ELSEIF ::_aWTSSessionInformation = nil .OR. ! ::lLoadClientDirectory
::lLoadClientDirectory:= .T.
::loadInformation()
ENDIF
RETURN ::_aWTSSessionInformation[ WTSClientDirectory + 1 ]
INLINE METHOD currentSize
*************************
LOCAL aSize, nDll, aDatos
LOCAL pBuffer := 0
LOCAL BytesReturned:= 0
IF ::lIsRemoteSession .AND. ( nDll:= DllLoad("WTSAPI32.DLL") ) != 0
IF DLLCALL( nDll, DLL_STDCALL, "WTSQuerySessionInformationA", WTS_CURRENT_SERVER_HANDLE, ;
WTS_CURRENT_SESSION, WTSClientDisplay, @pBuffer, @BytesReturned ) = 1
IF Valtype( ( aDatos:= PeekByte( pBuffer, 0, BytesReturned ) ) ) = 'A' .AND. Len( aDatos ) > 0
aSize:= { Bin2u( Chr( aDatos[ 1 ] ) + Chr( aDatos[ 2 ] ) + Chr( aDatos[ 3 ] ) + Chr( aDatos[ 4 ] ) ), ;
Bin2u( Chr( aDatos[ 5 ] ) + Chr( aDatos[ 6 ] ) + Chr( aDatos[ 7 ] ) + Chr( aDatos[ 8 ] ) ) }
ENDIF
DLLCALL( nDll, DLL_STDCALL, "WTSFreeMemory", pBuffer )
ENDIF
DllUnLoad( nDll )
ENDIF
RETURN IIF( aSize = nil, AppDesktop():currentSize(), aSize )
ENDCLASS
STATIC DLLFUNCTION GetSystemMetrics( nIndex ) USING STDCALL FROM USER32.DLL