Re: [python-win32] Need a value from pywin32

2022-06-21 Thread Tim Roberts

On 6/21/22 13:39, Steven Manross wrote:


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.
...
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


No, 0 is the error return that means the name was not found.

You shouldn't need to use LoadLibrary and GetProcAddress.  ctypes does 
that for you automatically.


    winsta = ctypes.WinDLL('winsta.dll')

    winsta.WinStationQueryInformationW( 0, session_id, 8, 
ctypes.byref(Buf), BufLen, ctypes.byref(RtnLen))


If you have Visual Studio, you can try doing "link /dump /exports 
\windows\system32\winsta.dll" to make sure it has that entry point.


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

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


Re: [python-win32] Need a value from pywin32

2022-06-21 Thread Steven Manross
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: : 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 0x

HTH

Steven
-Original Message-
From: python-win32  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