def hash_data(buffer, alg, block_size=16*1024): if alg not in _calg_map: raise InvalidHashAlgorithm() block_size = int(block_size) if block_size <= 0: raise ValueError("'block_size' should be a positive integer") with _crypt_context() as hCryptProv: with _crypt_hash(hCryptProv, _calg_map[alg]) as hCryptHash: buffer_len = len(buffer) if block_size > buffer_len: block_size = buffer_len i = 0 while i < buffer_len: count = block_size if (i + block_size <= buffer_len) else (buffer_len - i) if not CryptHashData(hCryptHash, _cast(buffer[i:i+count], PBYTE), DWORD(count), DWORD(0)): raise WinError() i += count dwHashLen = DWORD(sizeof(DWORD)) dwHashSize = DWORD() if not CryptGetHashParam(hCryptHash, HP_HASHSIZE, _cast(pointer(dwHashSize), PBYTE), pointer(dwHashLen), DWORD(0)): raise WinError() pbHashVal = (BYTE * dwHashSize.value)() dwHashLen.value = sizeof(pbHashVal) if not CryptGetHashParam(hCryptHash, HP_HASHVAL, pbHashVal, pointer(dwHashLen), DWORD(0)): raise WinError() return ''.join(map(lambda b: format(b, '02x'), bytes(pbHashVal)))
def doUrlGet(self, url, host, headers={}, user=0, password=0, port=80): wininet = windll.wininet flags = DWORD() data = '' retVal = (0, data) # Use the Registry settings for Proxy (nice!) INTERNET_OPEN_TYPE_PRECONFIG = 0 self.lock.acquire() self.hInternet = wininet.InternetOpenA('WAPT)', INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0); self.lock.release() if not self.hInternet: code = GetLastError() #gErr.log("couldn't open: %d - %s" %(code, FormatError(code))) self.stop() return retVal #print hInternet #print "Doing Connect" #gDbg.log('Connecting...') if self.callback: self.callback('Connecting...', 1) time.sleep(sleepTime) INTERNET_SERVICE_HTTP = 3 INTERNET_INVALID_PORT_NUMBER = 0 self.hConnect = wininet.InternetConnectA(self.hInternet, host, port, user, password, INTERNET_SERVICE_HTTP, 0, 0) if not self.hConnect: code = GetLastError() #gErr.log("couldn't connect: %d - %s" %(code, FormatError(code))) self.stop() return retVal #print hConnect #gDbg.log('Opening Request...') if self.callback: self.callback('Sending...', 2) time.sleep(sleepTime) INTERNET_FLAG_NO_CACHE_WRITE = 0x04000000 self.hRequest = wininet.HttpOpenRequestA(self.hConnect, "GET", url, 0, 0, 0, INTERNET_FLAG_NO_CACHE_WRITE, 0) if not self.hRequest: code = GetLastError() #gErr.log("couldn't open request: %d - %s" %(code, FormatError(code))) self.stop() return retVal #print hRequest #gDbg.log('Sending Request...') res = wininet.HttpSendRequestA(self.hRequest, 0,0,0,0) if not res: code = GetLastError() gErr.log("couldn't send request: %d - %s" %(code, FormatError(code))) self.stop() return retVal #print "Request Sent: %d", res HTTP_QUERY_FLAG_NUMBER = 0x20000000 HTTP_QUERY_CONTENT_LENGTH = 5 HTTP_QUERY_STATUS_CODE = 19 #gDbg.log('Getting Result...') if self.callback: self.callback('Getting Result...', 3) time.sleep(sleepTime) dwStatus = DWORD() dwBufLen = DWORD(4) res =wininet.HttpQueryInfoA(self.hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, byref(dwStatus), byref(dwBufLen), 0) if res == 0: code = GetLastError() #gErr.log("couldn't query info: %d - %s" %(code, FormatError(code))) dwStatus.value = 0 status = dwStatus.value #gDbg.log("Status = %d" %status) data = '' if status == 200: while 1: buff = c_buffer(8192) bytesRead = DWORD() bResult = wininet.InternetReadFile(self.hRequest, buff, 8192, byref(bytesRead)) #print "bResult: ", bResult if bytesRead.value == 0: break data = data + buff.raw[:bytesRead.value] self.stop() return (status, data)
def not_a_console(handle): if handle == INVALID_HANDLE_VALUE or handle is None: return True return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR or GetConsoleMode(handle, byref(DWORD())) == 0)
def comports(): GUIDs = (GUID*8)() # so far only seen one used, so hope 8 are enough... guids_size = DWORD() if not SetupDiClassGuidsFromName( Ports, GUIDs, ctypes.sizeof(GUIDs), ctypes.byref(guids_size)): raise ctypes.WinError() # repeat for all possible GUIDs for index in range(guids_size.value): g_hdi = SetupDiGetClassDevs( ctypes.byref(GUIDs[index]), None, NULL, DIGCF_PRESENT) # was DIGCF_PRESENT|DIGCF_DEVICEINTERFACE which misses CDC ports devinfo = SP_DEVINFO_DATA() devinfo.cbSize = ctypes.sizeof(devinfo) index = 0 while SetupDiEnumDeviceInfo(g_hdi, index, ctypes.byref(devinfo)): index += 1 # get the real com port name hkey = SetupDiOpenDevRegKey( g_hdi, ctypes.byref(devinfo), DICS_FLAG_GLOBAL, 0, DIREG_DEV, # DIREG_DRV for SW info KEY_READ) port_name_buffer = byte_buffer(250) port_name_length = ULONG(ctypes.sizeof(port_name_buffer)) RegQueryValueEx( hkey, PortName, None, None, ctypes.byref(port_name_buffer), ctypes.byref(port_name_length)) RegCloseKey(hkey) # unfortunately does this method also include parallel ports. # we could check for names starting with COM or just exclude LPT # and hope that other "unknown" names are serial ports... if string(port_name_buffer).startswith('LPT'): continue # hardware ID szHardwareID = byte_buffer(250) # try to get ID that includes serial number if not SetupDiGetDeviceInstanceId( g_hdi, ctypes.byref(devinfo), ctypes.byref(szHardwareID), ctypes.sizeof(szHardwareID) - 1, None): # fall back to more generic hardware ID if that would fail if not SetupDiGetDeviceRegistryProperty( g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None, ctypes.byref(szHardwareID), ctypes.sizeof(szHardwareID) - 1, None): # Ignore ERROR_INSUFFICIENT_BUFFER if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError() # stringify szHardwareID_str = string(szHardwareID) # in case of USB, make a more readable string, similar to that form # that we also generate on other platforms if szHardwareID_str.startswith('USB'): m = re.search(r'VID_([0-9a-f]{4})&PID_([0-9a-f]{4})(\\(\w+))?', szHardwareID_str, re.I) if m: if m.group(4): szHardwareID_str = 'USB VID:PID=%s:%s SNR=%s' % (m.group(1), m.group(2), m.group(4)) else: szHardwareID_str = 'USB VID:PID=%s:%s' % (m.group(1), m.group(2)) # friendly name szFriendlyName = byte_buffer(250) if not SetupDiGetDeviceRegistryProperty( g_hdi, ctypes.byref(devinfo), SPDRP_FRIENDLYNAME, #~ SPDRP_DEVICEDESC, None, ctypes.byref(szFriendlyName), ctypes.sizeof(szFriendlyName) - 1, None): # Ignore ERROR_INSUFFICIENT_BUFFER #~ if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER: #~ raise IOError("failed to get details for %s (%s)" % (devinfo, szHardwareID.value)) # ignore errors and still include the port in the list, friendly name will be same as port name yield string(port_name_buffer), 'n/a', szHardwareID_str else: yield string(port_name_buffer), string(szFriendlyName), szHardwareID_str SetupDiDestroyDeviceInfoList(g_hdi)
BATTERY_TYPE_WIRED = 0x01 # The device is a wired device and does not # have a battery. BATTERY_TYPE_ALKALINE = 0x02 # The device has an alkaline battery. BATTERY_TYPE_NIMH = 0x03 # The device has a nickel metal hydride battery. BATTERY_TYPE_UNKNOWN = 0xFF # The device has an unknown battery type. # BatteryLevels BATTERY_LEVEL_EMPTY = 0x00 BATTERY_LEVEL_LOW = 0x01 BATTERY_LEVEL_MEDIUM = 0x02 BATTERY_LEVEL_FULL = 0x03 # # Multiple Controller Support # XINPUT_USER_0 = DWORD(0) XINPUT_USER_1 = DWORD(1) XINPUT_USER_2 = DWORD(2) XINPUT_USER_3 = DWORD(3) XUSER_MAX_COUNT = 4 XINPUT_USERS = (XINPUT_USER_0, XINPUT_USER_1, XINPUT_USER_2, XINPUT_USER_3) XUSER_INDEX_ANY = 0x000000FF XINPUT_GAMEPAD_TL_LIT = DWORD(0) XINPUT_GAMEPAD_TR_LIT = DWORD(1) XINPUT_GAMEPAD_BR_LIT = DWORD(2) XINPUT_GAMEPAD_BL_LIT = DWORD(3) # # Codes returned for the gamepad keystroke #
def get_unicode_console(): """ Get Unicode console objects. @return: stdin, stdout, stderr, argv @rtype: tuple """ # Make Unicode console output work independently of the current code page. # This also fixes <http://bugs.python.org/issue1602>. # Credit to Michael Kaplan <http://blogs.msdn.com/b/michkap/archive/2010/04/07/9989346.aspx> # and TZOmegaTZIOY # <https://stackoverflow.com/questions/878972/windows-cmd-encoding-change-causes-python-crash/1432462#1432462>. global stdin, stdout, stderr, argv if not OSWIN32: return stdin, stdout, stderr, argv try: # <https://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx> # HANDLE WINAPI GetStdHandle(DWORD nStdHandle); # returns INVALID_HANDLE_VALUE, NULL, or a valid handle # # <https://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx> # DWORD WINAPI GetFileType(DWORD hFile); # # <https://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx> # BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode); GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle", windll.kernel32)) STD_INPUT_HANDLE = DWORD(-10) STD_OUTPUT_HANDLE = DWORD(-11) STD_ERROR_HANDLE = DWORD(-12) GetFileType = WINFUNCTYPE(DWORD, DWORD)(("GetFileType", windll.kernel32)) FILE_TYPE_CHAR = 0x0002 FILE_TYPE_REMOTE = 0x8000 GetConsoleMode = (WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))( ("GetConsoleMode", windll.kernel32))) INVALID_HANDLE_VALUE = DWORD(-1).value def not_a_console(handle): """Return whether the handle is not to a console.""" if handle == INVALID_HANDLE_VALUE or handle is None: return True return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR or GetConsoleMode(handle, byref(DWORD())) == 0) old_stdin_fileno = old_fileno('in') old_stdout_fileno = old_fileno('out') old_stderr_fileno = old_fileno('err') STDIN_FILENO = 0 STDOUT_FILENO = 1 STDERR_FILENO = 2 real_stdin = (old_stdin_fileno == STDIN_FILENO) real_stdout = (old_stdout_fileno == STDOUT_FILENO) real_stderr = (old_stderr_fileno == STDERR_FILENO) if real_stdin: hStdin = GetStdHandle(STD_INPUT_HANDLE) if not_a_console(hStdin): real_stdin = False if real_stdout: hStdout = GetStdHandle(STD_OUTPUT_HANDLE) force_truetype_console(hStdout) if not_a_console(hStdout): real_stdout = False if real_stderr: hStderr = GetStdHandle(STD_ERROR_HANDLE) force_truetype_console(hStderr) if not_a_console(hStderr): real_stderr = False if real_stdout or real_stderr: if real_stdin: stdin = UnicodeInput(hStdin, name='<Unicode console stdin>') if real_stdout: stdout = UnicodeOutput(hStdout, sys.stdout, STDOUT_FILENO, '<Unicode console stdout>') else: stdout = UnicodeOutput(None, sys.stdout, old_stdout_fileno, '<Unicode redirected stdout>') if real_stderr: stderr = UnicodeOutput(hStderr, sys.stderr, STDERR_FILENO, '<Unicode console stderr>') else: stderr = UnicodeOutput(None, sys.stderr, old_stderr_fileno, '<Unicode redirected stderr>') except Exception as e: _complain("exception %r while fixing up sys.stdout and sys.stderr" % (e, )) # While we're at it, let's unmangle the command-line arguments: # This works around <http://bugs.python.org/issue2128>. GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) CommandLineToArgvW = (WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))(("CommandLineToArgvW", windll.shell32))) argc = c_int(0) argv_unicode = CommandLineToArgvW(GetCommandLineW(), byref(argc)) argv = [argv_unicode[i].encode('utf-8') for i in range(0, argc.value)] if not hasattr(sys, 'frozen'): # If this is an executable produced by py2exe or bbfreeze, then it will # have been invoked directly. Otherwise, unicode_argv[0] is the Python # interpreter, so skip that. argv = argv[1:] # Also skip option arguments to the Python interpreter. while len(argv) > 0: arg = argv[0] if not arg.startswith(b"-") or arg == u"-": break argv = argv[1:] if arg == u'-m': # sys.argv[0] should really be the absolute path of the module source, # but never mind break if arg == u'-c': argv[0] = u'-c' break if argv == []: argv = [u''] return stdin, stdout, stderr, argv
def _get_conout_mode(): with open("CONOUT$", "w") as conout: mode = DWORD() conout_handle = get_osfhandle(conout.fileno()) kernel32.GetConsoleMode(conout_handle, byref(mode)) return mode.value
def fix_unicode_out(): #code found here: #http://stackoverflow.com/a/3259271/428751 import codecs from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int from ctypes.wintypes import BOOL, HANDLE, DWORD, LPWSTR, LPCWSTR, LPVOID original_stderr = sys.stderr # If any exception occurs in this code, we'll probably try to print it on stderr, # which makes for frustrating debugging if stderr is directed to our wrapper. # So be paranoid about catching errors and reporting them to original_stderr, # so that we can at least see them. def _complain(message): print >> original_stderr, message if isinstance(message, str) else repr(message) # Work around <http://bugs.python.org/issue6058>. codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None) # Make Unicode console output work independently of the current code page. # This also fixes <http://bugs.python.org/issue1602>. # Credit to Michael Kaplan <http://blogs.msdn.com/b/michkap/archive/2010/04/07/9989346.aspx> # and TZOmegaTZIOY # <http://stackoverflow.com/questions/878972/windows-cmd-encoding-change-causes-python-crash/1432462#1432462>. try: # <http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx> # HANDLE WINAPI GetStdHandle(DWORD nStdHandle); # returns INVALID_HANDLE_VALUE, NULL, or a valid handle # # <http://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx> # DWORD WINAPI GetFileType(DWORD hFile); # # <http://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx> # BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode); GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle", windll.kernel32)) STD_OUTPUT_HANDLE = DWORD(-11) STD_ERROR_HANDLE = DWORD(-12) GetFileType = WINFUNCTYPE(DWORD, DWORD)(("GetFileType", windll.kernel32)) FILE_TYPE_CHAR = 0x0002 FILE_TYPE_REMOTE = 0x8000 GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))( ("GetConsoleMode", windll.kernel32)) INVALID_HANDLE_VALUE = DWORD(-1).value def not_a_console(handle): if handle == INVALID_HANDLE_VALUE or handle is None: return True return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR or GetConsoleMode(handle, byref(DWORD())) == 0) old_stdout_fileno = None old_stderr_fileno = None if hasattr(sys.stdout, 'fileno'): old_stdout_fileno = sys.stdout.fileno() if hasattr(sys.stderr, 'fileno'): old_stderr_fileno = sys.stderr.fileno() STDOUT_FILENO = 1 STDERR_FILENO = 2 real_stdout = (old_stdout_fileno == STDOUT_FILENO) real_stderr = (old_stderr_fileno == STDERR_FILENO) if real_stdout: hStdout = GetStdHandle(STD_OUTPUT_HANDLE) if not_a_console(hStdout): real_stdout = False if real_stderr: hStderr = GetStdHandle(STD_ERROR_HANDLE) if not_a_console(hStderr): real_stderr = False if real_stdout or real_stderr: # BOOL WINAPI WriteConsoleW(HANDLE hOutput, LPWSTR lpBuffer, DWORD nChars, # LPDWORD lpCharsWritten, LPVOID lpReserved); WriteConsoleW = WINFUNCTYPE(BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), LPVOID)( ("WriteConsoleW", windll.kernel32)) class UnicodeOutput: def __init__(self, hConsole, stream, fileno, name): self._hConsole = hConsole self._stream = stream self._fileno = fileno self.closed = False self.softspace = False self.mode = 'w' self.encoding = 'utf-8' self.name = name self.flush() def isatty(self): return False def close(self): # don't really close the handle, that would only cause problems self.closed = True def fileno(self): return self._fileno def flush(self): if self._hConsole is None: try: self._stream.flush() except Exception as e: _complain("%s.flush: %r from %r" % (self.name, e, self._stream)) raise def write(self, text): try: if self._hConsole is None: if isinstance(text, unicode): text = text.encode('utf-8') self._stream.write(text) else: if not isinstance(text, unicode): text = str(text).decode('utf-8') remaining = len(text) while remaining: n = DWORD(0) # There is a shorter-than-documented limitation on the # length of the string passed to WriteConsoleW (see # <http://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232>. retval = WriteConsoleW(self._hConsole, text, min(remaining, 10000), byref(n), None) if retval == 0 or n.value == 0: raise IOError( "WriteConsoleW returned %r, n.value = %r" % (retval, n.value)) remaining -= n.value if not remaining: break text = text[n.value:] except Exception as e: _complain("%s.write: %r" % (self.name, e)) raise def writelines(self, lines): try: for line in lines: self.write(line) except Exception as e: _complain("%s.writelines: %r" % (self.name, e)) raise if real_stdout: sys.stdout = UnicodeOutput(hStdout, None, STDOUT_FILENO, '<Unicode console stdout>') else: sys.stdout = UnicodeOutput(None, sys.stdout, old_stdout_fileno, '<Unicode redirected stdout>') if real_stderr: sys.stderr = UnicodeOutput(hStderr, None, STDERR_FILENO, '<Unicode console stderr>') else: sys.stderr = UnicodeOutput(None, sys.stderr, old_stderr_fileno, '<Unicode redirected stderr>') except Exception as e: _complain("exception %r while fixing up sys.stdout and sys.stderr" % (e, ))
def initialize_gcrypt(required_ver): from ctypes import c_void_p from gnutls.library._init import gcrypt_thread_callbacks_ptr GCRYCTL_INIT_SECMEM = 24 GCRYCTL_SUSPEND_SECMEM_WARN = 28 GCRYCTL_RESUME_SECMEM_WARN = 29 GCRYCTL_DISABLE_SECMEM = 37 GCRYCTL_SET_THREAD_CBS = 47 GCRYCTL_INITIALIZATION_FINISHED = 38 system = get_system_name() if system == 'windows': from ctypes import CDLL, FormatError, POINTER, byref, create_unicode_buffer, c_wchar_p, sizeof, windll from ctypes.wintypes import BOOL, DWORD, HANDLE, HMODULE GetCurrentProcess = windll.kernel32.GetCurrentProcess GetCurrentProcess.argtypes = [] GetCurrentProcess.restype = HANDLE try: EnumProcessModules = windll.kernel32.EnumProcessModules except AttributeError: EnumProcessModules = windll.psapi.EnumProcessModules EnumProcessModules.argtypes = [ HANDLE, POINTER(HMODULE), DWORD, POINTER(DWORD) ] EnumProcessModules.restype = BOOL GetModuleFileName = windll.kernel32.GetModuleFileNameW GetModuleFileName.argtypes = [HMODULE, c_wchar_p, DWORD] GetModuleFileName.restype = DWORD module_handles = (HMODULE * 1024)() module_name = create_unicode_buffer(65536) needed = DWORD() if EnumProcessModules(GetCurrentProcess(), module_handles, sizeof(module_handles), byref(needed)): for i in xrange(needed.value / sizeof(HMODULE)): if GetModuleFileName( module_handles[i], module_name, len(module_name)) and 'libgcrypt' in module_name.value: libgcrypt = CDLL(module_name.value) break else: raise RuntimeError( 'cannot find libgcrypt among the loaded dlls') else: raise RuntimeError('cannot obtain the process modules: %s' % FormatError()) gcry_control = libgcrypt.gcry_control gcry_check_version = libgcrypt.gcry_check_version elif system == 'cygwin': libgcrypt = load_library(name='gcrypt', version=11) gcry_control = libgcrypt.gcry_control gcry_check_version = libgcrypt.gcry_check_version else: gcry_control = libgnutls.gcry_control gcry_check_version = libgnutls.gcry_check_version gcry_control(GCRYCTL_SET_THREAD_CBS, c_void_p(gcrypt_thread_callbacks_ptr)) if gcry_check_version(required_ver) is None: version = gcry_check_version(None) raise RuntimeError( "Found gcrypt library version %s, but at least version %s is required" % (version, required_ver)) if system == 'cygwin': gcry_control(GCRYCTL_DISABLE_SECMEM, 0) else: gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN) gcry_control(GCRYCTL_INIT_SECMEM, 32768, 0) gcry_control(GCRYCTL_RESUME_SECMEM_WARN) gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0)
def Get_TGS(hLsaConnection, dwKerberosAuthenticationPackageId, SPNentry): LPTR = (0x0000 | 0x0040) list_of_target = SPNentry["serviceprincipalname"].split(";") for target in list_of_target: szSPN = create_unicode_buffer(target.lower()) dwSPNSize = USHORT((len(target)) * sizeof(wchar_t)) dwTicketPayloadSize = DWORD( sizeof(KERB_RETRIEVE_TKT_REQUEST) + dwSPNSize.value) KerbRetrieveEncodedTicketMessage = 8 KERB_ETYPE_RC4_HMAC_NT = 23 KERB_RETRIEVE_TICKET_DONT_USE_CACHE = (0x1) dwKerbRetrieveTicketRequestAddress = windll.kernel32.LocalAlloc( LPTR, dwTicketPayloadSize.value) pKerbRetrieveTicketRequest = cast(dwKerbRetrieveTicketRequestAddress, PKERB_RETRIEVE_TKT_REQUEST) pKerbRetrieveTicketRequest.contents.MessageType = KerbRetrieveEncodedTicketMessage # current logon session context pKerbRetrieveTicketRequest.contents.LogonID = 0 # TargetName pKerbRetrieveTicketRequest.contents.TargetName.Length = USHORT( dwSPNSize.value) pKerbRetrieveTicketRequest.contents.TargetName.MaximumLength = USHORT( dwSPNSize.value + sizeof(wchar_t)) dwKerbRetrieveTicketRequestBufferAddress = dwKerbRetrieveTicketRequestAddress + sizeof( KERB_RETRIEVE_TKT_REQUEST) memmove(dwKerbRetrieveTicketRequestBufferAddress, szSPN, pKerbRetrieveTicketRequest.contents.TargetName.Length) pKerbRetrieveTicketRequest.contents.TargetName.Buffer = cast( dwKerbRetrieveTicketRequestBufferAddress, PWSTR) pKerbRetrieveTicketRequest.contents.TicketFlags = ULONG(0) pKerbRetrieveTicketRequest.contents.CacheOptions = KERB_RETRIEVE_TICKET_DONT_USE_CACHE pKerbRetrieveTicketRequest.contents.EncryptionType = KERB_ETYPE_RC4_HMAC_NT pKerbRetrieveTicketRequest.contents.CredentialsHandle = SecHandle() pKerbRetrieveTicketResponse = PVOID() pKerbRetrieveTicketResponse = cast(pKerbRetrieveTicketResponse, PKERB_RETRIEVE_TKT_RESPONSE) dwProtocolStatus = DWORD(0) status = LsaCallAuthenticationPackage( hLsaConnection, dwKerberosAuthenticationPackageId, pKerbRetrieveTicketRequest, dwTicketPayloadSize, byref(pKerbRetrieveTicketResponse), byref(dwTicketPayloadSize), byref(dwProtocolStatus)) windll.kernel32.LocalFree(pKerbRetrieveTicketRequest) if status == STATUS_SUCCESS and dwProtocolStatus.value == STATUS_SUCCESS and dwTicketPayloadSize.value != 0: pKerbRetrieveTicketResponse = cast(pKerbRetrieveTicketResponse, PKERB_RETRIEVE_TKT_RESPONSE) pEncodedTicket = pKerbRetrieveTicketResponse.contents.Ticket.EncodedTicket dwEncodedTicketSize = pKerbRetrieveTicketResponse.contents.Ticket.EncodedTicketSize Ticket = "" for i in range(dwEncodedTicketSize): Ticket += hex(pEncodedTicket[i]).replace("0x", '').zfill(2) LsaFreeReturnBuffer(pKerbRetrieveTicketResponse) return Ticket else: print " [-] Cannot retrieve ticket for account '%s' and SPN '%s', status: %s ; protocolstatus: %s" % ( SPNentry["samaccountname"], target, hex(status), hex(dwProtocolStatus.value)) print " [+] Trying the next one." print "[-] Could not retrieve any ticket for account '%s' and the list of SPN: '%s'" % ( SPNentry["samaccountname"], SPNentry["serviceprincipalname"]) return 0
def fix_unicode_on_win32(): from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int from ctypes.wintypes import BOOL, HANDLE, DWORD, LPWSTR, LPCWSTR, LPVOID original_stderr = sys.stderr # If any exception occurs in this code, we'll probably try to print it on stderr, # which makes for frustrating debugging if stderr is directed to our wrapper. # So be paranoid about catching errors and reporting them to original_stderr, # so that we can at least see them. def _complain(message): print(original_stderr, message if isinstance(message, str) else repr(message)) # Work around <http://bugs.python.org/issue6058>. codecs.register(lambda name: name == 'cp65001' and codecs.lookup('utf-8') or None) # Make Unicode console output work independently of the current code page. # This also fixes <http://bugs.python.org/issue1602>. # Credit to Michael Kaplan <http://blogs.msdn.com/b/michkap/archive/2010/04/07/9989346.aspx> # and TZOmegaTZIOY # <http://stackoverflow.com/questions/878972/windows-cmd-encoding-change-causes-python-crash/1432462#1432462>. try: # <http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx> # HANDLE WINAPI GetStdHandle(DWORD nStdHandle); # returns INVALID_HANDLE_VALUE, NULL, or a valid handle # # <http://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx> # DWORD WINAPI GetFileType(DWORD hFile); # # <http://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx> # BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode); GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle", windll.kernel32)) STD_OUTPUT_HANDLE = DWORD(-11) STD_ERROR_HANDLE = DWORD(-12) GetFileType = WINFUNCTYPE(DWORD, DWORD)(("GetFileType", windll.kernel32)) FILE_TYPE_CHAR = 0x0002 FILE_TYPE_REMOTE = 0x8000 GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))(("GetConsoleMode", windll.kernel32)) INVALID_HANDLE_VALUE = DWORD(-1).value def not_a_console(handle): if handle == INVALID_HANDLE_VALUE or handle is None: return True return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR or GetConsoleMode(handle, byref(DWORD())) == 0) old_stdout_fileno = None old_stderr_fileno = None if hasattr(sys.stdout, 'fileno'): old_stdout_fileno = sys.stdout.fileno() if hasattr(sys.stderr, 'fileno'): old_stderr_fileno = sys.stderr.fileno() STDOUT_FILENO = 1 STDERR_FILENO = 2 real_stdout = (old_stdout_fileno == STDOUT_FILENO) real_stderr = (old_stderr_fileno == STDERR_FILENO) if real_stdout: hStdout = GetStdHandle(STD_OUTPUT_HANDLE) if not_a_console(hStdout): real_stdout = False if real_stderr: hStderr = GetStdHandle(STD_ERROR_HANDLE) if not_a_console(hStderr): real_stderr = False if real_stdout or real_stderr: # BOOL WINAPI WriteConsoleW(HANDLE hOutput, LPWSTR lpBuffer, DWORD nChars, LPDWORD lpCharsWritten, LPVOID lpReserved); WriteConsoleW = WINFUNCTYPE(BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), LPVOID)(("WriteConsoleW", windll.kernel32)) class UnicodeOutput: def __init__(self, hConsole, stream, fileno, name): self._hConsole = hConsole self._stream = stream self._fileno = fileno self.closed = False self.softspace = False self.mode = 'w' self.encoding = 'utf-8' self.name = name self.flush() def isatty(self): return False def close(self): # don't really close the handle, that would only cause problems self.closed = True def fileno(self): return self._fileno def flush(self): if self._hConsole is None: try: self._stream.flush() except Exception as e: _complain("%s.flush: %r from %r" % (self.name, e, self._stream)) raise def write(self, text): try: if self._hConsole is None: if isinstance(text, unicode): text = text.encode('utf-8') self._stream.write(text) else: if not isinstance(text, unicode): text = str(text).decode('utf-8') remaining = len(text) while remaining > 0: n = DWORD(0) # There is a shorter-than-documented limitation on the # length of the string passed to WriteConsoleW (see # <http://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232>. retval = WriteConsoleW(self._hConsole, text, min(remaining, 10000), byref(n), None) if retval == 0 or n.value == 0: raise IOError("WriteConsoleW returned %r, n.value = %r" % (retval, n.value)) remaining -= n.value if remaining == 0: break text = text[n.value:] except Exception as e: _complain("%s.write: %r" % (self.name, e)) raise def writelines(self, lines): try: for line in lines: self.write(line) except Exception as e: _complain("%s.writelines: %r" % (self.name, e)) raise def __repr__(self): return self.name sys.stdout = (UnicodeOutput(hStdout, None, STDOUT_FILENO, '<Unicode console stdout>') if real_stdout else UnicodeOutput(None, sys.stdout, old_stdout_fileno, '<Unicode redirected stdout>')) sys.stderr = (UnicodeOutput(hStderr, None, STDERR_FILENO, '<Unicode console stderr>') if real_stderr else UnicodeOutput(None, sys.stderr, old_stderr_fileno, '<Unicode redirected stderr>')) except Exception as e: _complain("exception %r while fixing up sys.stdout and sys.stderr" % (e,)) if UNMANGLE_CMDLINE_ARGS: # This works around <http://bugs.python.org/issue2128>. GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))(("CommandLineToArgvW", windll.shell32)) argc = c_int(0) argv_unicode = CommandLineToArgvW(GetCommandLineW(), byref(argc)) argv = [argv_unicode[i].encode('utf-8') for i in xrange(0, argc.value)] if not hasattr(sys, 'frozen'): # If this is an executable produced by py2exe or bbfreeze, then it will # have been invoked directly. Otherwise, unicode_argv[0] is the Python # interpreter, so skip that. argv = argv[1:] # Also skip option arguments to the Python interpreter. while len(argv) > 0: arg = argv[0] if not arg.startswith(u"-") or arg == u"-": break argv = argv[1:] if arg == u'-m': # sys.argv[0] should really be the absolute path of the module source, # but never mind break if arg == u'-c': argv[0] = u'-c' break # if you like: sys.argv = argv
def inject_python(dwProcessId, port): var_size = ctypes.sizeof(ctypes.c_void_p) is_x86 = var_size == 4 if is_x86: pack = functools.partial(struct.pack, 'I') prologue = b'\x55\x89\xe5' # push ebp # mov ebp, esp epilogue = b'\x5d\xc3' # pop ebp # retn opcode_move_ptr = b'\xa3' # mov dword ptr [ptr], eax opcode_move_to_r0 = b'\xa1' # mov eax, dword ptr [x] else: pack = functools.partial(struct.pack, 'Q') prologue = b'\x48\x83\xec\x28' # sub rsp, 0x28 epilogue = b'\x48\x83\xc4\x28\xc3' # add rsp, 0x28 # ret opcode_move_ptr = b'\x48\xa3' # mov qword ptr [ptr], rax opcode_move_to_r0 = b'\x48\xa1' # mov rax, qword ptr [x] empty_variable = b'\x00' * var_size opcode_call_r0 = b'\xff\xd0' # call rax/eax hGetProcAddress = pack(GetProcAddress(GetModuleHandle(b'kernel32.dll'), b'GetProcAddress')) hLoadLibraryA = pack(GetProcAddress(GetModuleHandle(b'kernel32.dll'), b'LoadLibraryA')) kernel32 = ctypes.windll.LoadLibrary('kernel32') kernel32.GetProcAddress(b'GetProcAddress') #hProcess = get_process_handle(dwProcessId, PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE) hProcess = get_process_handle(dwProcessId, PROCESS_ALL_ACCESS) python_functions = [ 'PyRun_SimpleString', 'Py_Initialize', 'PyImport_AddModule', 'PyImport_ImportModule', 'PyObject_SetAttrString', 'Py_CompileString', 'PyModule_GetDict', 'PyEval_EvalCode', 'PyDict_New', 'Py_Finalize' ] python_functions = ['Py_SetProgramName', 'Py_Initialize', 'PyRun_SimpleString', 'Py_FinalizeEx'] data = hGetProcAddress + hLoadLibraryA lpmain_module_offset = len(data) data += empty_variable lpcode_offset = len(data) data += empty_variable lpglobal_dict_offset = len(data) data += empty_variable lplocal_dict_offset = len(data) data += empty_variable python_function_base_offset = len(data) data += empty_variable * len(python_functions) data += b'C:\\Apps\\Python\\python37.dll\x00' # Change this to the path of your python 3 DLL. data += b'\x00'.join([f.encode() for f in python_functions]) + b'\x00' #python_code = 'rpyc.utils.server.ThreadedServer(rpyc.core.SlaveService, hostname="", port=%s, reuse_addr=True, ipv6=False, authenticator=None, registrar=None, auto_register=False).start()' % port # Replace with a more verbose code if anything fails. See log file for failures. # Use a plain string, and encode (to bytes) below in misc_strings[]. python_code = r''' import sys, os with open('c:/apps/log.txt', 'w+') as log: try: import rpyc, rpyc.core, rpc.utils.server except ImportError as e: print('cannot import modules:', e, file=log) print('sys.path=' + str(sys.path), file=log) print('cwd=' + os.getcwd(), file=log) print('successfully imported rpyc, running...', file=log) try: rpyc.utils.server.ThreadedServer(rpyc.core.SlaveService, hostname="", port={port}, reuse_addr=True, ipv6=False, authenticator=None, registrar=None, auto_register=False).start() except Exception as e: print('could not start server:', str(e), file=log) '''.format(port=port) misc_strings = [ b'__main__', b'rpyc', b'rpyc.core', b'rpyc.utils.server', b'injection', python_code.encode() ] data += b'\x00'.join(misc_strings) + b'\x00' data += r'C:\Apps\Python\python.exe'.encode('utf-16le') + b'\x00\x00' # Change this to your python3 exe. lpDataBufferLocal = ctypes.create_string_buffer(data) lpDataBufferRemote = allocate_and_write(hProcess, 0, len(lpDataBufferLocal), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE, lpDataBufferLocal) code = b'' func_address_map = {} def get_data_address(x): return pack(lpDataBufferRemote + data.index(x)) def call_function(x): return opcode_move_to_r0 + func_address_map[x] + opcode_call_r0 def move_r0_to_address(x): return opcode_move_ptr + x if is_x86: opcode_push_r0 = b'\x50' # push rax/eax arg0_reg0 = arg1_reg0 = arg2_reg0 = opcode_push_r0 opcode_push_ptr = b'\xff\x35' # push dword ptr [x] def arg0_pointer(x): return opcode_push_ptr + x arg1_pointer = arg2_pointer = arg0_pointer opcode_push_imm = b'\x68' # push x def arg0_imm(x): return opcode_push_imm + pack(x) arg1_imm = arg2_imm = arg0_imm def arg0_data_address(x): return opcode_push_imm + get_data_address(x) arg1_data_address = arg2_data_address = arg0_data_address else: arg0_reg0 = b'\x48\x89\xc1' arg1_reg0 = b'\x48\x89\xc2' arg2_reg0 = b'\x49\x89\xc0' def arg0_pointer(x): return opcode_move_to_r0 + x + arg0_reg0 def arg1_pointer(x): return opcode_move_to_r0 + x + arg1_reg0 def arg2_pointer(x): return opcode_move_to_r0 + x + arg2_reg0 opcode_move_imm_to_r1 = b'\x48\xb9' def arg0_imm(x): return opcode_move_imm_to_r1 + pack(x) opcode_move_imm_to_r2 = b'\x48\xba' def arg1_imm(x): return opcode_move_imm_to_r2 + pack(x) opcode_move_imm_to_r8 = b'\x49\xb8' def arg2_imm(x): return opcode_move_imm_to_r8 + pack(x) def arg0_data_address(x): return opcode_move_imm_to_r1 + get_data_address(x) def arg1_data_address(x): return opcode_move_imm_to_r2 + get_data_address(x) def arg2_data_address(x): return opcode_move_imm_to_r8 + get_data_address(x) callGetProcAddress = opcode_move_to_r0 + get_data_address(hGetProcAddress) + opcode_call_r0 callLoadLibraryA = opcode_move_to_r0 + get_data_address(hLoadLibraryA) + opcode_call_r0 lpmain_module = pack(lpDataBufferRemote + lpmain_module_offset) lpcode = pack(lpDataBufferRemote + lpcode_offset) lpglobal_dict = pack(lpDataBufferRemote + lpglobal_dict_offset) lplocal_dict = pack(lpDataBufferRemote + lplocal_dict_offset) code += prologue for i, function in enumerate(python_functions): address = pack(lpDataBufferRemote + python_function_base_offset + (i*var_size)) func_address_map[function] = address # GetProcProcess(LoadLibrary('python37.dll'), function) code += arg0_data_address(b'C:\\Apps\\Python\\python37.dll') + callLoadLibraryA + \ arg1_data_address(function.encode()) + arg0_reg0 + callGetProcAddress + \ move_r0_to_address(address) #code += b'\xcc' # For debugging under a debugger (attach to target process!) code += arg0_data_address(r'C:\Apps'.encode('utf-16le')) + call_function('Py_SetProgramName') # Py_Initialize(); code += call_function('Py_Initialize') code += arg0_data_address(b'import sys') + call_function('PyRun_SimpleString') # No need for all the code below; we just use the very convenient PyRun_SimpleString. # main_module = PyImport_AddModule("__main__"); """ code += arg0_data_address(b'__main__') + call_function('PyImport_AddModule') + \ move_r0_to_address(lpmain_module) # PyImport_ImportModule("rpyc.core"); code += arg0_data_address(b'rpyc.core') + call_function('PyImport_ImportModule') # PyImport_ImportModule("rpyc.utils.server"); code += arg0_data_address(b'rpyc.utils.server') + call_function('PyImport_ImportModule') # PyObject_SetAttrString(main_module, "rpyc", PyImport_ImportModule("rpyc")); code += arg0_data_address(b'rpyc') + call_function('PyImport_ImportModule') code += arg2_reg0 + arg1_data_address(b'rpyc') + arg0_pointer(lpmain_module) + \ call_function('PyObject_SetAttrString') # code = Py_CompileString("rpyc.utils.server.ThreadedServer(rpyc.core.SlaveService, hostname=\"\", port=%s, reuse_addr=True, ipv6=False, authenticator=None, registrar=None, auto_register=False).start()", "injection", Py_file_input); code += arg2_imm(0x00000100) + arg1_data_address(b'injection') + \ arg0_data_address(b'rpyc.utils.server.ThreadedServer(rpyc.core.SlaveService') + \ call_function('Py_CompileString') + move_r0_to_address(lpcode) # global_dict = PyModule_GetDict(main_module); code += arg0_pointer(lpmain_module) + call_function('PyModule_GetDict') + \ move_r0_to_address(lpglobal_dict) # local_dict = PyDict_New(); code += call_function('PyDict_New') + move_r0_to_address(lplocal_dict) # PyEval_EvalCode(code, global_dict, local_dict); code += arg2_pointer(lplocal_dict) + arg1_pointer(lpglobal_dict) + \ arg0_pointer(lpcode) + call_function('PyEval_EvalCode') """ # Realistically, we will never make it here (unless the initial code above fails for some reason..) # Py_Finalize(); code += call_function('Py_FinalizeEx') code += epilogue lpCodeBufferLocal = ctypes.create_string_buffer(code) lpCodeBufferRemote = allocate_and_write(hProcess, 0, len(lpCodeBufferLocal), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE, lpCodeBufferLocal) thread_id = DWORD() create_thread(hProcess, lpCodeBufferRemote, lpThreadId=LPDWORD(thread_id)) return thread_id
def __init__(self, mode="both", redirect_ports=(80, 443), custom_filter=None, proxy_addr=False, proxy_port=8080, api_host="localhost", api_port=PROXY_API_PORT, cache_size=65536): """ :param mode: Redirection operation mode: "forward" to only redirect forwarded packets, "local" to only redirect packets originating from the local machine, "both" to redirect both. :param redirect_ports: if the destination port is in this tuple, the requests are redirected to the proxy. :param custom_filter: specify a custom WinDivert filter to select packets that should be intercepted. Overrides redirect_ports setting. :param proxy_addr: IP address of the proxy (IP within a network, 127.0.0.1 does not work). By default, this is detected automatically. :param proxy_port: Port the proxy is listenting on. :param api_host: Host the forward module API is listening on. :param api_port: Port the forward module API is listening on. :param cache_size: Maximum number of connection tuples that are stored. Only relevant in very high load scenarios. """ if proxy_port in redirect_ports: raise ValueError("The proxy port must not be a redirect port.") if not proxy_addr: # Auto-Detect local IP. # https://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) proxy_addr = s.getsockname()[0] s.close() self.mode = mode self.proxy_addr, self.proxy_port = proxy_addr, proxy_port self.connection_cache_size = cache_size self.client_server_map = OrderedDict() self.api = APIServer(self, (api_host, api_port), APIRequestHandler) self.api_thread = threading.Thread(target=self.api.serve_forever) self.api_thread.daemon = True self.driver = WinDivert() self.driver.register() self.request_filter = custom_filter or " or ".join( ("tcp.DstPort == %d" % p) for p in redirect_ports) self.request_forward_handle = None self.request_forward_thread = threading.Thread( target=self.request_forward) self.request_forward_thread.daemon = True self.addr_pid_map = dict() self.trusted_pids = set() self.tcptable2 = MIB_TCPTABLE2(0) self.tcptable2_size = DWORD(0) self.request_local_handle = None self.request_local_thread = threading.Thread(target=self.request_local) self.request_local_thread.daemon = True # The proxy server responds to the client. To the client, # this response should look like it has been sent by the real target self.response_filter = "outbound and tcp.SrcPort == %d" % proxy_port self.response_handle = None self.response_thread = threading.Thread(target=self.response) self.response_thread.daemon = True self.icmp_handle = None
def _windows_write_string(s, out): """ Returns True if the string was written using special methods, False if it has yet to be written out.""" # Adapted from http://stackoverflow.com/a/3259271/35070 # https://github.com/ytdl-org/youtube-dl/issues/15758 from ctypes import byref, POINTER, windll, WINFUNCTYPE from ctypes.wintypes import BOOL, DWORD, HANDLE, LPWSTR, LPVOID FILE_TYPE_CHAR = 0x0002 FILE_TYPE_REMOTE = 0x8000 ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 GetStdHandle = compat_ctypes_WINFUNCTYPE(HANDLE, DWORD)( ('GetStdHandle', windll.kernel32)) GetFileType = compat_ctypes_WINFUNCTYPE(DWORD, HANDLE)( ('GetFileType', windll.kernel32)) GetConsoleMode = compat_ctypes_WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))( ('GetConsoleMode', windll.kernel32)) SetConsoleMode = compat_ctypes_WINFUNCTYPE(BOOL, HANDLE, DWORD)( ('SetConsoleMode', windll.kernel32)) WriteConsoleW = compat_ctypes_WINFUNCTYPE(BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), LPVOID)(('WriteConsoleW', windll.kernel32)) try: fileno = out.fileno() except AttributeError: # If the output stream doesn't have a fileno, it's virtual return False except io.UnsupportedOperation: # Some strange Windows pseudo files? return False if fileno == 1: h = GetStdHandle(-11) elif fileno == 2: h = GetStdHandle(-12) else: return False if h is None or h == HANDLE(-1): return False if (GetFileType(h) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR: return False mode = DWORD() if not GetConsoleMode(h, byref(mode)): return False if (mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0: SetConsoleMode(h, mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) def next_nonbmp_pos(s): try: return next(i for i, c in enumerate(s) if ord(c) > 0xffff) except StopIteration: return len(s) written = DWORD(0) while s: count = min(next_nonbmp_pos(s), 1024) ret = WriteConsoleW(h, s, count if count else 2, byref(written), None) if ret == 0: raise OSError('Failed to write string') if not count: # We just wrote a non-BMP character assert written.value == 2 s = s[1:] else: assert written.value > 0 s = s[written.value:] return True
def win32_unicode_console(): import codecs from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int from ctypes.wintypes import BOOL, HANDLE, DWORD, LPWSTR, LPCWSTR, LPVOID original_stderr = sys.stderr # Output exceptions in this code to original_stderr, so that we can at least see them def _complain(message): original_stderr.write( message if isinstance(message, str) else repr(message)) original_stderr.write('\n') codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None) try: GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle", windll.kernel32)) STD_OUTPUT_HANDLE = DWORD(-11) STD_ERROR_HANDLE = DWORD(-12) GetFileType = WINFUNCTYPE(DWORD, DWORD)(("GetFileType", windll.kernel32)) FILE_TYPE_CHAR = 0x0002 FILE_TYPE_REMOTE = 0x8000 GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))( ("GetConsoleMode", windll.kernel32)) INVALID_HANDLE_VALUE = DWORD(-1).value def not_a_console(handle): if handle == INVALID_HANDLE_VALUE or handle is None: return True return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR or GetConsoleMode(handle, byref(DWORD())) == 0) old_stdout_fileno = None old_stderr_fileno = None if hasattr(sys.stdout, 'fileno'): old_stdout_fileno = sys.stdout.fileno() if hasattr(sys.stderr, 'fileno'): old_stderr_fileno = sys.stderr.fileno() STDOUT_FILENO = 1 STDERR_FILENO = 2 real_stdout = (old_stdout_fileno == STDOUT_FILENO) real_stderr = (old_stderr_fileno == STDERR_FILENO) if real_stdout: hStdout = GetStdHandle(STD_OUTPUT_HANDLE) if not_a_console(hStdout): real_stdout = False if real_stderr: hStderr = GetStdHandle(STD_ERROR_HANDLE) if not_a_console(hStderr): real_stderr = False if real_stdout or real_stderr: WriteConsoleW = WINFUNCTYPE(BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), LPVOID)( ("WriteConsoleW", windll.kernel32)) class UnicodeOutput: def __init__(self, hConsole, stream, fileno, name): self._hConsole = hConsole self._stream = stream self._fileno = fileno self.closed = False self.softspace = False self.mode = 'w' self.encoding = 'utf-8' self.name = name self.flush() def isatty(self): return False def close(self): # don't really close the handle, that would only cause problems self.closed = True def fileno(self): return self._fileno def flush(self): if self._hConsole is None: try: self._stream.flush() except Exception as e: _complain("%s.flush: %r from %r" % (self.name, e, self._stream)) raise def write(self, text): try: if self._hConsole is None: if not PY3K and isinstance(text, unicode): text = text.encode('utf-8') elif PY3K and isinstance(text, str): text = text.encode('utf-8') self._stream.write(text) else: if not PY3K and not isinstance(text, unicode): text = str(text).decode('utf-8') elif PY3K and not isinstance(text, str): text = text.decode('utf-8') remaining = len(text) while remaining: n = DWORD(0) # There is a shorter-than-documented limitation on the # length of the string passed to WriteConsoleW (see # <http://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232>. retval = WriteConsoleW(self._hConsole, text, min(remaining, 10000), byref(n), None) if retval == 0 or n.value == 0: raise IOError( "WriteConsoleW returned %r, n.value = %r" % (retval, n.value)) remaining -= n.value if not remaining: break text = text[n.value:] except Exception as e: _complain("%s.write: %r" % (self.name, e)) raise def writelines(self, lines): try: for line in lines: self.write(line) except Exception as e: _complain("%s.writelines: %r" % (self.name, e)) raise if real_stdout: sys.stdout = UnicodeOutput(hStdout, None, STDOUT_FILENO, '<Unicode console stdout>') else: sys.stdout = UnicodeOutput(None, sys.stdout, old_stdout_fileno, '<Unicode redirected stdout>') if real_stderr: sys.stderr = UnicodeOutput(hStderr, None, STDERR_FILENO, '<Unicode console stderr>') else: sys.stderr = UnicodeOutput(None, sys.stderr, old_stderr_fileno, '<Unicode redirected stderr>') except Exception as e: _complain("exception %r while fixing up sys.stdout and sys.stderr" % (e, ))
def doUrlStatus(self, url, host, headers={}, user=0, password=0,port=80): wininet = windll.wininet flags = DWORD() self.lock.acquire() self.hInternet = wininet.InternetOpenA('wapt-get/1.0', 0, 0, 0, 0); self.lock.release() if not self.hInternet: #gErr.log("couldn't open") self.stop() return 0 #print hInternet #print "Doing Connect" #gDbg.log('Connecting...') if self.callback: self.callback('Connecting...', 1) time.sleep(sleepTime) INTERNET_SERVICE_HTTP = 3 self.hConnect = wininet.InternetConnectA(self.hInternet, host, port, user, password, 3, 0, 0) if not self.hConnect: #gErr.log("couldn't connect") self.stop() return 0 #print hConnect #gDbg.log('Opening Request...') if self.callback: self.callback('Sending...', 2) time.sleep(sleepTime) INTERNET_FLAG_NO_CACHE_WRITE = 0x04000000 #hRequest = wininet.InternetOpenUrlA(hInternet, "http://rpc.bloglines.com/listsubs", 0, 0, 0x80000200L, 0) self.hRequest = wininet.HttpOpenRequestA(self.hConnect, "GET", url, 0, 0, 0, INTERNET_FLAG_NO_CACHE_WRITE, 0) if not self.hRequest: #gErr.log("couldn't open request") self.stop() return 0 HTTP_ADDREQ_FLAG_ADD_IF_NEW = 0x10000000 HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA = 0x40000000 HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON = 0x01000000 HTTP_ADDREQ_FLAG_COALESCE = HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA HTTP_ADDREQ_FLAG_ADD = 0x20000000 HTTP_ADDREQ_FLAG_REPLACE = 0x80000000 for k in headers.keys(): res = wininet.HttpAddRequestHeadersA(self.hRequest, "%s: %s\r\n" %(k, headers[k]), -1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD) if not res: code = GetLastError() #gErr.log("couldn't add header: %d - %s" %(code, FormatError(code))) self.stop() return retVal gDbg.log('Sending Request...') res = wininet.HttpSendRequestA(self.hRequest, 0,0,0,0) if not res: #gErr.log("couldn't send request") self.stop() return 0 #print "Request Sent: %d", res HTTP_QUERY_FLAG_NUMBER = 0x20000000 HTTP_QUERY_CONTENT_LENGTH = 5 HTTP_QUERY_STATUS_CODE = 19 #gDbg.log('Getting Result...') if self.callback: self.callback('Getting Result...', 3) time.sleep(sleepTime) dwStatus = DWORD() dwBufLen = DWORD(4) res =wininet.HttpQueryInfoA(self.hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, byref(dwStatus), byref(dwBufLen), 0) if res == 0: #gErr.log("Bad HttpQueryInfo") #print "HttpQueryInfo failed" dwStatus.value = 0 status = dwStatus.value #gDbg.log("Status = %d" %status) self.stop() return status
def _find_modules_with_enum_process_module_ex(prefixes, user_api): """Loop through loaded libraries and return binders on supported ones This function is expected to work on windows system only. This code is adapted from code by Philipp Hagemeister @phihag available at https://stackoverflow.com/questions/17474574 """ from ctypes.wintypes import DWORD, HMODULE, MAX_PATH PROCESS_QUERY_INFORMATION = 0x0400 PROCESS_VM_READ = 0x0010 LIST_MODULES_ALL = 0x03 ps_api = _get_windll('Psapi') kernel_32 = _get_windll('kernel32') h_process = kernel_32.OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, False, os.getpid()) if not h_process: # pragma: no cover raise OSError('Could not open PID %s' % os.getpid()) _modules = [] try: buf_count = 256 needed = DWORD() # Grow the buffer until it becomes large enough to hold all the # module headers while True: buf = (HMODULE * buf_count)() buf_size = ctypes.sizeof(buf) if not ps_api.EnumProcessModulesEx(h_process, ctypes.byref(buf), buf_size, ctypes.byref(needed), LIST_MODULES_ALL): raise OSError('EnumProcessModulesEx failed') if buf_size >= needed.value: break buf_count = needed.value // (buf_size // buf_count) count = needed.value // (buf_size // buf_count) h_modules = map(HMODULE, buf[:count]) # Loop through all the module headers and get the module path buf = ctypes.create_unicode_buffer(MAX_PATH) n_size = DWORD() for h_module in h_modules: # Get the path of the current module if not ps_api.GetModuleFileNameExW(h_process, h_module, ctypes.byref(buf), ctypes.byref(n_size)): raise OSError('GetModuleFileNameEx failed') filepath = buf.value # Store the module in cls_thread_locals._module if it is # supported and selected _get_module_info_from_path(filepath, prefixes, user_api, _modules) finally: kernel_32.CloseHandle(h_process) return _modules
Name = None # ignored for PRINTER_ENUM_LOCAL Level = 1 # or 2, 4, 5 class PRINTER_INFO_1(ctypes.Structure): _fields_ = [ ("Flags", DWORD), ("pDescription", LPCWSTR), ("pName", LPCWSTR), ("pComment", LPCWSTR), ] # Invoke once with a NULL pointer to get buffer size. info = ctypes.POINTER(BYTE)() pcbNeeded = DWORD(0) pcReturned = DWORD(0) # the number of PRINTER_INFO_1 structures retrieved winspool.EnumPrintersW(PRINTER_ENUM_LOCAL, Name, Level, ctypes.byref(info), 0, ctypes.byref(pcbNeeded), ctypes.byref(pcReturned)) bufsize = pcbNeeded.value buffer = msvcrt.malloc(bufsize) winspool.EnumPrintersW(PRINTER_ENUM_LOCAL, Name, Level, buffer, bufsize, ctypes.byref(pcbNeeded), ctypes.byref(pcReturned)) info = ctypes.cast(buffer, ctypes.POINTER(PRINTER_INFO_1)) printerNames = [] for i in range(pcReturned.value): printerNames.append(info[i].pName) msvcrt.free(buffer)
if os.name == "nt": class Break(Exception): pass try: from ctypes import byref, windll from ctypes.wintypes import DWORD, HANDLE kernel32 = windll.kernel32 h = kernel32.GetStdHandle(-11) # stdout if h is None or h == HANDLE(-1): raise Break() FILE_TYPE_CHAR = 0x0002 if (kernel32.GetFileType(h) & 3) != FILE_TYPE_CHAR: raise Break() mode = DWORD() kernel32.GetConsoleMode(h, byref(mode)) ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 if (mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0: kernel32.SetConsoleMode( h, mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) except Break: pass def truncate_int32(value): """ Truncate the given value so it can be stored in exactly 4 bytes. The sign will be kept. Too high or too low values will be cut off, not clamped to the valid range.
from ctypes.wintypes import BOOL, DWORD, LONG, HANDLE, ULARGE_INTEGER from ctypes.wintypes import LPSTR, LPWSTR, LPCSTR, LPCWSTR from .. import windll, nonzero from .minwinbase import LPSECURITY_ATTRIBUTES, LPOVERLAPPED from ..shared.ntdef import ULONGLONG from ..shared.minwindef import FILETIME CREATE_NEW = 1 CREATE_ALWAYS = 2 OPEN_EXISTING = 3 OPEN_ALWAYS = 4 TRUNCATE_EXISTING = 5 INVALID_FILE_SIZE = 0xFFFFFFFF INVALID_SET_FILE_POINTER = DWORD(-1) INVALID_FILE_ATTRIBUTES = DWORD(-1) class DISK_SPACE_INFORMATION(Structure): _fields_ = [ ("ActualTotalAllocationUnits", ULONGLONG), ("ActualAvailableAllocationUnits", ULONGLONG), ("ActualPoolUnavailableAllocationUnits", ULONGLONG), ("CallerTotalAllocationUnits", ULONGLONG), ("CallerAvailableAllocationUnits", ULONGLONG), ("CallerPoolUnavailableAllocationUnits", ULONGLONG), ("UsedAllocationUnits", ULONGLONG), ("TotalReservedAllocationUnits", ULONGLONG), ("VolumeStorageReserveAllocationUnits", ULONGLONG), ("AvailableCommittedAllocationUnits", ULONGLONG),
def enable_ansi_colors_win10(): import ctypes # Function factory for errcheck callbacks that raise WinError on failure. def raise_if(error_result): def check(result, _func, args): if result == error_result: raise ctypes.WinError(ctypes.get_last_error()) return args return check # Windows API types. from ctypes.wintypes import BOOL, DWORD, HANDLE, LPCWSTR, LPVOID LPDWORD = ctypes.POINTER(DWORD) # Generic constants. NULL = ctypes.c_void_p(0).value INVALID_HANDLE_VALUE = ctypes.c_void_p(-1).value ERROR_INVALID_PARAMETER = 87 # CreateFile flags. # yapf: disable GENERIC_READ = 0x80000000 GENERIC_WRITE = 0x40000000 FILE_SHARE_READ = 0x01 FILE_SHARE_WRITE = 0x02 OPEN_EXISTING = 3 # yapf: enable # Get/SetConsoleMode flags. ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x04 kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) # HANDLE CreateFileW(...) CreateFileW = kernel32.CreateFileW CreateFileW.restype = HANDLE CreateFileW.errcheck = raise_if(INVALID_HANDLE_VALUE) # yapf: disable CreateFileW.argtypes = (LPCWSTR, # lpFileName DWORD, # dwDesiredAccess DWORD, # dwShareMode LPVOID, # lpSecurityAttributes DWORD, # dwCreationDisposition DWORD, # dwFlagsAndAttributes HANDLE) # hTemplateFile # yapf: enable # BOOL CloseHandle(HANDLE hObject) CloseHandle = kernel32.CloseHandle CloseHandle.restype = BOOL CloseHandle.errcheck = raise_if(False) CloseHandle.argtypes = (HANDLE, ) # BOOL GetConsoleMode(HANDLE hConsoleHandle, LPDWORD lpMode) GetConsoleMode = kernel32.GetConsoleMode GetConsoleMode.restype = BOOL GetConsoleMode.errcheck = raise_if(False) GetConsoleMode.argtypes = (HANDLE, LPDWORD) # BOOL SetConsoleMode(HANDLE hConsoleHandle, DWORD dwMode) SetConsoleMode = kernel32.SetConsoleMode SetConsoleMode.restype = BOOL SetConsoleMode.errcheck = raise_if(False) SetConsoleMode.argtypes = (HANDLE, DWORD) # Open the console output device. conout = CreateFileW("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0) # Get the current mode. mode = DWORD() GetConsoleMode(conout, ctypes.byref(mode)) # Try to set the flag that controls ANSI escape code support. try: SetConsoleMode(conout, mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) except WindowsError as e: # pylint:disable=undefined-variable if e.winerror == ERROR_INVALID_PARAMETER: return False # Not supported, likely an older version of Windows. raise finally: CloseHandle(conout) return True
def connect(self): result = ConnectNamedPipe( self.__pipe_handle, ctypes.byref(self.__client_overlap) ) err = GetLastError() if result: pass elif err == ERROR_IO_PENDING: self.__debug('waiting for connection') result = GetOverlappedResult( self.__pipe_handle, ctypes.byref(self.__client_overlap), ctypes.byref(DWORD(0)), True ) err = GetLastError() if not result: try: raise PipeError(err) except PipeError: LOGGING.error(traceback.format_exc()) self.reconnect() return elif err == ERROR_PIPE_CONNECTED: pass elif err: raise PipeError(err) self.has_client = True self.__debug('client connected') client_process_id = ULONG(0) client_session_id = ULONG(0) server_process_id = ULONG(0) server_session_id = ULONG(0) GetNamedPipeClientProcessId( self.__pipe_handle, ctypes.byref(client_process_id) ) GetNamedPipeClientSessionId( self.__pipe_handle, ctypes.byref(client_session_id) ) GetNamedPipeServerProcessId( self.__pipe_handle, ctypes.byref(server_process_id) ) GetNamedPipeServerSessionId( self.__pipe_handle, ctypes.byref(server_session_id) ) self.__debug('client process id: {0}', client_process_id.value) self.__debug('client session id: {0}', client_session_id.value) self.__debug('server process id: {0}', server_process_id.value) self.__debug('server session id: {0}', server_session_id.value) self.__reset_read() self.__read() self.__client_wait.set()
def __enter__(self): self.handle = HANDLE() name = LPCSTR(self.printer_name) if not OpenPrinterA(name, pointer(self.handle), None): raise Exception("failed to open printer %s" % self.printer_name) log("OpenPrinter: handle=%#x", self.handle.value) size = DWORD(0) GetPrinterA(self.handle, 1, None, 0, pointer(size)) if size.value == 0: raise Exception("GetPrinterA PRINTER_INFO_1 failed for '%s'" % self.printer_name) log("GetPrinter: PRINTER_INFO_1 size=%#x", size.value) self.info1 = msvcrt.malloc(size.value) if not GetPrinterA(self.handle, 1, self.info1, size.value, pointer(size)): raise Exception("GetPrinterA PRINTER_INFO_1 failed for '%s'" % self.printer_name) info = cast(self.info1, POINTER(PRINTER_INFO_1)) log(" flags=%#x" % info[0].Flags) log(" name=%#s" % info[0].pName) log(" description=%s" % info[0].pDescription) log(" comment=%s" % info[0].pComment) size = DWORD(0) GetPrinterA(self.handle, 2, None, 0, pointer(size)) if size.value == 0: raise Exception("GetPrinterA PRINTER_INFO_2 failed for '%s'" % self.printer_name) log("GetPrinter: PRINTER_INFO_2 size=%#x", size.value) self.info2 = msvcrt.malloc(size.value) if GetPrinterA(self.handle, 2, self.info2, size.value, pointer(size)): info = cast(self.info2, POINTER(PRINTER_INFO_2)) log(" driver=%#s" % info[0].pDriverName) size = DWORD(0) GetPrinterA(self.handle, 8, None, 0, pointer(size)) if size.value == 0: raise Exception("GetPrinter: PRINTER_INFO_8 failed for '%s'" % self.printer_name) self.info8 = msvcrt.malloc(size.value) if GetPrinterA(self.handle, 8, self.info8, size.value, pointer(size)): info = cast(self.info8, POINTER(PRINTER_INFO_8)) if info[0] and info[0].pDevMode: devmode = cast(info[0].pDevMode, POINTER(DEVMODE)) log("PRINTER_INFO_8: devmode=%s" % devmode) log("PRINTER_INFO_8: device name='%s'" % devmode[0].dmDeviceName) size = DWORD(0) GetPrinterA(self.handle, 9, None, 0, pointer(size)) if size.value == 0: raise Exception("GetPrinter: PRINTER_INFO_9 failed for '%s'" % self.printer_name) log("GetPrinter: PRINTER_INFO_9 size=%#x" % size.value) self.info9 = msvcrt.malloc(size.value) if GetPrinterA(self.handle, 9, self.info9, size.value, pointer(size)): info = cast(self.info9, POINTER(PRINTER_INFO_9)) if info[0] and info[0].pDevMode: devmode = cast(info[0].pDevMode, POINTER(DEVMODE)) log("PRINTER_INFO_9: devmode=%s" % devmode) log("PRINTER_INFO_9: device name=%s" % devmode[0].dmDeviceName) assert devmode, "failed to query a DEVMODE for %s" % self.printer_name self.hdc = CreateDCA(None, name, None, devmode) log("CreateDCA(..)=%#x", self.hdc) return self.hdc
def open(self): if self.__pipe_handle is not None: raise PipeError('Client has already been opened.') self.__read_queue = queue.Queue() pipe_name = _create_pipe_name(self.__pipe_name) LOGGING.debug('CLIENT: opening {0}'.format(self.__pipe_name)) while True: self.__pipe_handle = CreateFile( pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL ) err = GetLastError() if err == ERROR_PIPE_BUSY: pass elif self.__pipe_handle != INVALID_HANDLE_VALUE: break elif not WaitNamedPipe(pipe_name, 2000): CloseHandle(self.__pipe_handle) self.__pipe_handle = None raise PipeError(err) self.__debug('pipe {0} opened', self.__pipe_name) client_process_id = ULONG(0) client_session_id = ULONG(0) server_process_id = ULONG(0) server_session_id = ULONG(0) GetNamedPipeClientProcessId( self.__pipe_handle, ctypes.byref(client_process_id) ) GetNamedPipeClientSessionId( self.__pipe_handle, ctypes.byref(client_session_id) ) GetNamedPipeServerProcessId( self.__pipe_handle, ctypes.byref(server_process_id) ) GetNamedPipeServerSessionId( self.__pipe_handle, ctypes.byref(server_session_id) ) self.__debug('client process id: {0}', client_process_id.value) self.__debug('client session id: {0}', client_session_id.value) self.__debug('server process id: {0}', server_process_id.value) self.__debug('server session id: {0}', server_session_id.value) self.__debug('setting pipe handle state') pipe_mode = DWORD(PIPE_READMODE_MESSAGE) result = SetNamedPipeHandleState( self.__pipe_handle, ctypes.byref(pipe_mode), NULL, NULL ) if not result: err = GetLastError() CloseHandle(self.__pipe_handle) raise PipeError(err) self.__debug('IO thread start') self.__lock = threading.RLock() self.__io_event = threading.Event() self.__io_read = threading.Thread( name='Client Pipe {0} Read Worker'.format(str(self.__pipe_handle)), target=self.__read_loop ) self.__io_read.daemon = True self.__io_read.start()
# and TZOmegaTZIOY # <https://stackoverflow.com/questions/878972/windows-cmd-encoding-change-causes-python-crash/1432462#1432462>. try: # <https://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx> # HANDLE WINAPI GetStdHandle(DWORD nStdHandle); # returns INVALID_HANDLE_VALUE, NULL, or a valid handle # # <https://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx> # DWORD WINAPI GetFileType(DWORD hFile); # # <https://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx> # BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode); GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle", windll.kernel32)) STD_INPUT_HANDLE = DWORD(-10) STD_OUTPUT_HANDLE = DWORD(-11) STD_ERROR_HANDLE = DWORD(-12) GetFileType = WINFUNCTYPE(DWORD, DWORD)(("GetFileType", windll.kernel32)) FILE_TYPE_CHAR = 0x0002 FILE_TYPE_REMOTE = 0x8000 GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))( ("GetConsoleMode", windll.kernel32)) INVALID_HANDLE_VALUE = DWORD(-1).value def not_a_console(handle): if handle == INVALID_HANDLE_VALUE or handle is None: return True return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR or GetConsoleMode(handle, byref(DWORD())) == 0)
def GetProductInfo(dwOSMajorVersion=5, dwOSMinorVersion=0, dwSpMajorVersion=0, dwSpMinorVersion=0): product_type = DWORD(0) from xpra.platform.win32.common import GetProductInfo as k32GetProductInfo v = k32GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion, dwSpMinorVersion, byref(product_type)) log("GetProductInfo(%i, %i, %i, %i)=%i product_type=%s", dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion, dwSpMinorVersion, v, hex(product_type.value)) return bool(v)
def initialize(): global done import sys if sys.platform != "win32" or done: return True done = True import codecs, re from ctypes import WINFUNCTYPE, WinError, windll, POINTER, byref, c_int, get_last_error from ctypes.wintypes import BOOL, HANDLE, DWORD, UINT, LPWSTR, LPCWSTR, LPVOID from allmydata.util import log from allmydata.util.encodingutil import canonical_encoding # <https://msdn.microsoft.com/en-us/library/ms680621%28VS.85%29.aspx> SetErrorMode = WINFUNCTYPE( UINT, UINT, use_last_error=True )(("SetErrorMode", windll.kernel32)) SEM_FAILCRITICALERRORS = 0x0001 SEM_NOOPENFILEERRORBOX = 0x8000 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX) original_stderr = sys.stderr # If any exception occurs in this code, we'll probably try to print it on stderr, # which makes for frustrating debugging if stderr is directed to our wrapper. # So be paranoid about catching errors and reporting them to original_stderr, # so that we can at least see them. def _complain(message): print >>original_stderr, isinstance(message, str) and message or repr(message) log.msg(message, level=log.WEIRD) # Work around <http://bugs.python.org/issue6058>. codecs.register(lambda name: name == 'cp65001' and codecs.lookup('utf-8') or None) # Make Unicode console output work independently of the current code page. # This also fixes <http://bugs.python.org/issue1602>. # Credit to Michael Kaplan <https://blogs.msdn.com/b/michkap/archive/2010/04/07/9989346.aspx> # and TZOmegaTZIOY # <http://stackoverflow.com/questions/878972/windows-cmd-encoding-change-causes-python-crash/1432462#1432462>. try: # <https://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx> # HANDLE WINAPI GetStdHandle(DWORD nStdHandle); # returns INVALID_HANDLE_VALUE, NULL, or a valid handle # # <https://msdn.microsoft.com/en-us/library/aa364960(VS.85).aspx> # DWORD WINAPI GetFileType(DWORD hFile); # # <https://msdn.microsoft.com/en-us/library/ms683167(VS.85).aspx> # BOOL WINAPI GetConsoleMode(HANDLE hConsole, LPDWORD lpMode); GetStdHandle = WINFUNCTYPE( HANDLE, DWORD, use_last_error=True )(("GetStdHandle", windll.kernel32)) STD_OUTPUT_HANDLE = DWORD(-11) STD_ERROR_HANDLE = DWORD(-12) GetFileType = WINFUNCTYPE( DWORD, DWORD, use_last_error=True )(("GetFileType", windll.kernel32)) FILE_TYPE_CHAR = 0x0002 FILE_TYPE_REMOTE = 0x8000 GetConsoleMode = WINFUNCTYPE( BOOL, HANDLE, POINTER(DWORD), use_last_error=True )(("GetConsoleMode", windll.kernel32)) INVALID_HANDLE_VALUE = DWORD(-1).value def not_a_console(handle): if handle == INVALID_HANDLE_VALUE or handle is None: return True return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR or GetConsoleMode(handle, byref(DWORD())) == 0) old_stdout_fileno = None old_stderr_fileno = None if hasattr(sys.stdout, 'fileno'): old_stdout_fileno = sys.stdout.fileno() if hasattr(sys.stderr, 'fileno'): old_stderr_fileno = sys.stderr.fileno() STDOUT_FILENO = 1 STDERR_FILENO = 2 real_stdout = (old_stdout_fileno == STDOUT_FILENO) real_stderr = (old_stderr_fileno == STDERR_FILENO) if real_stdout: hStdout = GetStdHandle(STD_OUTPUT_HANDLE) if not_a_console(hStdout): real_stdout = False if real_stderr: hStderr = GetStdHandle(STD_ERROR_HANDLE) if not_a_console(hStderr): real_stderr = False if real_stdout or real_stderr: # <https://msdn.microsoft.com/en-us/library/windows/desktop/ms687401%28v=vs.85%29.aspx> # BOOL WINAPI WriteConsoleW(HANDLE hOutput, LPWSTR lpBuffer, DWORD nChars, # LPDWORD lpCharsWritten, LPVOID lpReserved); WriteConsoleW = WINFUNCTYPE( BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), LPVOID, use_last_error=True )(("WriteConsoleW", windll.kernel32)) class UnicodeOutput: def __init__(self, hConsole, stream, fileno, name): self._hConsole = hConsole self._stream = stream self._fileno = fileno self.closed = False self.softspace = False self.mode = 'w' self.encoding = 'utf-8' self.name = name if hasattr(stream, 'encoding') and canonical_encoding(stream.encoding) != 'utf-8': log.msg("%s: %r had encoding %r, but we're going to write UTF-8 to it" % (name, stream, stream.encoding), level=log.CURIOUS) self.flush() def isatty(self): return False def close(self): # don't really close the handle, that would only cause problems self.closed = True def fileno(self): return self._fileno def flush(self): if self._hConsole is None: try: self._stream.flush() except Exception, e: _complain("%s.flush: %r from %r" % (self.name, e, self._stream)) raise def write(self, text): try: if self._hConsole is None: if isinstance(text, unicode): text = text.encode('utf-8') self._stream.write(text) else: if not isinstance(text, unicode): text = str(text).decode('utf-8') remaining = len(text) while remaining > 0: n = DWORD(0) # There is a shorter-than-documented limitation on the length of the string # passed to WriteConsoleW (see #1232). retval = WriteConsoleW(self._hConsole, text, min(remaining, 10000), byref(n), None) if retval == 0: raise IOError("WriteConsoleW failed with WinError: %s" % (WinError(get_last_error()),)) if n.value == 0: raise IOError("WriteConsoleW returned %r, n.value = 0" % (retval,)) remaining -= n.value if remaining == 0: break text = text[n.value:] except Exception, e: _complain("%s.write: %r" % (self.name, e)) raise def writelines(self, lines): try: for line in lines: self.write(line) except Exception, e: _complain("%s.writelines: %r" % (self.name, e)) raise
def comports(): """This generator scans the device registry for com ports and yields port, desc, hwid""" g_hdi = SetupDiGetClassDevs(ctypes.byref(GUID_CLASS_COMPORT), None, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE) #~ for i in range(256): for dwIndex in range(256): did = SP_DEVICE_INTERFACE_DATA() did.cbSize = ctypes.sizeof(did) if not SetupDiEnumDeviceInterfaces( g_hdi, None, ctypes.byref(GUID_CLASS_COMPORT), dwIndex, ctypes.byref(did)): if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS: raise ctypes.WinError() break dwNeeded = DWORD() # get the size if not SetupDiGetDeviceInterfaceDetail(g_hdi, ctypes.byref(did), None, 0, ctypes.byref(dwNeeded), None): # Ignore ERROR_INSUFFICIENT_BUFFER if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError() # allocate buffer class SP_DEVICE_INTERFACE_DETAIL_DATA_A(ctypes.Structure): _fields_ = [ ('cbSize', DWORD), ('DevicePath', CHAR * (dwNeeded.value - ctypes.sizeof(DWORD))), ] def __str__(self): return "DevicePath:%s" % (self.DevicePath, ) idd = SP_DEVICE_INTERFACE_DETAIL_DATA_A() if is_64bit(): idd.cbSize = 8 else: idd.cbSize = 5 devinfo = SP_DEVINFO_DATA() devinfo.cbSize = ctypes.sizeof(devinfo) if not SetupDiGetDeviceInterfaceDetail( g_hdi, ctypes.byref(did), ctypes.byref(idd), dwNeeded, None, ctypes.byref(devinfo)): raise ctypes.WinError() # hardware ID szHardwareID = byte_buffer(250) if not SetupDiGetDeviceRegistryProperty( g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None, ctypes.byref(szHardwareID), ctypes.sizeof(szHardwareID) - 1, None): # Ignore ERROR_INSUFFICIENT_BUFFER if GetLastError() != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError() # friendly name szFriendlyName = byte_buffer(250) if SetupDiGetDeviceRegistryProperty(g_hdi, ctypes.byref(devinfo), SPDRP_FRIENDLYNAME, None, ctypes.byref(szFriendlyName), ctypes.sizeof(szFriendlyName) - 1, None): # the real com port name has to read differently... hkey = SetupDiOpenDevRegKey(g_hdi, ctypes.byref(devinfo), DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ) port_name_buffer = byte_buffer(250) port_name_length = ULONG(ctypes.sizeof(port_name_buffer)) RegQueryValueEx(hkey, PortName, None, None, ctypes.byref(port_name_buffer), ctypes.byref(port_name_length)) RegCloseKey(hkey) yield string(port_name_buffer), string(szFriendlyName), string( szHardwareID) SetupDiDestroyDeviceInfoList(g_hdi)
def iterate_comports(): """Return a generator that yields descriptions for serial ports""" GUIDs = (GUID * 8)() # so far only seen one used, so hope 8 are enough... guids_size = DWORD() if not SetupDiClassGuidsFromName("Ports", GUIDs, ctypes.sizeof(GUIDs), ctypes.byref(guids_size)): raise ctypes.WinError() # repeat for all possible GUIDs for index in range(guids_size.value): g_hdi = SetupDiGetClassDevs( ctypes.byref(GUIDs[index]), None, NULL, DIGCF_PRESENT ) # was DIGCF_PRESENT|DIGCF_DEVICEINTERFACE which misses CDC ports devinfo = SP_DEVINFO_DATA() devinfo.cbSize = ctypes.sizeof(devinfo) index = 0 while SetupDiEnumDeviceInfo(g_hdi, index, ctypes.byref(devinfo)): index += 1 # get the real com port name hkey = SetupDiOpenDevRegKey( g_hdi, ctypes.byref(devinfo), DICS_FLAG_GLOBAL, 0, DIREG_DEV, # DIREG_DRV for SW info KEY_READ) port_name_buffer = ctypes.create_unicode_buffer(250) port_name_length = ULONG(ctypes.sizeof(port_name_buffer)) RegQueryValueEx(hkey, "PortName", None, None, ctypes.byref(port_name_buffer), ctypes.byref(port_name_length)) RegCloseKey(hkey) # unfortunately does this method also include parallel ports. # we could check for names starting with COM or just exclude LPT # and hope that other "unknown" names are serial ports... if port_name_buffer.value.startswith('LPT'): continue # hardware ID szHardwareID = ctypes.create_unicode_buffer(250) # try to get ID that includes serial number if not SetupDiGetDeviceInstanceId( g_hdi, ctypes.byref(devinfo), #~ ctypes.byref(szHardwareID), szHardwareID, ctypes.sizeof(szHardwareID) - 1, None): # fall back to more generic hardware ID if that would fail if not SetupDiGetDeviceRegistryProperty( g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None, ctypes.byref(szHardwareID), ctypes.sizeof(szHardwareID) - 1, None): # Ignore ERROR_INSUFFICIENT_BUFFER if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError() # stringify szHardwareID_str = szHardwareID.value info = list_ports_common.ListPortInfo(port_name_buffer.value) # in case of USB, make a more readable string, similar to that form # that we also generate on other platforms if szHardwareID_str.startswith('USB'): m = re.search( r'VID_([0-9a-f]{4})(&PID_([0-9a-f]{4}))?(\\(\w+))?', szHardwareID_str, re.I) if m: info.vid = int(m.group(1), 16) if m.group(3): info.pid = int(m.group(3), 16) if m.group(5): info.serial_number = m.group(5) # calculate a location string loc_path_str = ctypes.create_unicode_buffer(250) if SetupDiGetDeviceRegistryProperty( g_hdi, ctypes.byref(devinfo), SPDRP_LOCATION_PATHS, None, ctypes.byref(loc_path_str), ctypes.sizeof(loc_path_str) - 1, None): m = re.finditer(r'USBROOT\((\w+)\)|#USB\((\w+)\)', loc_path_str.value) location = [] for g in m: if g.group(1): location.append('{:d}'.format(int(g.group(1)) + 1)) else: if len(location) > 1: location.append('.') else: location.append('-') location.append(g.group(2)) if location: info.location = ''.join(location) info.hwid = info.usb_info() elif szHardwareID_str.startswith('FTDIBUS'): m = re.search( r'VID_([0-9a-f]{4})\+PID_([0-9a-f]{4})(\+(\w+))?', szHardwareID_str, re.I) if m: info.vid = int(m.group(1), 16) info.pid = int(m.group(2), 16) if m.group(4): info.serial_number = m.group(4) # USB location is hidden by FDTI driver :( info.hwid = info.usb_info() else: info.hwid = szHardwareID_str # friendly name szFriendlyName = ctypes.create_unicode_buffer(250) if SetupDiGetDeviceRegistryProperty( g_hdi, ctypes.byref(devinfo), SPDRP_FRIENDLYNAME, #~ SPDRP_DEVICEDESC, None, ctypes.byref(szFriendlyName), ctypes.sizeof(szFriendlyName) - 1, None): info.description = szFriendlyName.value #~ else: # Ignore ERROR_INSUFFICIENT_BUFFER #~ if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER: #~ raise IOError("failed to get details for %s (%s)" % (devinfo, szHardwareID.value)) # ignore errors and still include the port in the list, friendly name will be same as port name # manufacturer szManufacturer = ctypes.create_unicode_buffer(250) if SetupDiGetDeviceRegistryProperty( g_hdi, ctypes.byref(devinfo), SPDRP_MFG, #~ SPDRP_DEVICEDESC, None, ctypes.byref(szManufacturer), ctypes.sizeof(szManufacturer) - 1, None): info.manufacturer = szManufacturer.value yield info SetupDiDestroyDeviceInfoList(g_hdi)
def GetWindowsVersionString(): system_info = SYSTEM_INFO() osvi = OSVERSIONINFOEX() osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX) windll.kernel32.GetVersionExW(byref(osvi)) try: MyGetSystemInfo = windll.kernel32.GetNativeSystemInfo except AttributeError: MyGetSystemInfo = windll.kernel32.GetSystemInfo MyGetSystemInfo(byref(system_info)) name = "" major_version = osvi.dwMajorVersion minor_version = osvi.dwMinorVersion if major_version == 5: suiteMask = osvi.wSuiteMask if minor_version == 0: if osvi.wProductType == VER_NT_WORKSTATION: name = "2000 Professional" else: if suiteMask & VER_SUITE_DATACENTER: name = "2000 Datacenter Server" elif suiteMask & VER_SUITE_ENTERPRISE: name = "2000 Advanced Server" else: name = "2000 Server" elif minor_version == 1: if GetSystemMetrics(SM_MEDIACENTER): name = "XP Media Center Edition" elif GetSystemMetrics(SM_TABLETPC): name = "XP Tablet PC Edition" elif GetSystemMetrics(SM_STARTER): name = "XP Starter Edition" elif suiteMask & VER_SUITE_PERSONAL: name = "XP Home Edition" else: name = "XP Professional" elif minor_version == 2: if GetSystemMetrics(SM_SERVERR2): name = "Server 2003 R2" elif suiteMask == VER_SUITE_STORAGE_SERVER: name = "Storage Server 2003" elif suiteMask == VER_SUITE_WH_SERVER: name = "Home Server" elif osvi.wProductType == VER_NT_WORKSTATION: # Windows XP Professional x64 Edition name = "XP Professional" else: name = "Server 2003" if osvi.wProductType != VER_NT_WORKSTATION: if suiteMask & VER_SUITE_COMPUTE_SERVER: name += " Compute Cluster Edition" elif suiteMask & VER_SUITE_DATACENTER: name += " Datacenter Edition" elif suiteMask & VER_SUITE_ENTERPRISE: name += " Enterprise Edition" elif suiteMask & VER_SUITE_BLADE: name += " Web Edition" else: name += " Standard Edition" elif major_version >= 6: try: os_type = { (6, 0, True): "Vista", (6, 0, False): "Server 2008", (6, 1, True): "7", (6, 1, False): "Server 2008 R2", (6, 2, True): "8", (6, 2, False): "Server 2012", (6, 3, True): "8.1", (6, 3, False): "Server 2012 R2", (10, 0, True): "10", (10, 0, False): "Server 2016", }[( major_version, minor_version, osvi.wProductType == VER_NT_WORKSTATION, )] except KeyError: os_type = "Unknown OS %d.%d" % (major_version, minor_version) dwType = DWORD() windll.kernel32.GetProductInfo(major_version, minor_version, 0, 0, byref(dwType)) try: name = EDITIONS[dwType.value] % os_type except KeyError: name = "%s (Unknown Edition %d)" % (os_type, dwType.value) if osvi.wServicePackMajor: name += " SP%d" % osvi.wServicePackMajor if osvi.wServicePackMinor: name += ".%d" % osvi.wServicePackMinor if system_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64: name += ", 64-bit" elif system_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64: name += ", Itanium" else: name += ", 32-bit" name += " (build %d)" % osvi.dwBuildNumber return "Microsoft Windows " + name
def doUrlPost(self, url, host, postData, headers = {}, user=0, password=0): wininet = windll.wininet flags = DWORD() data = '' retVal = (0, data) # Use the Registry settings for Proxy (nice!) INTERNET_OPEN_TYPE_PRECONFIG = 0 self.lock.acquire() self.hInternet = wininet.InternetOpenA('Blogbot/1.0 (http://blogbot.com/)', INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0); self.lock.release() if not self.hInternet: code = GetLastError() gErr.log("couldn't open: %d - %s" %(code, FormatError(code))) self.stop() return retVal #print hInternet #print "Doing Connect" gDbg.log('Connecting...') if self.callback: self.callback('Conecting...', 1) time.sleep(sleepTime) INTERNET_SERVICE_HTTP = 3 INTERNET_INVALID_PORT_NUMBER = 0 self.hConnect = wininet.InternetConnectA(self.hInternet, host, INTERNET_INVALID_PORT_NUMBER, user, password, INTERNET_SERVICE_HTTP, 0, 0) if not self.hConnect: code = GetLastError() gErr.log("couldn't connect: %d - %s" %(code, FormatError(code))) self.stop() return retVal #print hConnect gDbg.log('Opening Request...') if self.callback: self.callback('Sending...', 2) time.sleep(sleepTime) INTERNET_FLAG_NO_CACHE_WRITE = 0x04000000 #hRequest = wininet.InternetOpenUrlA(hInternet, "http://rpc.bloglines.com/listsubs", 0, 0, 0x80000200L, 0) self.hRequest = wininet.HttpOpenRequestA(self.hConnect, "POST", url, 0, 0, 0, INTERNET_FLAG_NO_CACHE_WRITE, 0) if not self.hRequest: code = GetLastError() gErr.log("couldn't open request: %d - %s" %(code, FormatError(code))) self.stop() return retVal #print hRequest HTTP_ADDREQ_FLAG_ADD_IF_NEW = 0x10000000 HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA = 0x40000000 HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON = 0x01000000 HTTP_ADDREQ_FLAG_COALESCE = HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA HTTP_ADDREQ_FLAG_ADD = 0x20000000 HTTP_ADDREQ_FLAG_REPLACE = 0x80000000 for k in headers.keys(): res = wininet.HttpAddRequestHeadersA(self.hRequest, "%s: %s\r\n" %(k, headers[k]), -1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD) if not res: code = GetLastError() gErr.log("couldn't add header: %d - %s" %(code, FormatError(code))) self.stop() return retVal gDbg.log('Sending Request...') res = wininet.HttpSendRequestA(self.hRequest, 0,0,postData,len(postData)) if not res: code = GetLastError() gErr.log("couldn't send request: %d - %s" %(code, FormatError(code))) self.stop() return retVal #print "Request Sent: %d", res HTTP_QUERY_FLAG_NUMBER = 0x20000000 HTTP_QUERY_CONTENT_LENGTH = 5 HTTP_QUERY_STATUS_CODE = 19 gDbg.log('Getting Result...') if self.callback: self.callback('Getting Result...', 3) time.sleep(sleepTime) dwStatus = DWORD() dwBufLen = DWORD(4) res =wininet.HttpQueryInfoA(self.hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, byref(dwStatus), byref(dwBufLen), 0) if res == 0: code = GetLastError() gErr.log("couldn't query info: %d - %s" %(code, FormatError(code))) dwStatus.value = 0 status = dwStatus.value gDbg.log("Status = %d" %status) data = '' if (status / 100) == 2: while 1: buff = c_buffer(8192) bytesRead = DWORD() bResult = wininet.InternetReadFile(self.hRequest, buff, 8192, byref(bytesRead)) #print "bResult: ", bResult if bytesRead.value == 0: break data = data + buff.raw[:bytesRead.value] self.stop() return (status, data)
def listComPorts(onlyAvailable=True): """List com ports on the system. @param onlyAvailable: Only return ports that are currently available. @type onlyAvailable: bool @return: Generates dicts including keys of port, friendlyName and hardwareID. @rtype: generator of (str, str, str) """ flags = DIGCF_DEVICEINTERFACE if onlyAvailable: flags |= DIGCF_PRESENT buf = ctypes.create_unicode_buffer(1024) g_hdi = SetupDiGetClassDevs(ctypes.byref(GUID_CLASS_COMPORT), None, NULL, flags) try: for dwIndex in xrange(256): entry = {} did = SP_DEVICE_INTERFACE_DATA() did.cbSize = ctypes.sizeof(did) if not SetupDiEnumDeviceInterfaces( g_hdi, None, ctypes.byref(GUID_CLASS_COMPORT), dwIndex, ctypes.byref(did) ): if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS: raise ctypes.WinError() break dwNeeded = DWORD() # get the size if not SetupDiGetDeviceInterfaceDetail( g_hdi, ctypes.byref(did), None, 0, ctypes.byref(dwNeeded), None ): # Ignore ERROR_INSUFFICIENT_BUFFER if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError() # allocate buffer class SP_DEVICE_INTERFACE_DETAIL_DATA_W(ctypes.Structure): _fields_ = ( ('cbSize', DWORD), ('DevicePath', WCHAR*(dwNeeded.value - ctypes.sizeof(DWORD))), ) def __str__(self): return "DevicePath:%s" % (self.DevicePath,) idd = SP_DEVICE_INTERFACE_DETAIL_DATA_W() idd.cbSize = SIZEOF_SP_DEVICE_INTERFACE_DETAIL_DATA_W devinfo = SP_DEVINFO_DATA() devinfo.cbSize = ctypes.sizeof(devinfo) if not SetupDiGetDeviceInterfaceDetail( g_hdi, ctypes.byref(did), ctypes.byref(idd), dwNeeded, None, ctypes.byref(devinfo) ): raise ctypes.WinError() # hardware ID if not SetupDiGetDeviceRegistryProperty( g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None, ctypes.byref(buf), ctypes.sizeof(buf) - 1, None ): # Ignore ERROR_INSUFFICIENT_BUFFER if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError() else: hwID = entry["hardwareID"] = buf.value regKey = ctypes.windll.setupapi.SetupDiOpenDevRegKey(g_hdi, ctypes.byref(devinfo), DICS_FLAG_GLOBAL, 0, DIREG_DEV, winreg.KEY_READ) port = entry["port"] = winreg.QueryValueEx(regKey, "PortName")[0] if hwID.startswith("BTHENUM\\"): # This is a Microsoft bluetooth port. try: addr = winreg.QueryValueEx(regKey, "Bluetooth_UniqueID")[0].split("#", 1)[1].split("_", 1)[0] addr = int(addr, 16) entry["bluetoothAddress"] = addr if addr: entry["bluetoothName"] = getBluetoothDeviceInfo(addr).szName except: pass elif hwID == r"Bluetooth\0004&0002": # This is a Toshiba bluetooth port. try: entry["bluetoothAddress"], entry["bluetoothName"] = getToshibaBluetoothPortInfo(port) except: pass ctypes.windll.advapi32.RegCloseKey(regKey) # friendly name if not SetupDiGetDeviceRegistryProperty( g_hdi, ctypes.byref(devinfo), SPDRP_FRIENDLYNAME, None, ctypes.byref(buf), ctypes.sizeof(buf) - 1, None ): # Ignore ERROR_INSUFFICIENT_BUFFER if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError() else: entry["friendlyName"] = buf.value yield entry finally: SetupDiDestroyDeviceInfoList(g_hdi)
def enum_cb(hwnd, results): if win32gui.IsWindowVisible(hwnd) and win32gui.GetWindowText(hwnd) != '': dwmapi.DwmGetWindowAttribute(HWND(hwnd), DWORD(DWMWA_CLOAKED), ctypes.byref(isCloacked), ctypes.sizeof(isCloacked)) if (isCloacked.value == 0): results.append((hwnd, win32gui.GetWindowText(hwnd)))
GetCurrentProcess.restype = HANDLE OpenProcessToken = ctypes.windll.kernel32.OpenProcessToken OpenProcessToken.argtypes = (HANDLE, DWORD, PHANDLE) OpenProcessToken.restype = BOOL CloseHandle = ctypes.windll.kernel32.CloseHandle CloseHandle.argtypes = (HANDLE, ) CloseHandle.restype = BOOL GetTokenInformation = ctypes.windll.Advapi32.GetTokenInformation GetTokenInformation.argtypes = (HANDLE, ctypes.c_int, ctypes.c_void_p, DWORD, PDWORD) GetTokenInformation.restype = BOOL exit_code = DWORD() TOKEN_READ = 0x20008 TokenElevation = 0x14 class ShellExecuteInfo(ctypes.Structure): _fields_ = [('cbSize', DWORD), ('fMask', c_ulong), ('hwnd', HWND), ('lpVerb', c_char_p), ('lpFile', c_char_p), ('lpParameters', c_char_p), ('lpDirectory', c_char_p), ('nShow', c_int), ('hInstApp', HINSTANCE), ('lpIDList', c_void_p), ('lpClass', c_char_p), ('hKeyClass', HKEY), ('dwHotKey', DWORD), ('hIcon', HANDLE), ('hProcess', HANDLE)] def __init__(self, **kw):