Jump to content

Recommended Posts

..was looking for UserName from SessionID so I put this together

#include <Debug.au3> ; for _DebugArrayDisplay()

; all you can get from _WTSQuerySessionInformation()
Global $i = _WTSQuerySessionInformation(-1, 4) ; current user's SessionId
Global $__a_WTS_INFO_CLASS = StringSplit("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,WTSSessionInfoEx,WTSConfigInfo,WTSValidationInfo,WTSSessionAddressV4,WTSIsRemoteSession", ",", 2)
For $n = 0 To UBound($__a_WTS_INFO_CLASS) -1
    ConsoleWrite($n & @TAB & StringLeft($__a_WTS_INFO_CLASS[$n] & ' ________________', 24) & " " & _WTSQuerySessionInformation($i, $n, 1) & @CRLF)
Next

Global $a = ListUserSessions()
_DebugArrayDisplay($a, "ListUserSessions()")

Func ListUserSessions() ; mod. of https://www.autoitscript.com/forum/topic/139774-dllcall-and-returned-pointers/?do=findComment&comment=980850
    Local $_Self_SessionId = _WTSQuerySessionInformation(-1, 4) ; -1 = current user ; 4 = WTSSessionId
    Local Enum $e_IsSelf_SessionId, $e_SessionName, $e_UserName, $e_SessionId, $e_StateName, $e_StateInt, $e_ClientName, $e_ClientIp, $e_Domain, $e_UBound
    Local Const $tagWTS_SESSION_INFO = 'dword SessionId;ptr WinStationName;uint State'
    Local $aResult = DllCall('wtsapi32.dll', 'int', 'WTSEnumerateSessionsW', 'ptr', 0, 'dword', 0, 'dword', 1, 'ptr*', 0, 'dword*', 0)
    If @error Or $aResult[0] = 0 Then Return SetError(1, 0, "") ; https://docs.microsoft.com/en-us/windows/desktop/api/wtsapi32/ne-wtsapi32-_wts_connectstate_class
    Local $aConnectionState = StringSplit("Active,Connected,ConnectQuery,Shadow,Disconnected,Idle,Listen,Reset,Down,Init", ",", 2)
    Local $tInfo, $Offset = 0, $c = 0, $aReturn[$aResult[5] + 1][$e_UBound] ; $e_UBound is the last enumerator, just to determine the size of the array
    $aReturn[0][$e_SessionId] = "ID"
    $aReturn[0][$e_SessionName] = "SessionName"
    $aReturn[0][$e_StateInt] = "StateInt"
    $aReturn[0][$e_StateName] = "State"
    $aReturn[0][$e_UserName] = "UserName"
    $aReturn[0][$e_ClientName] = "ClientName"
    $aReturn[0][$e_ClientIp] = "ClientIp"
    $aReturn[0][$e_Domain] = "Domain"
    For $i = 1 To $aResult[5]
        $tInfo = DllStructCreate($tagWTS_SESSION_INFO, $aResult[4] + $Offset)
        $Offset += DllStructGetSize($tInfo)
        $c += 1
        $aReturn[$c][$e_SessionId] = DllStructGetData($tInfo, 'SessionId')
        $aReturn[$c][$e_SessionName] = DllStructGetData(DllStructCreate('wchar[1024]', DllStructGetData($tInfo, 'WinStationName')), 1)
        $aReturn[$c][$e_StateInt] = DllStructGetData($tInfo, 'State')
        If UBound($aConnectionState) > $aReturn[$c][$e_StateInt] Then $aReturn[$c][$e_StateName] = $aConnectionState[$aReturn[$c][$e_StateInt]]
        $aReturn[$c][$e_UserName] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 5) ; WTSUserName
        $aReturn[$c][$e_ClientName] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 10) ; WTSClientName
        $aReturn[$c][$e_ClientIp] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 14) ; WTSClientAddress
        $aReturn[$c][$e_Domain] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 7) ; WTSDomainName
        $aReturn[0][$e_IsSelf_SessionId] = $c
        If $_Self_SessionId = $aReturn[$c][$e_SessionId] Then
            $aReturn[$c][$e_IsSelf_SessionId] = 1
        Else
            $aReturn[$c][$e_IsSelf_SessionId] = 0
        EndIf
    Next
    DllCall('wtsapi32.dll', 'none', 'WTSFreeMemory', 'ptr', $aResult[4])
    Return $aReturn
EndFunc   ;==>ListUserSessions

Func _WTSQuerySessionInformation($SessionId, $WTSInfoClass = 10, $iReturnAsIs = 0) ; mod. of https://www.autoitscript.com/forum/topic/134679-get-hostname-of-the-client-connected-to-the-terminalserver-session/
    Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSQuerySessionInformation", "Ptr", 0, "int", $SessionId, "int", $WTSInfoClass, "ptr*", 0, "dword*", 0)
    If @error Or $aResult[0] = 0 Then Return SetError(1, 0, "")
    Local $ip = DllStructGetData(DllStructCreate("byte[" & $aResult[5] & "]", $aResult[4]), 1)
    DllCall("Wtsapi32.dll", "int", "WTSFreeMemory", "ptr", $aResult[4])
    If $iReturnAsIs Then Return $ip
    Switch $WTSInfoClass ; https://docs.microsoft.com/en-us/windows/desktop/api/wtsapi32/ns-wtsapi32-_wts_client_address
        Case 4 ; WTSSessionId
            Return Int('0x' & StringTrimRight(StringReverse($ip), 3))

        Case 14 ; WTSClientAddress
            If Not (Int(StringLeft($ip, 4)) = 2) Then ; IPv4
                $ip = ""
            Else
                $ip = Dec(StringMid($ip, 15, 2)) & '.' & Dec(StringMid($ip, 17, 2)) & '.' & Dec(StringMid($ip, 19, 2)) & '.' & Dec(StringMid($ip, 21, 2))
            EndIf

    EndSwitch
    Return StringReplace(BinaryToString($ip), Chr(0), "")
EndFunc   ;==>_GetWTSClientName

 

Edited by argumentum
better code

Share this post


Link to post
Share on other sites

I just wanted to get the current users SessionID so I pulled just a little out of what you posted.

I also added the 29 to the function to verify that the session you specified is a Remote session or not.

 

The Microsoft link to figure out the WTSInfoClass values was broken but I found them and figured i'd post here in case someone else wants it.

 

;Options for the $SessionID
    Global Static $WTS_CURRENT_SESSION = -1

;Options for the $WTSInfoClass
    Global Static $WTSInitialProgram = 0
    Global Static $WTSApplicationName = 1
    Global Static $WTSWorkingDirectory = 2
    Global Static $WTSOEMId = 3
    Global Static $WTSSessionId = 4
    Global Static $WTSUserName = 5
    Global Static $WTSWinStationName = 6
    Global Static $WTSDomainName = 7
    Global Static $WTSConnectState = 8
    Global Static $WTSClientBuildNumber = 9
    Global Static $WTSClientName = 10
    Global Static $WTSClientDirectory = 11
    Global Static $WTSClientProductId = 12
    Global Static $WTSClientHardwareId = 13
    Global Static $WTSClientAddress = 14
    Global Static $WTSClientDisplay = 15
    Global Static $WTSClientProtocolType = 16
    Global Static $WTSIdleTime = 17
    Global Static $WTSLogonTime = 18
    Global Static $WTSIncomingBytes = 19
    Global Static $WTSOutgoingBytes = 20
    Global Static $WTSIncomingFrames = 21
    Global Static $WTSOutgoingFrames = 22
    Global Static $WTSClientInfo = 23
    Global Static $WTSSessionInfo = 24
    Global Static $WTSSessionInfoEx = 25
    Global Static $WTSConfigInfo = 26
    Global Static $WTSValidationInfo = 27
    Global Static $WTSSessionAddressV4 = 28
    Global Static $WTSIsRemoteSession = 29


$id = _WTSQuerySessionInformation($WTS_CURRENT_SESSION, $WTSSessionId) ;Get the current users SessionId
ConsoleWrite("My Session ID:  " & $id & @CRLF)

$Username = _WTSQuerySessionInformation($WTS_CURRENT_SESSION, $WTSUserName) ;Get the username for the specified session
ConsoleWrite("My Username:  " & $Username & @CRLF)

$Username = _WTSQuerySessionInformation($WTS_CURRENT_SESSION, $WTSIsRemoteSession) ;Can verify that the session is Remote
ConsoleWrite("IsRemote?  " & $Username & @CRLF)



Func _WTSQuerySessionInformation($SessionId = -1, $WTSInfoClass = 10, $iReturnAsIs = 0) ; mod. of https://www.autoitscript.com/forum/topic/134679-get-hostname-of-the-client-connected-to-the-terminalserver-session/
    Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSQuerySessionInformation", "Ptr", 0, "int", $SessionId, "int", $WTSInfoClass, "ptr*", 0, "dword*", 0)
    If @error Or $aResult[0] = 0 Then Return SetError(1, 0, "")
    Local $ip = DllStructGetData(DllStructCreate("byte[" & $aResult[5] & "]", $aResult[4]), 1)
    DllCall("Wtsapi32.dll", "int", "WTSFreeMemory", "ptr", $aResult[4])
    If $iReturnAsIs Then Return $ip
    Switch $WTSInfoClass
        Case 4 ; We want the WTSSessionId
            Return Int('0x' & StringTrimRight(StringReverse($ip), 3))

        Case 29 ; 1 = this is a remote session, 0 means its a physical session  $WTSIsRemoteSession
            Return Int('0x' & StringTrimRight(StringReverse($ip), 3))

        Case 14 ; We want the WTSClientAddress
            If Not (Int(StringLeft($ip, 4)) = 2) Then ; IPv4
                $ip = ""
            Else
                $ip = Dec(StringMid($ip, 15, 2)) & '.' & Dec(StringMid($ip, 17, 2)) & '.' & Dec(StringMid($ip, 19, 2)) & '.' & Dec(StringMid($ip, 21, 2))
            EndIf

    EndSwitch
    Return StringReplace(BinaryToString($ip), Chr(0), "")
EndFunc   ;==>_GetWTSClientName

 


hmm... I guess I have to have a signature...

Share this post


Link to post
Share on other sites

@argumentum

So I will be the first to admit I don't understand dll structure and converting back to readable data.  I have been toying with your listusersessions array trying to understand it and get it to pull the data I want.   But I need two additional columns of info.  WTSLogonTime & WTSIdleTime.  Here are the changes I have made to your base code but I don't think I am converting things correctly.  If you could help me understand what I am doing wrong and where I can find the different structures for each property.  I believe I want to create an array that list all the properties for all sessions.   I made no changes to the function  _WTSQuerySessionInformation

 

Func ListUserSessions() ; mod. of https://www.autoitscript.com/forum/topic/139774-dllcall-and-returned-pointers/?do=findComment&comment=980850
    Local $_Self_SessionId = _WTSQuerySessionInformation(-1, 4) ; -1 = current user ; 4 = WTSSessionId
    Local Enum $e_IsSelf_SessionId, $e_SessionName, $e_UserName, $e_SessionId, $e_StateName, $e_StateInt, $e_ClientName, $e_ClientIp, $e_Domain, $e_IdleTime, $e_LogonTime, $e_UBound
    Local Const $tagWTS_SESSION_INFO = 'dword SessionId;ptr WinStationName;uint State'
    Local $aResult = DllCall('wtsapi32.dll', 'int', 'WTSEnumerateSessionsW', 'ptr', 0, 'dword', 0, 'dword', 1, 'ptr*', 0, 'dword*', 0)
    If @error Or $aResult[0] = 0 Then Return SetError(1, 0, "") ; https://docs.microsoft.com/en-us/windows/desktop/api/wtsapi32/ne-wtsapi32-_wts_connectstate_class
    Local $aConnectionState = StringSplit("Active,Connected,ConnectQuery,Shadow,Disconnected,Idle,Listen,Reset,Down,Init", ",", 2)
    Local $tInfo, $Offset = 0, $c = 0, $aReturn[$aResult[5] + 1][$e_UBound] ; $e_UBound is the last enumerator, just to determine the size of the array
    $aReturn[0][$e_SessionId] = "ID"
    $aReturn[0][$e_SessionName] = "SessionName"
    $aReturn[0][$e_StateInt] = "StateInt"
    $aReturn[0][$e_StateName] = "State"
    $aReturn[0][$e_UserName] = "UserName"
    $aReturn[0][$e_ClientName] = "ClientName"
    $aReturn[0][$e_ClientIp] = "ClientIp"
    $aReturn[0][$e_Domain] = "Domain"
    $aReturn[0][$e_IdleTime] = "IdleTime"
    $aReturn[0][$e_LogonTime] = "LogonTime"
    For $i = 1 To $aResult[5]
        $tInfo = DllStructCreate($tagWTS_SESSION_INFO, $aResult[4] + $Offset)
        $Offset += DllStructGetSize($tInfo)
        $c += 1
        $aReturn[$c][$e_SessionId] = DllStructGetData($tInfo, 'SessionId')
        $aReturn[$c][$e_SessionName] = DllStructGetData(DllStructCreate('wchar[1024]', DllStructGetData($tInfo, 'WinStationName')), 1)
        $aReturn[$c][$e_StateInt] = DllStructGetData($tInfo, 'State')
        If UBound($aConnectionState) > $aReturn[$c][$e_StateInt] Then $aReturn[$c][$e_StateName] = $aConnectionState[$aReturn[$c][$e_StateInt]]
        $aReturn[$c][$e_UserName] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 5) ; WTSUserName
        $aReturn[$c][$e_ClientName] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 10) ; WTSClientName
        $aReturn[$c][$e_ClientIp] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 14) ; WTSClientAddress
        $aReturn[$c][$e_Domain] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 7) ; WTSDomainName
        $aReturn[$c][$e_IdleTime] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 17) ; WTSIdleTime
        $aReturn[$c][$e_LogonTime] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 18) ; WTSLogonTime
        $aReturn[0][$e_IsSelf_SessionId] = $c
        If $_Self_SessionId = $aReturn[$c][$e_SessionId] Then
            $aReturn[$c][$e_IsSelf_SessionId] = 1
        Else
            $aReturn[$c][$e_IsSelf_SessionId] = 0
        EndIf
    Next
    DllCall('wtsapi32.dll', 'none', 'WTSFreeMemory', 'ptr', $aResult[4])
    Return $aReturn
EndFunc   ;==>ListUserSessions

 

Share this post


Link to post
Share on other sites
9 hours ago, Nhardel said:

Bump

Hey @Bump, to tell the truth, I did not code it. The links to the original code should be as comments in the code. I modified it to fit my needs after a long hours of trance like state.
I've got lots of unrelated work to do and can't afford the getting into the request right now, as I too suck at all these DLL stuff.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By RestrictedUser
      Hi AutoIt scriptwriters! 
      In some of windows operating systems, i saw that "Administrator" and "Guest" username in different languages are "Administradore" and "Gast" and etc. 
      How to make a simple script to find Administrator and Guest username in different language in these systems?
    • By bouzzi
      Hi guys,
      I'm trying to make a script that could tell me, from a username list file,  if the username is active, inactive or not existant  in a multi-domain Active Directory....
      I found a few scripts giving me hints but I found nothing to help me to accomplish this task...
      Do you have any ideas !
      Thanks
      Bouzzi!
       
    • By Kevin Finnegan
      Hi all,
      I'm currently writing a backup script to automate the process of storing and compressing data for any member leaving the firm I work at. Ideally I would like to pull the user's display name or full name, for instance, a WMI query selecting FullName WHERE Win32_NetworkLoginProfile Name equals "Domain\kefinnegan" would bring back "Kevin Finnegan" or whatever naming convention your company uses.
      Although this solution seems ideal as long as you log in as a user with privileged access, it won't work if the domain user you wish to backup has been purged from the Active Directory system entirely as the WMIService seems to query it in some shape or form (thousands of members in our firm, need to trim the fat every now and then). I was wondering if it's possible to query an API, service or possibly even scan registry entries stored on the leaver's machine while logged in as the local administrator (can run the script with privileged domain credentials if needs be) that could give me a domain user's full name, who logged onto this machine, without the use of Active Directory?
    • By hhsecond
      Hi folks,
      I am struggling to read time from a remote machine. By initial probing i could find it is possible by WMI object and connectserver (if we need to user password, yes here i need to use another username and password)
      Please help me to sort this out. Any suggestions would be appreciated. 
    • By 0_00_0
      So I've been looking everywhere for an answer to this but I haven't managed to get anything to work. Below is the basic function to set a proxy for IE through the registry. Many say that I can simply write a proxy in the format "user:pass@server:port" to ProxyServer but that hasn't worked for me. I have also tried other suggestions such as creating a ProxyUser / ProxyPass key and writing credentials to those keys but still no dice.
       
      Func _IESetProxy($tProxy) If $tProxy="0" Then RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings", "ProxyEnable", "REG_DWORD", 0) Else RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings", "ProxyServer", "REG_SZ", $tProxy) RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings", "ProxyEnable", "REG_DWORD", 1) EndIf EndFunc     I believe this article from Microsoft may have something to do with it? http://support.microsoft.com/kb/834489/EN-US   So I tried this (with 0 and 1 values): RegWrite("HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE") RegWrite("HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE", "iexplore.exe", "REG_DWORD", 0) RegWrite("HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE", "explorer.exe", "REG_DWORD", 0)   and still no luck!   Please! I desperately need help for this! Thanks a million in advance!  
×
×
  • Create New...