I've written a simple (test) script to list files in a selected directory. Not using FindFirstFile;
only native API.
When I execute the script and watch, Win32API monitor tells me STATUS_SUCCESS.
My File Information buffer is c_buffer(1024), not using a Unicode buffer to see the raw data.
So after call NtQueryDirectoryFile all is ok.
When I write c_buffer in raw mode to console to see the files in the directory, the output is not structured.
I created a FILE_DIRECTORY_INFORMATION structure but either it does not work Windows 7 X86 or there's a problem in my code.
My Question:
Please tell me which FILE_DIRECTORY_INFORMATION structure use on Windows 7 X86 or any variants
from ctypes import *
hFile = windll.kernel32.CreateFileW("C:\\a",0x80000000,0,0,3,0x02000000,0)
class Info(Union):
_fields_ = [('STATUS',c_long),
('Pointer',c_ulong),]
class io_stat(Structure):
_fields_ = [('Stat',Info),
('Information',c_ulong),]
class FILE_OBJECT(Structure):
_fields_ = [('Next',c_ulong),
('FileIndex',c_ulong),
('ctime',c_longlong),
('lat',c_longlong),
('wtime',c_longlong),
('ch',c_longlong),
('Endogfile',c_longlong),
('allo',c_longlong),
('Fileattr',c_ulong),
('Filenalen',c_ulong),
('Filename',c_wchar * 2),]
b = io_stat()
a = c_buffer(1024)
windll.ntdll.NtQueryDirectoryFile(hFile,0,0,0,byref(b),byref(a),sizeof(a), 1,0,None,0)
print(a.raw)
Not optimized.
NtQueryDirectoryFile should be called in a loop until it returns STATUS_NO_MORE_FILES. If either the returned status is STATUS_BUFFER_OVERFLOW or the status is successful (non-negative) with the status block Information as 0, then double the buffer size and try again. For each successful pass, copy the FILE_DIRECTORY_INFORMATION records out of the buffer. Each record has to be sized to include the FileName. You've reached the end when the Next field is 0.
The following example subclasses FILE_DIRECTORY_INFORMATION as a DirEntry class that has a listbuf class method to list the records in a queried buffer. It skips the "." and ".." entries. It uses this class in an ntlistdir function that lists the DirEntry records for a given directory via NtQueryDirectoryFile. It supports passing an open file descriptor as the path argument, which is like how os.listdir works on POSIX systems.
ctypes definitions
import os
import msvcrt
import ctypes
from ctypes import wintypes
ntdll = ctypes.WinDLL('ntdll')
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
def NtError(status):
err = ntdll.RtlNtStatusToDosError(status)
return ctypes.WinError(err)
NTSTATUS = wintypes.LONG
STATUS_BUFFER_OVERFLOW = NTSTATUS(0x80000005).value
STATUS_NO_MORE_FILES = NTSTATUS(0x80000006).value
STATUS_INFO_LENGTH_MISMATCH = NTSTATUS(0xC0000004).value
ERROR_DIRECTORY = 0x010B
INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value
GENERIC_READ = 0x80000000
FILE_SHARE_READ = 1
OPEN_EXISTING = 3
FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
FILE_ATTRIBUTE_DIRECTORY = 0x0010
FILE_INFORMATION_CLASS = wintypes.ULONG
FileDirectoryInformation = 1
FileBasicInformation = 4
LPSECURITY_ATTRIBUTES = wintypes.LPVOID
PIO_APC_ROUTINE = wintypes.LPVOID
ULONG_PTR = wintypes.WPARAM
class UNICODE_STRING(ctypes.Structure):
_fields_ = (('Length', wintypes.USHORT),
('MaximumLength', wintypes.USHORT),
('Buffer', wintypes.LPWSTR))
PUNICODE_STRING = ctypes.POINTER(UNICODE_STRING)
class IO_STATUS_BLOCK(ctypes.Structure):
class _STATUS(ctypes.Union):
_fields_ = (('Status', NTSTATUS),
('Pointer', wintypes.LPVOID))
_anonymous_ = '_Status',
_fields_ = (('_Status', _STATUS),
('Information', ULONG_PTR))
PIO_STATUS_BLOCK = ctypes.POINTER(IO_STATUS_BLOCK)
ntdll.NtQueryInformationFile.restype = NTSTATUS
ntdll.NtQueryInformationFile.argtypes = (
wintypes.HANDLE, # In FileHandle
PIO_STATUS_BLOCK, # Out IoStatusBlock
wintypes.LPVOID, # Out FileInformation
wintypes.ULONG, # In Length
FILE_INFORMATION_CLASS) # In FileInformationClass
ntdll.NtQueryDirectoryFile.restype = NTSTATUS
ntdll.NtQueryDirectoryFile.argtypes = (
wintypes.HANDLE, # In FileHandle
wintypes.HANDLE, # In_opt Event
PIO_APC_ROUTINE, # In_opt ApcRoutine
wintypes.LPVOID, # In_opt ApcContext
PIO_STATUS_BLOCK, # Out IoStatusBlock
wintypes.LPVOID, # Out FileInformation
wintypes.ULONG, # In Length
FILE_INFORMATION_CLASS, # In FileInformationClass
wintypes.BOOLEAN, # In ReturnSingleEntry
PUNICODE_STRING, # In_opt FileName
wintypes.BOOLEAN) # In RestartScan
kernel32.CreateFileW.restype = wintypes.HANDLE
kernel32.CreateFileW.argtypes = (
wintypes.LPCWSTR, # In lpFileName
wintypes.DWORD, # In dwDesiredAccess
wintypes.DWORD, # In dwShareMode
LPSECURITY_ATTRIBUTES, # In_opt lpSecurityAttributes
wintypes.DWORD, # In dwCreationDisposition
wintypes.DWORD, # In dwFlagsAndAttributes
wintypes.HANDLE) # In_opt hTemplateFile
class FILE_BASIC_INFORMATION(ctypes.Structure):
_fields_ = (('CreationTime', wintypes.LARGE_INTEGER),
('LastAccessTime', wintypes.LARGE_INTEGER),
('LastWriteTime', wintypes.LARGE_INTEGER),
('ChangeTime', wintypes.LARGE_INTEGER),
('FileAttributes', wintypes.ULONG))
class FILE_DIRECTORY_INFORMATION(ctypes.Structure):
_fields_ = (('_Next', wintypes.ULONG),
('FileIndex', wintypes.ULONG),
('CreationTime', wintypes.LARGE_INTEGER),
('LastAccessTime', wintypes.LARGE_INTEGER),
('LastWriteTime', wintypes.LARGE_INTEGER),
('ChangeTime', wintypes.LARGE_INTEGER),
('EndOfFile', wintypes.LARGE_INTEGER),
('AllocationSize', wintypes.LARGE_INTEGER),
('FileAttributes', wintypes.ULONG),
('FileNameLength', wintypes.ULONG),
('_FileName', wintypes.WCHAR * 1))
#property
def FileName(self):
addr = ctypes.addressof(self) + type(self)._FileName.offset
size = self.FileNameLength // ctypes.sizeof(wintypes.WCHAR)
return (wintypes.WCHAR * size).from_address(addr).value
DirEntry and ntlistdir
class DirEntry(FILE_DIRECTORY_INFORMATION):
def __repr__(self):
return '<{} {!r}>'.format(self.__class__.__name__, self.FileName)
#classmethod
def listbuf(cls, buf):
result = []
base_size = ctypes.sizeof(cls) - ctypes.sizeof(wintypes.WCHAR)
offset = 0
while True:
fdi = cls.from_buffer(buf, offset)
if fdi.FileNameLength and fdi.FileName not in ('.', '..'):
cfdi = cls()
size = base_size + fdi.FileNameLength
ctypes.resize(cfdi, size)
ctypes.memmove(ctypes.byref(cfdi), ctypes.byref(fdi), size)
result.append(cfdi)
if fdi._Next:
offset += fdi._Next
else:
break
return result
def isdir(path):
if not isinstance(path, int):
return os.path.isdir(path)
try:
hFile = msvcrt.get_osfhandle(path)
except IOError:
return False
iosb = IO_STATUS_BLOCK()
info = FILE_BASIC_INFORMATION()
status = ntdll.NtQueryInformationFile(hFile, ctypes.byref(iosb),
ctypes.byref(info), ctypes.sizeof(info),
FileBasicInformation)
return bool(status >= 0 and info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
def ntlistdir(path=None):
result = []
if path is None:
path = os.getcwd()
if isinstance(path, int):
close = False
fd = path
hFile = msvcrt.get_osfhandle(fd)
else:
close = True
hFile = kernel32.CreateFileW(path, GENERIC_READ, FILE_SHARE_READ,
None, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, None)
if hFile == INVALID_HANDLE_VALUE:
raise ctypes.WinError(ctypes.get_last_error())
fd = msvcrt.open_osfhandle(hFile, os.O_RDONLY)
try:
if not isdir(fd):
raise ctypes.WinError(ERROR_DIRECTORY)
iosb = IO_STATUS_BLOCK()
info = (ctypes.c_char * 4096)()
while True:
status = ntdll.NtQueryDirectoryFile(hFile, None, None, None,
ctypes.byref(iosb), ctypes.byref(info),
ctypes.sizeof(info), FileDirectoryInformation,
False, None, False)
if (status == STATUS_BUFFER_OVERFLOW or
iosb.Information == 0 and status >= 0):
info = (ctypes.c_char * (ctypes.sizeof(info) * 2))()
elif status == STATUS_NO_MORE_FILES:
break
elif status >= 0:
sublist = DirEntry.listbuf(info)
result.extend(sublist)
else:
raise NtError(status)
finally:
if close:
os.close(fd)
return result
Example
if __name__ == '__main__':
import sys
for entry in ntlistdir(sys.exec_prefix):
print(entry)
Output:
<DirEntry 'DLLs'>
<DirEntry 'include'>
<DirEntry 'Lib'>
<DirEntry 'libs'>
<DirEntry 'LICENSE.txt'>
<DirEntry 'NEWS.txt'>
<DirEntry 'python.exe'>
<DirEntry 'python.pdb'>
<DirEntry 'python3.dll'>
<DirEntry 'python36.dll'>
<DirEntry 'python36.pdb'>
<DirEntry 'python36_d.dll'>
<DirEntry 'python36_d.pdb'>
<DirEntry 'python3_d.dll'>
<DirEntry 'pythonw.exe'>
<DirEntry 'pythonw.pdb'>
<DirEntry 'pythonw_d.exe'>
<DirEntry 'pythonw_d.pdb'>
<DirEntry 'python_d.exe'>
<DirEntry 'python_d.pdb'>
<DirEntry 'Scripts'>
<DirEntry 'tcl'>
<DirEntry 'Tools'>
<DirEntry 'vcruntime140.dll'>
Related
I am using Python and trying to paste an already copied text from the clipboard automatically to an active textbox or anything that has the keyboard's focus. In other words, the program should paste automatically the copied data from clipboard once I click for example on a browser's address bar or any text editor or any text box.
Is this possible in python? is there any function for this? I have searched on the website but did not find any good solution.
If possible, a small demo would be appreciated.
Thank You.
You can use SendInput to grab the focus of the current window and input characters. Here is an implementation that should work for your purposes. It takes the contents of the clipboard and types them out if the object in focus collects such keyboard input.
import time
import string
import ctypes
import ctypes.wintypes
# part one: clipboard text retrieval
CF_UNICODETEXT = 13 # unicode text format; terminates with a linefeed
OpenClipboard = ctypes.windll.user32.OpenClipboard
OpenClipboard.argtypes = ctypes.wintypes.HWND,
OpenClipboard.restype = ctypes.wintypes.BOOL
GetClipboardData = ctypes.windll.user32.GetClipboardData
GetClipboardData.argtypes = ctypes.wintypes.UINT,
GetClipboardData.restype = ctypes.wintypes.HANDLE
GlobalLock = ctypes.windll.kernel32.GlobalLock
GlobalLock.argtypes = ctypes.wintypes.HGLOBAL,
GlobalLock.restype = ctypes.wintypes.LPVOID
GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
GlobalUnlock.argtypes = ctypes.wintypes.HGLOBAL,
GlobalUnlock.restype = ctypes.wintypes.BOOL
CloseClipboard = ctypes.windll.user32.CloseClipboard
CloseClipboard.argtypes = None
CloseClipboard.restype = ctypes.wintypes.BOOL
def get_clipboard_text():
text = ""
if OpenClipboard(None):
h_clip_mem = GetClipboardData(CF_UNICODETEXT)
text = ctypes.wstring_at(GlobalLock(h_clip_mem))
GlobalUnlock(h_clip_mem)
CloseClipboard()
return text
CB_TEXT = get_clipboard_text()
# part two: typing it into the focused element of a window
LONG = ctypes.c_long
DWORD = ctypes.c_ulong
ULONG_PTR = ctypes.POINTER(DWORD)
WORD = ctypes.c_ushort
VK_SHIFT = 0x10 # Shift key
# special keys
VK_OEM_1 = 0xBA
VK_OEM_PLUS = 0xBB
VK_OEM_COMMA = 0xBC
VK_OEM_MINUS = 0xBD
VK_OEM_PERIOD = 0xBE
VK_OEM_2 = 0xBF
VK_OEM_3 = 0xC0
VK_OEM_4 = 0xDB
VK_OEM_5 = 0xDC
VK_OEM_6 = 0xDD
VK_OEM_7 = 0xDE
KEYEVENTF_KEYUP = 0x0002 # Releases the key
INPUT_KEYBOARD = 1
UPPER = frozenset('~!##$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?')
LOWER = frozenset("`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./")
ORDER = string.ascii_letters + string.digits + ' \b\r\t'
ALTER = dict(zip('!##$%^&*()', '1234567890'))
OTHER = {
'`': VK_OEM_3, '~': VK_OEM_3, '-': VK_OEM_MINUS, '_': VK_OEM_MINUS,
'=': VK_OEM_PLUS, '+': VK_OEM_PLUS, '[': VK_OEM_4, '{': VK_OEM_4,
']': VK_OEM_6, '}': VK_OEM_6, '\\': VK_OEM_5, '|': VK_OEM_5,
';': VK_OEM_1, ':': VK_OEM_1, "'": VK_OEM_7, '"': VK_OEM_7,
',': VK_OEM_COMMA, '<': VK_OEM_COMMA, '.': VK_OEM_PERIOD,
'>': VK_OEM_PERIOD, '/': VK_OEM_2, '?': VK_OEM_2
}
class KEYBDINPUT(ctypes.Structure):
_fields_ = (
('wVk', WORD),
('wScan', WORD),
('dwFlags', DWORD),
('time', DWORD),
('dwExtraInfo', ULONG_PTR)
)
class INPUT(ctypes.Structure):
_fields_ = ('type', DWORD), ('ki', KEYBDINPUT), ('pad', ctypes.c_ubyte * 8)
def Input(structure):
return INPUT(INPUT_KEYBOARD, structure)
def KeyboardInput(code, flags):
return KEYBDINPUT(code, code, flags, 0, None)
def Keyboard(code, flags=0):
return Input(KeyboardInput(code, flags))
def SendInput(*inputs):
nInputs = len(inputs)
LPINPUT = INPUT * nInputs
pInputs = LPINPUT(*inputs)
cbSize = ctypes.c_int(ctypes.sizeof(INPUT))
return ctypes.windll.user32.SendInput(nInputs, pInputs, cbSize)
def stream(string):
mode = False
for character in string.replace('\r\n', '\r').replace('\n', '\r'):
if mode and character in LOWER or not mode and character in UPPER:
yield Keyboard(VK_SHIFT, mode and KEYEVENTF_KEYUP)
mode = not mode
character = ALTER.get(character, character)
if character in ORDER:
code = ord(character.upper())
elif character in OTHER:
code = OTHER[character]
else:
continue
raise ValueError('Undecoded')
yield Keyboard(code)
yield Keyboard(code, KEYEVENTF_KEYUP)
if mode:
yield Keyboard(VK_SHIFT, KEYEVENTF_KEYUP)
def send_clipboard():
for k in stream(CB_TEXT + '\r'):
SendInput(k)
def demo(wait=3):
time.sleep(wait)
send_clipboard()
if __name__ == '__main__':
demo()
I'm using Python3.5.1 serial module. When I open a port it fails with OS Error 22 (Windows Error 87) which signals failure to configure port, one of the arguments in OPEN system call were incorrect, or malformed.
My code uses loops over serial settings - that sends bad packets to the device until the device responds with a (readable) error message (so I know that my serial port is configured correctly). Yes, I should just know the device's settings but this isn't a prefect world.
import serial
import time
baud_rate = [50,75,110,134,150,200,300600,1200,1800,2400,4800,9600,19200,38400,57600,115200]
parity = [serial.PARITY_ODD,serial.PARITY_EVEN,serial.PARITY_NONE]
stop_bits = [serial.STOPBITS_TWO, serial.STOPBITS_ONE]
bytesize = [serial.SEVENBITS,serial.EIGHTBITS]
timeout = 5000
for b in baud_rate:
for p in parity:
for s in stop_bits:
for bs in bytesize:
ser = serial.Serial(port='COM3',baudrate=b,parity=p,stopbits=s,bytesize=bs)
try:
if ser.isOpen():
ser.write(b'TEST')
ser.reset_output_buffer()
time.sleep(1)
out = ser.read(3)
if out[0] == 64 and out[1] == 67 and out[2] == 32:
print("dumping settings")
print(ser.get_settings())
else:
ser.close()
except SerialException:
print("Serial Exception occured.")
pass
The problem happens under windows 7 x64 service pack 1. The python version is 3.5. The cmd.exe instance is ran as administrator.
I'm very sure COM3 exists when I run the script
import serial.tools.list_ports
ports = list(serial.tools.list_ports.comports())
for p in ports:
print(p)
I receive the output:
>python list_serial.py
COM3 - Prolific USB-to-Serial Comm Port (COM3)
So I believe the port URL/URI (idfk) is correct.
Full Error Text:
Traceback (most recent call last):
File "serial_reader.py", line 13, in <module>
ser = serial.Serial(port='COM3',baudrate=b,parity=p,stopbits=s,bytesize=bs)
File "C:\Users\FA1\AppData\Local\Programs\Python\Python35-32\lib\site-packages\serial\serialwin32.py", line 31, in __init__
SerialBase.__init__(self, *args, **kwargs)
File "C:\Users\FA1\AppData\Local\Programs\Python\Python35-32\lib\site-packages\serial\serialutil.py", line 180, in __init__
self.open()
File "C:\Users\FA1\AppData\Local\Programs\Python\Python35-32\lib\site-packages\serial\serialwin32.py", line 78, in open
self._reconfigure_port()
File "C:\Users\FA1\AppData\Local\Programs\Python\Python35-32\lib\site-packages\serial\serialwin32.py", line 220, in _reconfigure_port
raise SerialException("Cannot configure port, something went wrong. Original message: %r" % ctypes.WinError())
serial.serialutil.SerialException: Cannot configure port, something went wrong. Original message: OSError(22, 'The parameter is incorrect.', None, 87)
I've ensured the driver is properly installed, but I receive this error with 2 different serial converters. So I believe the issue isn't hardware or driver related.
You say that you "should just know the device's settings but this isn't a prefect world". But Windows does allow querying communications device properties via GetCommProperties. pySerial doesn't appear to support this, but you can use ctypes to call this function directly.
The following defines a get_comm_properties function to query the settable properties of a comm port. It accepts either an existing device handle (e.g. the _handle attribute of a pySerial port) or a DOS device name such as COM1 or WinAPI device name such as \\.\COM1.
import collections
import ctypes
from ctypes import wintypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
OPEN_EXISTING = 3
INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value
ERROR_FILE_NOT_FOUND = 0x0002
class COMMPROP(ctypes.Structure):
_fields_= (('wPacketLength', wintypes.WORD),
('wPacketVersion', wintypes.WORD),
('dwServiceMask', wintypes.DWORD),
('dwReserved1', wintypes.DWORD),
('dwMaxTxQueue', wintypes.DWORD),
('dwMaxRxQueue', wintypes.DWORD),
('dwMaxBaud', wintypes.DWORD),
('dwProvSubType', wintypes.DWORD),
('dwProvCapabilities', wintypes.DWORD),
('dwSettableParams', wintypes.DWORD),
('dwSettableBaud', wintypes.DWORD),
('wSettableData', wintypes.WORD),
('wSettableStopParity', wintypes.WORD),
('dwCurrentTxQueue', wintypes.DWORD),
('dwCurrentRxQueue', wintypes.DWORD),
('dwProvSpec1', wintypes.DWORD),
('dwProvSpec2', wintypes.DWORD),
('wcProvChar', wintypes.WCHAR * 1))
class _CONST:
COMMPROP_INITIALIZED = 0xE73CF52E
SP_SERIALCOMM = 0x00000001
BAUD_USER = 0x10000000 # programmable baud rate
DATABITS_16X = 0x0020 # hardware wide data path
PROV_SUBTYPE = collections.OrderedDict([
('UNSPECIFIED', 0x00000000),
('RS232', 0x00000001),
('PARALLELPORT', 0x00000002),
('RS422', 0x00000003),
('RS423', 0x00000004),
('RS449', 0x00000005),
('MODEM', 0x00000006),
('FAX', 0x00000021),
('SCANNER', 0x00000022),
('NETWORK_BRIDGE', 0x00000100),
('LAT', 0x00000101),
('TCPIP_TELNET', 0x00000102),
('X25', 0x00000103),
])
PROV_CAPABILITIES = collections.OrderedDict([
('DTRDSR', 0x0001), # data-terminal-ready / data-set-ready
('RTSCTS', 0x0002), # request-to-send / clear-to-send
('RLSD', 0x0004), # receive-line-signal-detect
('PARITY_CHECK', 0x0008),
('XONXOFF', 0x0010), # XON/XOFF flow control
('SETXCHAR', 0x0020), # settable XON/XOFF
('TOTALTIMEOUTS', 0x0040), # total (elapsed) time-outs
('INTTIMEOUTS', 0x0080), # interval time-outs
('SPECIALCHARS', 0x0100),
('16BITMODE', 0x0200),
])
SETTABLE_PARAMS = collections.OrderedDict([
('PARITY', 0x0001),
('BAUD', 0x0002),
('DATABITS', 0x0004),
('STOPBITS', 0x0008),
('HANDSHAKING', 0x0010), # flow control
('PARITY_CHECK', 0x0020),
('RLSD', 0x0040), # receive-line-signal-detect
])
SETTABLE_BAUD = collections.OrderedDict([
(75, 0x00000001),
(110, 0x00000002),
(134.5, 0x00000004),
(150, 0x00000008),
(300, 0x00000010),
(600, 0x00000020),
(1200, 0x00000040),
(1800, 0x00000080),
(2400, 0x00000100),
(4800, 0x00000200),
(7200, 0x00000400),
(9600, 0x00000800),
(14400, 0x00001000),
(19200, 0x00002000),
(38400, 0x00004000),
(56000, 0x00008000),
(57600, 0x00040000),
(115200, 0x00020000),
(128000, 0x00010000),
])
SETTABLE_DATA = collections.OrderedDict([
(5, 0x0001), # 5 data bits
(6, 0x0002), # 6 data bits
(7, 0x0004), # 7 data bits
(8, 0x0008), # 8 data bits
(16, 0x0010), # 16 data bits
])
SETTABLE_STOP = collections.OrderedDict([
(1, 0x0001), # 1 stop bit
(1.5, 0x0002), # 1.5 stop bits
(2, 0x0004), # 2 stop bits
])
SETTABLE_PARITY = collections.OrderedDict([
('NONE', 0x0100), # no parity
('ODD', 0x0200), # odd parity
('EVEN', 0x0400), # even parity
('MARK', 0x0800), # mark parity
('SPACE', 0x1000), # space parity
])
#property
def max_baud(self):
s = self.dwMaxBaud
m = self._CONST.SETTABLE_BAUD
if s == self._CONST.BAUD_USER:
return 0
else:
return m[s]
#property
def prov_subtype(self):
s = self.dwProvSubType
m = self._CONST.PROV_SUBTYPE
return [x for x, c in m.items() if c & s]
#property
def prov_capabilities(self):
s = self.dwProvCapabilities
m = self._CONST.PROV_CAPABILITIES
return [x for x, c in m.items() if c & s]
#property
def settable_params(self):
s = self.dwSettableParams
m = self._CONST.SETTABLE_PARAMS
return [x for x, c in m.items() if c & s]
#property
def settable_baud(self):
s = self.dwSettableBaud
m = self._CONST.SETTABLE_BAUD
return [x for x, c in m.items() if c & s]
#property
def user_settable_baud(self):
return bool(self.dwSettableBaud & self._CONST.BAUD_USER)
#property
def settable_data(self):
s = self.wSettableData
m = self._CONST.SETTABLE_DATA
return [x for x, c in m.items() if c & s]
#property
def wide_settable_data(self):
return bool(self.wSettableData & self._CONST.DATABITS_16X)
#property
def settable_stop(self):
s = self.wSettableStopParity
m = self._CONST.SETTABLE_STOP
return [x for x, c in m.items() if c & s]
#property
def settable_parity(self):
s = self.wSettableStopParity
m = self._CONST.SETTABLE_PARITY
return [x for x, c in m.items() if c & s]
LPCOMMPROP = ctypes.POINTER(COMMPROP)
class SECURITY_ATTRIBUTES(ctypes.Structure):
_fields_ = (('nLength', wintypes.DWORD),
('lpSecurityDescriptor', wintypes.LPVOID),
('bInheritHandle', wintypes.BOOL))
LPSECURITY_ATTRIBUTES = ctypes.POINTER(SECURITY_ATTRIBUTES)
kernel32.CreateFileW.restype = wintypes.HANDLE
kernel32.CreateFileW.argtypes = (
wintypes.LPCWSTR, # _In_ lpFileName
wintypes.DWORD, # _In_ dwDesiredAccess
wintypes.DWORD, # _In_ dwShareMode
LPSECURITY_ATTRIBUTES, # _In_opt_ lpSecurityAttributes
wintypes.DWORD, # _In_ dwCreationDisposition
wintypes.DWORD, # _In_ dwFlagsAndAttributes
wintypes.HANDLE) # _In_opt_ hTemplateFile
kernel32.CloseHandle.argtypes = (wintypes.HANDLE,)
kernel32.GetCommProperties.argtypes = (
wintypes.HANDLE, # _In_ hFile
LPCOMMPROP) # _Out_ lpCommProp
def get_comm_properties(handle_or_port):
if isinstance(handle_or_port, str):
handle = kernel32.CreateFileW(
handle_or_port,
GENERIC_READ | GENERIC_WRITE,
0, # exclusive access
None, # default security
OPEN_EXISTING,
0,
None)
if handle == INVALID_HANDLE_VALUE:
raise ctypes.WinError(ctypes.get_last_error())
close_handle = True
else:
handle = handle_or_port
close_handle = False
try:
prop = COMMPROP()
if not kernel32.GetCommProperties(handle, ctypes.byref(prop)):
raise ctypes.WinError(ctypes.get_last_error())
finally:
if close_handle:
kernel32.CloseHandle(handle)
return prop
Example:
if __name__ == '__main__':
for i in range(1, 10):
port = r'\\.\COM%d' % i
try:
prop = get_comm_properties(port)
except WindowsError as e:
if e.winerror == ERROR_FILE_NOT_FOUND:
continue
print('%s properties' % port)
x = prop.dwMaxTxQueue if prop.dwMaxTxQueue else 'no limit'
print('\tMax output buffer size: %s' % x)
x = prop.dwMaxRxQueue if prop.dwMaxRxQueue else 'no limit'
print('\tMax input buffer size: %s' % x)
x = prop.dwCurrentTxQueue if prop.dwCurrentTxQueue else 'unavailable'
print('\tCurrent output buffer size: %s' % x)
x = prop.dwCurrentRxQueue if prop.dwCurrentRxQueue else 'unavailable'
print('\tCurrent input buffer size: %s' % x)
x = prop.max_baud if prop.max_baud else 'user programmable'
print('\tMax baud rate: %s' % x)
print('\tProvider subtypes:\n\t\t%s' %
'\n\t\t'.join(prop.prov_subtype))
print('\tProvider capabilities:\n\t\t%s' %
'\n\t\t'.join(prop.prov_capabilities))
print('\tSettable parameters:\n\t\t%s' %
'\n\t\t'.join(prop.settable_params))
print('\tSettable baud rates:\n\t\t%s' %
'\n\t\t'.join([str(x) for x in prop.settable_baud]))
print('\tSettable user baud rates: %s' %
prop.user_settable_baud)
print('\tSettable data bits:\n\t\t%s' %
'\n\t\t'.join([str(x) for x in prop.settable_data]))
print('\tSettable wide data bits: %s' %
prop.wide_settable_data)
print('\tSettable stop bits:\n\t\t%s' %
'\n\t\t'.join([str(x) for x in prop.settable_stop]))
print('\tSettable parity:\n\t\t%s' %
'\n\t\t'.join(prop.settable_parity))
Output:
\\.\COM1 properties
Max output buffer size: no limit
Max input buffer size: no limit
Current output buffer size: unavailable
Current input buffer size: 4096
Max baud rate: user programmable
Provider subtypes:
RS232
RS422
RS449
FAX
LAT
X25
Provider capabilities:
DTRDSR
RTSCTS
RLSD
PARITY_CHECK
XONXOFF
SETXCHAR
TOTALTIMEOUTS
INTTIMEOUTS
Settable parameters:
PARITY
BAUD
DATABITS
STOPBITS
HANDSHAKING
PARITY_CHECK
RLSD
Settable baud rates:
75
110
134.5
150
300
600
1200
1800
2400
4800
7200
9600
14400
19200
38400
56000
57600
115200
Settable user baud rates: True
Settable data bits:
5
6
7
8
Settable wide data bits: False
Settable stop bits:
1
1.5
2
Settable parity:
NONE
ODD
EVEN
MARK
SPACE
Baud rates <100 are treated as configuration errors in Windows 7. So starting the loop on 50,75 baud will both yield errors. 110 baud does not return an error.
I would like to write a general method for all operating systems (Win, MacOS, Unix, ...) that changes a folder's icon.
I would like to extend the following implementation
import os
import warnings
import ctypes
from ctypes import POINTER, Structure, c_wchar, c_int, sizeof, byref
from ctypes.wintypes import BYTE, WORD, DWORD, LPWSTR, LPSTR
import win32api
class SetFolderIcon(object):
def __init__(self, folderPath, iconPath, reset=False):
assert os.path.isdir(folderPath), "folderPath '%s' is not a valid folder"%folderPath
self.__folderPath = unicode(os.path.abspath(folderPath), 'mbcs')
assert os.path.isfile(iconPath), "iconPath '%s' does not exist"%iconPath
self.__iconPath = unicode(os.path.abspath(iconPath), 'mbcs')
assert isinstance(reset, bool), "reset must be boolean"
self.__reset = reset
# set icon if system is windows
if os.name == 'nt':
try:
self.__set_icon_on_windows()
except Exception as e:
warnings.warn("Unable to set folder icon (%s)"%e)
elif os.name == 'posix':
raise Exception('posix system not implemented yet')
elif os.name == 'mac':
raise Exception('mac system not implemented yet')
elif os.name == 'os2':
raise Exception('os2 system not implemented yet')
elif os.name == 'ce':
raise Exception('ce system not implemented yet')
elif os.name == 'java':
raise Exception('java system not implemented yet')
elif os.name == 'riscos':
raise Exception('riscos system not implemented yet')
def __set_icon_on_windows(self):
HICON = c_int
LPTSTR = LPWSTR
TCHAR = c_wchar
MAX_PATH = 260
FCSM_ICONFILE = 0x00000010
FCS_FORCEWRITE = 0x00000002
SHGFI_ICONLOCATION = 0x000001000
class GUID(Structure):
_fields_ = [ ('Data1', DWORD),
('Data2', WORD),
('Data3', WORD),
('Data4', BYTE * 8) ]
class SHFOLDERCUSTOMSETTINGS(Structure):
_fields_ = [ ('dwSize', DWORD),
('dwMask', DWORD),
('pvid', POINTER(GUID)),
('pszWebViewTemplate', LPTSTR),
('cchWebViewTemplate', DWORD),
('pszWebViewTemplateVersion', LPTSTR),
('pszInfoTip', LPTSTR),
('cchInfoTip', DWORD),
('pclsid', POINTER(GUID)),
('dwFlags', DWORD),
('pszIconFile', LPTSTR),
('cchIconFile', DWORD),
('iIconIndex', c_int),
('pszLogo', LPTSTR),
('cchLogo', DWORD) ]
class SHFILEINFO(Structure):
_fields_ = [ ('hIcon', HICON),
('iIcon', c_int),
('dwAttributes', DWORD),
('szDisplayName', TCHAR * MAX_PATH),
('szTypeName', TCHAR * 80) ]
shell32 = ctypes.windll.shell32
fcs = SHFOLDERCUSTOMSETTINGS()
fcs.dwSize = sizeof(fcs)
fcs.dwMask = FCSM_ICONFILE
fcs.pszIconFile = self.__iconPath
fcs.cchIconFile = 0
fcs.iIconIndex = self.__reset
hr = shell32.SHGetSetFolderCustomSettings(byref(fcs), self.__folderPath, FCS_FORCEWRITE)
if hr:
raise WindowsError(win32api.FormatMessage(hr))
sfi = SHFILEINFO()
hr = shell32.SHGetFileInfoW(self.__folderPath, 0, byref(sfi), sizeof(sfi), SHGFI_ICONLOCATION)
#if hr == 0:
# raise WindowsError(win32api.FormatMessage(hr))
index = shell32.Shell_GetCachedImageIndexW(sfi.szDisplayName, sfi.iIcon, 0)
shell32.SHUpdateImageW(sfi.szDisplayName, sfi.iIcon, 0, index)
iconPath = 'C:\\Users\\myself\\Desktop\\icon.ico'
#iconPath = "C:\\Windows\\system32\\SHELL32.dll"
SetFolderIcon('C:\\Users\\myself\\Desktop\\Newfolder',iconPath, reset=False)
# reset icon
SetFolderIcon('C:\\Users\\myself\\Desktop\\Newfolder',iconPath, reset=True)
As you can see I only implemented the windows version using __set_icon_on_windows method. similar methods such as __set_icon_on_mac ... must be implemented
Thanks
I am trying to write a sort of driver using python for windows 8. I will be receiving touch coordinates via serial which I then want to use to make it appear as though someone touched those coordinates on the screen (emulate a touch).
My first question is:
Is a touch event in Windows 8 different from just a mouse click at the area? (I know they revamped everything for touch events but am unsure of what that involved -- possibly like an area of effect thing to make it more touch screen friendly?)
Secondly:
If so, is there a library for python to emulate a 'touch' at a coordinate instead of a 'click'?
UPDATE:
Using ctypes and the page linked in the comments, I have created this:
from ctypes import *
#Constants
#For touchMask
TOUCH_MASK_NONE= 0x00000000 #Default
TOUCH_MASK_CONTACTAREA= 0x00000001
TOUCH_MASK_ORIENTATION= 0x00000002
TOUCH_MASK_PRESSURE= 0x00000004
TOUCH_MASK_ALL= 0x00000007
#For touchFlag
TOUCH_FLAG_NONE= 0x00000000
#For pointerType
PT_POINTER= 0x00000001#All
PT_TOUCH= 0x00000002
PT_PEN= 0x00000003
PT_MOUSE= 0x00000004
#For pointerFlags
POINTER_FLAG_NONE= 0x00000000#Default
POINTER_FLAG_NEW= 0x00000001
POINTER_FLAG_INRANGE= 0x00000002
POINTER_FLAG_INCONTACT= 0x00000004
POINTER_FLAG_FIRSTBUTTON= 0x00000010
POINTER_FLAG_SECONDBUTTON=0x00000020
POINTER_FLAG_THIRDBUTTON= 0x00000040
POINTER_FLAG_FOURTHBUTTON=0x00000080
POINTER_FLAG_FIFTHBUTTON= 0x00000100
POINTER_FLAG_PRIMARY= 0x00002000
POINTER_FLAG_CONFIDENCE= 0x00004000
POINTER_FLAG_CANCELED= 0x00008000
POINTER_FLAG_DOWN= 0x00010000
POINTER_FLAG_UPDATE= 0x00020000
POINTER_FLAG_UP= 0x00040000
POINTER_FLAG_WHEEL= 0x00080000
POINTER_FLAG_HWHEEL= 0x00100000
POINTER_FLAG_CAPTURECHANGED=0x00200000
#Structs Needed
class POINT(Structure):
_fields_=[("x", c_long),
("y", c_long)]
class POINTER_INFO(Structure):
_fields_=[("pointerType",c_int32),
("pointerId",c_uint32),
("frameId",c_uint32),
("pointerFlags",c_int),
("sourceDevice",c_uint32),
("hwndTarget",c_uint32),
("ptPixelLocation",POINT),
("ptHimetricLocation",POINT),
("ptPixelLocationRaw",POINT),
("ptHimetricLocationRaw",POINT),
("dwTime",c_uint32),
("historyCount",c_uint32),
("inputData",c_int32),
("dwKeyStates",c_uint32),
("PerformanceCount",c_uint64),
("ButtonChangeType",c_int)
]
class RECT(Structure):
_fields_=[("left",c_long),
("top",c_long),
("right",c_long),
("bottom",c_long)]
class POINTER_TOUCH_INFO(Structure):
_fields_=[("pointerInfo",POINTER_INFO),
("touchFlags",c_int),
("touchMask",c_int),
("rcContact", RECT),
("rcContactRaw",RECT),
("orientation", c_uint32),
("pressure", c_uint32)]
#Initialize Touch Injection
pointerInfo=POINTER_INFO(pointerType=PT_TOUCH,
pointerId=0,
ptPixelLocation=POINT(950,540))
touchInfo=POINTER_TOUCH_INFO(pointerInfo=pointerInfo,
touchFlags=TOUCH_FLAG_NONE,
touchMask=TOUCH_MASK_ALL,
rcContact=RECT(pointerInfo.ptPixelLocation.x-5,
pointerInfo.ptPixelLocation.y-5,
pointerInfo.ptPixelLocation.x+5,
pointerInfo.ptPixelLocation.y+5),
orientation=90,
pressure=32000)
if (windll.user32.InitializeTouchInjection(1,1) != 0):
print "Initialized Touch Injection"
#Press Down
touchInfo.pointerInfo.pointerFlags=(POINTER_FLAG_DOWN|
POINTER_FLAG_INRANGE|
POINTER_FLAG_INCONTACT)
if (windll.user32.InjectTouchInput(1, byref(touchInfo))==0):
print "Failed with Error: "+ FormatError()
else:
print "Touch Down Succeeded!"
#Pull Up
touchInfo.pointerInfo.pointerFlags=POINTER_FLAG_UP
if (windll.user32.InjectTouchInput(1,byref(touchInfo))==0):
print "Failed with Error: "+FormatError()
else:
print "Pull Up Succeeded!"
Fails everytime with error about the input parameters.
I've gone through every reference and can't find a type that seems incorrect. Does anyone see something obvious?
Thanks
Thanks to Eryksum and Xyroid, I was able to get it working. Thanks for putting up with my C-type / Windows ignorance. Here is the final script with the touch emulation packaged as a function (extra constants as well):
from ctypes import *
from ctypes.wintypes import *
#Constants
#For touchMask
TOUCH_MASK_NONE= 0x00000000 #Default
TOUCH_MASK_CONTACTAREA= 0x00000001
TOUCH_MASK_ORIENTATION= 0x00000002
TOUCH_MASK_PRESSURE= 0x00000004
TOUCH_MASK_ALL= 0x00000007
#For touchFlag
TOUCH_FLAG_NONE= 0x00000000
#For pointerType
PT_POINTER= 0x00000001#All
PT_TOUCH= 0x00000002
PT_PEN= 0x00000003
PT_MOUSE= 0x00000004
#For pointerFlags
POINTER_FLAG_NONE= 0x00000000#Default
POINTER_FLAG_NEW= 0x00000001
POINTER_FLAG_INRANGE= 0x00000002
POINTER_FLAG_INCONTACT= 0x00000004
POINTER_FLAG_FIRSTBUTTON= 0x00000010
POINTER_FLAG_SECONDBUTTON=0x00000020
POINTER_FLAG_THIRDBUTTON= 0x00000040
POINTER_FLAG_FOURTHBUTTON=0x00000080
POINTER_FLAG_FIFTHBUTTON= 0x00000100
POINTER_FLAG_PRIMARY= 0x00002000
POINTER_FLAG_CONFIDENCE= 0x00004000
POINTER_FLAG_CANCELED= 0x00008000
POINTER_FLAG_DOWN= 0x00010000
POINTER_FLAG_UPDATE= 0x00020000
POINTER_FLAG_UP= 0x00040000
POINTER_FLAG_WHEEL= 0x00080000
POINTER_FLAG_HWHEEL= 0x00100000
POINTER_FLAG_CAPTURECHANGED=0x00200000
#Structs Needed
class POINTER_INFO(Structure):
_fields_=[("pointerType",c_uint32),
("pointerId",c_uint32),
("frameId",c_uint32),
("pointerFlags",c_int),
("sourceDevice",HANDLE),
("hwndTarget",HWND),
("ptPixelLocation",POINT),
("ptHimetricLocation",POINT),
("ptPixelLocationRaw",POINT),
("ptHimetricLocationRaw",POINT),
("dwTime",DWORD),
("historyCount",c_uint32),
("inputData",c_int32),
("dwKeyStates",DWORD),
("PerformanceCount",c_uint64),
("ButtonChangeType",c_int)
]
class POINTER_TOUCH_INFO(Structure):
_fields_=[("pointerInfo",POINTER_INFO),
("touchFlags",c_int),
("touchMask",c_int),
("rcContact", RECT),
("rcContactRaw",RECT),
("orientation", c_uint32),
("pressure", c_uint32)]
#Initialize Pointer and Touch info
pointerInfo=POINTER_INFO(pointerType=PT_TOUCH,
pointerId=0,
ptPixelLocation=POINT(950,540))
touchInfo=POINTER_TOUCH_INFO(pointerInfo=pointerInfo,
touchFlags=TOUCH_FLAG_NONE,
touchMask=TOUCH_MASK_ALL,
rcContact=RECT(pointerInfo.ptPixelLocation.x-5,
pointerInfo.ptPixelLocation.y-5,
pointerInfo.ptPixelLocation.x+5,
pointerInfo.ptPixelLocation.y+5),
orientation=90,
pressure=32000)
def makeTouch(x,y,fingerRadius):
touchInfo.pointerInfo.ptPixelLocation.x=x
touchInfo.pointerInfo.ptPixelLocation.y=y
touchInfo.rcContact.left=x-fingerRadius
touchInfo.rcContact.right=x+fingerRadius
touchInfo.rcContact.top=y-fingerRadius
touchInfo.rcContact.bottom=y+fingerRadius
#Initialize Touch Injection
if (windll.user32.InitializeTouchInjection(1,1) != 0):
print "Initialized Touch Injection"
#Press Down
touchInfo.pointerInfo.pointerFlags=(POINTER_FLAG_DOWN|
POINTER_FLAG_INRANGE|
POINTER_FLAG_INCONTACT)
if (windll.user32.InjectTouchInput(1, byref(touchInfo))==0):
print "Failed with Error: "+ FormatError()
else:
print "Touch Down Succeeded!"
#Pull Up
touchInfo.pointerInfo.pointerFlags=POINTER_FLAG_UP
if (windll.user32.InjectTouchInput(1,byref(touchInfo))==0):
print "Failed with Error: "+FormatError()
else:
print "Pull Up Succeeded!"
return
#Ex:
#makeTouch(950,270,5)
For future multitouch travelers, the above example needs some significant massaging to create multiple touch events with a proper lifetime.
This includes maintaining persistent POINTER_TOUCH_INFO arrays, setting their ID's appropriately, and properly calling DOWN, UPDATE, and UP events as needed.
Hopefully this addition to the example script will save others time:
from ctypes import *
from ctypes.wintypes import *
# Constants
# For touchMask
TOUCH_MASK_NONE= 0x00000000 # Default
TOUCH_MASK_CONTACTAREA= 0x00000001
TOUCH_MASK_ORIENTATION= 0x00000002
TOUCH_MASK_PRESSURE= 0x00000004
TOUCH_MASK_ALL= 0x00000007
# For touchFlag
TOUCH_FLAG_NONE= 0x00000000
# For pointerType
PT_POINTER= 0x00000001 # All
PT_TOUCH= 0x00000002
PT_PEN= 0x00000003
PT_MOUSE= 0x00000004
#For pointerFlags
POINTER_FLAG_NONE= 0x00000000 # Default
POINTER_FLAG_NEW= 0x00000001
POINTER_FLAG_INRANGE= 0x00000002
POINTER_FLAG_INCONTACT= 0x00000004
POINTER_FLAG_FIRSTBUTTON= 0x00000010
POINTER_FLAG_SECONDBUTTON=0x00000020
POINTER_FLAG_THIRDBUTTON= 0x00000040
POINTER_FLAG_FOURTHBUTTON=0x00000080
POINTER_FLAG_FIFTHBUTTON= 0x00000100
POINTER_FLAG_PRIMARY= 0x00002000
POINTER_FLAG_CONFIDENCE= 0x00004000
POINTER_FLAG_CANCELED= 0x00008000
POINTER_FLAG_DOWN= 0x00010000
POINTER_FLAG_UPDATE= 0x00020000
POINTER_FLAG_UP= 0x00040000
POINTER_FLAG_WHEEL= 0x00080000
POINTER_FLAG_HWHEEL= 0x00100000
POINTER_FLAG_CAPTURECHANGED=0x00200000
# Structs Needed
class POINTER_INFO(Structure):
_fields_=[("pointerType",c_uint32),
("pointerId",c_uint32),
("frameId",c_uint32),
("pointerFlags",c_int),
("sourceDevice",HANDLE),
("hwndTarget",HWND),
("ptPixelLocation",POINT),
("ptHimetricLocation",POINT),
("ptPixelLocationRaw",POINT),
("ptHimetricLocationRaw",POINT),
("dwTime",DWORD),
("historyCount",c_uint32),
("inputData",c_int32),
("dwKeyStates",DWORD),
("PerformanceCount",c_uint64),
("ButtonChangeType",c_int)
]
class POINTER_TOUCH_INFO(Structure):
_fields_=[("pointerInfo",POINTER_INFO),
("touchFlags",c_int),
("touchMask",c_int),
("rcContact", RECT),
("rcContactRaw",RECT),
("orientation", c_uint32),
("pressure", c_uint32)]
# Initialize Pointer and Touch info
def initialize(maxtouches=10, dwmode=1):
global touches
touches = (POINTER_TOUCH_INFO * maxtouches)()
for ind in range(maxtouches):
pointerInfo=POINTER_INFO(pointerType = PT_TOUCH,
pointerId = ind,
ptPixelLocation = POINT(950,540),
pointerFlags = POINTER_FLAG_NEW)
touchInfo=POINTER_TOUCH_INFO(pointerInfo = pointerInfo,
touchFlags = TOUCH_FLAG_NONE,
touchMask = TOUCH_MASK_ALL,
rcContact = RECT(pointerInfo.ptPixelLocation.x-5,
pointerInfo.ptPixelLocation.y-5,
pointerInfo.ptPixelLocation.x+5,
pointerInfo.ptPixelLocation.y+5),
orientation = 90,
pressure = 32000)
touches[ind] = touchInfo
if (windll.user32.InitializeTouchInjection(len(touches), 1) != 0):
print("Initialized Touch Injection")
ids_to_update = 0
currently_down = None
def updateTouchInfo(id, down, x = 0, y = 0, fingerRadius=1, orientation = 90, pressure = 32000):
global currently_down, ids_to_update
if currently_down == None or len(currently_down) != len(touches):
currently_down = [False] * len(touches)
if down:
touches[id].pointerInfo.pointerFlags = (((POINTER_FLAG_DOWN) if not currently_down[id] else POINTER_FLAG_UPDATE)|
POINTER_FLAG_INRANGE |
POINTER_FLAG_INCONTACT)
touches[id].orientation = orientation
touches[id].pressure = pressure
touches[id].pointerInfo.ptPixelLocation.x = x
touches[id].pointerInfo.ptPixelLocation.y = y
touches[id].rcContact.left = x - fingerRadius
touches[id].rcContact.right = x + fingerRadius
touches[id].rcContact.top = y - fingerRadius
touches[id].rcContact.bottom = y + fingerRadius
else:
touches[id].pointerInfo.pointerFlags = POINTER_FLAG_UP #if currently_down[id] else POINTER_FLAG_UPDATE #if currently_down[id] else POINTER_FLAG_UPDATE
ids_to_update += 1 if down or currently_down[id] else 0
currently_down[id] = down
def applyTouches():
global ids_to_update
if ids_to_update > 0:
if (windll.user32.InjectTouchInput(int(ids_to_update), byref(touches[0])) == 0):
print("Failed trying to update", ids_to_update, "points with Error:", FormatError())
ids_to_update = 0
# Use like:
#import multitouch # Call once
#multitouch.initialize() # Call once
#for i in range(10): # Call every frame
# if i < len(keypoints):
# multitouch.updateTouchInfo(i, True,
# int(keypoints[i].pt[0] * 3),
# int(keypoints[i].pt[1] * 3),
# int(keypoints[i].size / 2))
# else:
# multitouch.updateTouchInfo(i, False)
#multitouch.applyTouches()
I am porting some Java code to Python and we would like to use Python 3 but I can't find LDAP module for Python 3 in Windows.
This is forcing us to use 2.6 version and it is bothersome as rest of the code is already in 3.0 format.
You may use ldap3 module (formerly known as python3-ldap), it runs on python3 really well and requires no external C dependances. Also it can correctly handle both unicode and byte data in ldap records (in early versions there was a trouble with jpegPhoto field, now everything is fine)
If you're running this on Windows, you can get LDAP to work in Python 3.1 by using the ADO access method via Mark Hammond's PyWin32.
To test this, I installed ActiveState Python 3.1, then installed PyWin32 for Python 3.1
http://sourceforge.net/projects/pywin32/files/
I was then able to run LDAP queries using a module I wrote that is based on this LDAP code from the ActiveState Python Cookbook:
Recipe 511451: Dump all Active Directory Information using LDAP scripting by Manuel Garcia
http://code.activestate.com/recipes/511451/
although now that I look at it I realize I completely rewrote my module just using his code as an example.
Update
Here is my LDAPList module and another support module to convert user access bit codes into something a tiny bit more english-like:
LDAPList.py
# LDAPList.py
# Todd Fiske
# class to encapsulate accessing LDAP information
# 2009-03-18 first version
# 2010-01-04 updated for Python 3 (print functions, <> to !=)
import win32com.client
import UACCodes
ADS_SCOPE_SUBTREE = 2
class LDAPList():
def __init__(self, sContext):
self.Context = sContext # naming context, "DC=xyz,DC=org"
self.objectCategory = ""
self.objectClass = ""
self.FilterClause = ""
self.query = ""
self.cn = None
self.cm = None
self.rs = None
def SetCategory(self, sCategory):
self.objectCategory = sCategory
self.FilterClause = "where objectCategory = '%s'" % self.objectCategory
def SetClass(self, sClass):
self.objectClass = sClass
self.FilterClause = "where objectClass = '%s'" % self.objectClass
def open(self):
self.query = "select * from 'LDAP://%s' %s order by displayName" % (self.Context, self.FilterClause)
self.cn = win32com.client.Dispatch("ADODB.Connection")
self.cm = win32com.client.Dispatch("ADODB.Command")
self.cn.Open("Provider=ADsDSOObject")
self.cm.ActiveConnection = self.cn
self.cm.Properties["Page Size"] = 1000
self.cm.Properties["Searchscope"] = ADS_SCOPE_SUBTREE
self.cm.CommandText = self.query
self.rs = self.cm.Execute()[0]
def close(self):
if self.rs is not None:
self.rs.Close()
self.rs = None
if self.cm is not None:
self.cm = None
if self.cn is not None:
self.cn.Close()
self.cn = None
def count(self):
if self.rs is None:
return -2
return self.rs.RecordCount
def more(self):
if self.rs is None:
return False
return not self.rs.EOF
def GetObject(self):
if self.rs is None:
return None
return win32com.client.GetObject(self.rs.Fields["ADsPath"].Value)
def next(self):
if self.rs is None:
return
self.rs.MoveNext()
#----------
# helper functions
def NamingContext():
# return default naming context
root = win32com.client.GetObject("LDAP://RootDse")
return root.get("DefaultNamingContext")
def AccountControl(obj):
if obj.userAccountControl is not None:
return obj.userAccountControl
else:
return 0
def ConvertUAC(nUAC):
return UACCodes.ConvertUAC(nUAC)
def AccountActive(n):
return (n & UACCodes.ADS_UF_ACCOUNTDISABLE) != UACCodes.ADS_UF_ACCOUNTDISABLE
def GetCategory(obj):
# CN=Group,CN=Schema,CN=Configuration,DC=xyz,DC=org
s = obj.objectCategory
s = s.split(",")[0][3:]
return s
# s = "Group"
def GetGroups(obj):
"""
('CN=XYZ Staff Rockville,OU=Distribution Groups,DC=xyz,DC=org',
'CN=XYZ Staff,OU=Distribution Groups,DC=xyz,DC=org')
"""
if obj.memberOf is None:
return ""
if type(obj.memberOf)==type(()):
tGroups = obj.memberOf
else:
tGroups = (obj.memberOf,)
return tGroups
def GetNameParts(obj):
if obj.givenName is None:
sFirst = ""
else:
sFirst = obj.givenName
if obj.middleName is None:
sMiddle = ""
else:
sMiddle = obj.middleName
if obj.sn is None:
sLast = ""
else:
sLast = obj.sn
if sLast == "" and sFirst == "":
if obj.name is not None:
sName = obj.name
sName = sName[3:]
lParts = sName.split(" ")
if len(lParts) == 1:
"todo: split on embedded capital letter"
print("single-part name: %s" % sName)
sFirst = sName
else:
sLast = lParts[-1]
sFirst = " ".join(lParts[:-1])
return (sFirst, sMiddle, sLast)
def GetManager(obj):
if obj.manager is None:
return ""
else:
return obj.manager
#----------
# test
if __name__ == "__main__":
print
print("testing LDAPList class")
nc = NamingContext()
print("context =", nc)
ll = LDAPList(nc)
ll.SetCategory('user')
ll.open() # generates recordset
print("query = %s" % ll.query)
print("%d items" % ll.count())
n = 0
while (n < 10) and (ll.more()):
o = ll.GetObject() # return
nUAC = AccountControl(o)
print("%-30s %-30s %-30s %-40s %s" % (
o.displayName,
o.name,
o.sAMAccountName,
UACCodes.ConvertUAC(nUAC),
GetManager(o)
))
n += 1
ll.next()
ll.close()
###
UACCodes.py
# UACCodes.py
# Todd Fiske
# generated 2009-09-23 16:36:56 by BuildUACCodes.py
# updated 2010-01-04 for Python 3 (print functions)
# provide UAC constants, lookup list, and conversion function
import sys
# UAC Constants
ADS_UF_SCRIPT = 0x00000001
ADS_UF_ACCOUNTDISABLE = 0x00000002
ADS_UF_HOMEDIR_REQUIRED = 0x00000008
ADS_UF_LOCKOUT = 0x00000010
ADS_UF_PASSWD_NOTREQD = 0x00000020
ADS_UF_PASSWD_CANT_CHANGE = 0x00000040
ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x00000080
ADS_UF_TEMP_DUPLICATE_ACCOUNT = 0x00000100
ADS_UF_NORMAL_ACCOUNT = 0x00000200
ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 0x00000800
ADS_UF_WORKSTATION_TRUST_ACCOUNT = 0x00001000
ADS_UF_SERVER_TRUST_ACCOUNT = 0x00002000
ADS_UF_DONT_EXPIRE_PASSWD = 0x00010000
ADS_UF_MNS_LOGON_ACCOUNT = 0x00020000
ADS_UF_SMARTCARD_REQUIRED = 0x00040000
ADS_UF_TRUSTED_FOR_DELEGATION = 0x00080000
ADS_UF_NOT_DELEGATED = 0x00100000
ADS_UF_USE_DES_KEY_ONLY = 0x00200000
ADS_UF_DONT_REQUIRE_PREAUTH = 0x00400000
ADS_UF_PASSWORD_EXPIRED = 0x00800000
ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x01000000
# UAC short name lookup list
lUACCodes = [
("ADS_UF_SCRIPT" , 0x00000001, "script"),
("ADS_UF_ACCOUNTDISABLE" , 0x00000002, "disabled"),
("ADS_UF_HOMEDIR_REQUIRED" , 0x00000008, "homedir"),
("ADS_UF_LOCKOUT" , 0x00000010, "lockout"),
("ADS_UF_PASSWD_NOTREQD" , 0x00000020, "pwnotreqd"),
("ADS_UF_PASSWD_CANT_CHANGE" , 0x00000040, "pwcantchange"),
("ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED" , 0x00000080, "encryptedpw"),
("ADS_UF_TEMP_DUPLICATE_ACCOUNT" , 0x00000100, "dupaccount"),
("ADS_UF_NORMAL_ACCOUNT" , 0x00000200, "useracct"),
("ADS_UF_INTERDOMAIN_TRUST_ACCOUNT" , 0x00000800, "interdomain"),
("ADS_UF_WORKSTATION_TRUST_ACCOUNT" , 0x00001000, "workstation"),
("ADS_UF_SERVER_TRUST_ACCOUNT" , 0x00002000, "server"),
("ADS_UF_DONT_EXPIRE_PASSWD" , 0x00010000, "pwnoexpire"),
("ADS_UF_MNS_LOGON_ACCOUNT" , 0x00020000, "mnslogon"),
("ADS_UF_SMARTCARD_REQUIRED" , 0x00040000, "smartcard"),
("ADS_UF_TRUSTED_FOR_DELEGATION" , 0x00080000, "trustdeleg"),
("ADS_UF_NOT_DELEGATED" , 0x00100000, "notdeleg"),
("ADS_UF_USE_DES_KEY_ONLY" , 0x00200000, "deskey"),
("ADS_UF_DONT_REQUIRE_PREAUTH" , 0x00400000, "nopreauth"),
("ADS_UF_PASSWORD_EXPIRED" , 0x00800000, "pwexpired"),
("ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION", 0x01000000, "trustauth"),
]
# UAC conversion function
def ConvertUAC(nUAC):
s = ""
for c in lUACCodes:
if ((nUAC & c[1]) == c[1]):
s = s + c[2] + " "
return s
# test routine
if __name__ == "__main__":
print("UACCodes Test")
print("-------------")
for n in [0, 512, 514, 65535]:
print("%d = %s" % (n, ConvertUAC(n)))
print
for s in sys.argv[1:]:
n = int(s)
print("%d = %s" % (n, ConvertUAC(n)))
###
Both modules have some usage examples and should be fairly easy to figure out, but let me know if you have any questions or comments.
There is a Pure Python implementation of an LDAP client called Ldaptor. I don't think it's maintained though. If you really need it, you might be able to run 2to3 on this and port it.
This answer is no longer accurate; see below for other answers.
Sorry to break this on you, but I don't think there is a python-ldap for Python 3 (yet)...
That's the reason why we should keep active development at Python 2.6 for now (as long as most crucial dependencies (libs) are not ported to 3.0).