I was intrigued by this and I would like to get it to work, but I cannot...  I 
know I'm doing something wrong, but don't know what.  I will leave this for the 
archives, and maybe it will help someone else some day.

My guess is that the issue is the conversion of the winsta_handle to a 
ctypes.c_ulonglong() is generating an invalid handle ID or the GetProcAddress 
isn't finding the correct info using that handle.

I'm very new to C programming

'''
    Get Terminal Services Idle Time and other values from WINSTA.DLL for local 
server

    ----> THIS DOES NOT WORK!!!!!  <----
    ----> ONLY SENT AS STARTER CODE FOR SOMEONE TO FIGURE OUT WHAT I AM MISSING 
<----

    Microsoft Info:  
https://docs.microsoft.com/en-us/previous-versions/aa383827(v=vs.85)
    Google Thread: 
https://groups.google.com/g/microsoft.public.win32.programmer.kernel/c/xt2G599tJuQ?hl=en&pli=1#91fc4e79a5d6c495
'''
import ctypes

class WinStationInformation(ctypes.Structure):
    __fields__ = [
        ('ConnectState', ctypes.c_long),
        ('WinStationName', ctypes.wintypes.WCHAR),
        ('LogonId', ctypes.c_ulong),
        ('ConnectTime', ctypes.wintypes.LARGE_INTEGER),
        ('DisconnectTime', ctypes.wintypes.LARGE_INTEGER),
        ('LastInputTime', ctypes.wintypes.LARGE_INTEGER),
        ('LogonTime', ctypes.wintypes.LARGE_INTEGER),
        ('Status', ctypes.c_int()),
        ('Domain', ctypes.wintypes.WCHAR * (17 + 1)),
        ('UserName', ctypes.wintypes.WCHAR * (20 + 1)),
        ('CurrentTime', ctypes.wintypes.LARGE_INTEGER),
    ]

def get_wts_info(session_id):
    '''
        Get WTS Info
    '''
    # This only tries to work on the local server currently but I get an access 
violation running the WinStationQueryInformationW line

    Buf = ctypes.POINTER(WinStationInformation)()
    BufLen = 260

    hWinSta = ctypes.windll.LoadLibrary("WINSTA.DLL")
    if hWinSta:
        winsta_handle = hWinSta._handle
        print(f'winsta_handle = {winsta_handle}')
        QueryInfoHandle = 
ctypes.windll.kernel32.GetProcAddress(ctypes.c_ulonglong(winsta_handle), 
b"WinStationQueryInformationW")

        # This handle is 0...  possibly because of the numeric conversion from 
the winsta_handle to a ctypes.c_ulonglong  ???  unsure
        # I had to convert it because the handle was generating an error as a 
regular value:
        #  ArgumentError: argument 1: <class 'OverflowError'>: int too long to 
convert
        #
        print(f'QueryInfoHandle = {QueryInfoHandle}')  
        WinStationQueryInformationW = hWinSta._FuncPtr(QueryInfoHandle)

        RtnLen = ctypes.c_ulong()
        try:
            Result = WinStationQueryInformationW(0, session_id, 8, 
ctypes.byref(Buf), BufLen, ctypes.byref(RtnLen))
        except Exception as e:
            print(f'Excepted running WinStationQueryInformationW: {e}')
            return False

    print(f'Result = {Result}')
    return True

get_wts_info(11) 
# where 11 is a valid session id on the local RDP server as defined by:
#     Server Manager -> Remote Desktop Services -> Collections -> your 
Collection Name -> Connections
#        Right Click on the columns in Connections Tab and add "ID" to the list 
of columns

My output:
                               
winsta_handle = 140703764119552
QueryInfoHandle = 0
Excepted running WinStationQueryInformationW: exception: access violation 
writing 0x0000000000000000

HTH

Steven
-----Original Message-----
From: python-win32 <python-win32-bounces+steven=manross....@python.org> On 
Behalf Of Tim Roberts
Sent: Monday, June 20, 2022 10:06 AM
To: python-win32@python.org
Subject: Re: [python-win32] Need a value from pywin32

Craig R. Matthews wrote:
>
> I have a need to determine the "IDLE TIME" as provided by the Windows 
> Query program.
>
> Sample output:
> C:\>query user /server:CTX202201
>  USERNAME              SESSIONNAME        ID  STATE   IDLE TIME LOGON 
> TIME
>  administrator         rdp-tcp#67          2  Active       1:38
> 6/15/2022 10:48 AM
>
> I can't find the above "IDLE TIME" anywhere in pywin32 "Python for
> Win32 Extensions".
>
> I need this time value, and would rather keep all the code in python 
> without having to resort to something like subprocess to encapsulate 
> the Windows Query program.

This is part of Windows Terminal Services.  The API to fetch the idle time is 
undocumented and unsupported, but you can find the information here:

https://groups.google.com/g/microsoft.public.win32.programmer.kernel/c/xt2G599tJuQ?hl=en#91fc4e79a5d6c495

Because it is undocumented, it might be better to parse the output of "query 
user".

--
Tim Roberts, t...@probo.com
Providenza & Boekelheide, Inc.

_______________________________________________
python-win32 mailing list
python-win32@python.org
https://mail.python.org/mailman/listinfo/python-win32

Reply via email to