def get_device_interface(i, device=None): interfaceData = SP_DEVICE_INTERFACE_DATA() interfaceData.cbSize = ctypes.sizeof(SP_DEVICE_INTERFACE_DATA) if SetupDiEnumDeviceInterfaces( hDevInfo, device and ctypes.byref(device) or None, ctypes.byref(current_guid), i, ctypes.byref(interfaceData)): return interfaceData elif ctypes.GetLastError() == ERROR_NO_MORE_ITEMS: return else: warn('get_device_interface', ctypes.GetLastError(), ctypes.FormatError())
def inet_pton(address_family, ip_string): addr = sockaddr() addr.sa_family = address_family addr_size = ctypes.c_int(ctypes.sizeof(addr)) if WSAStringToAddressA(ip_string.encode("UTF-8"), address_family, None, ctypes.byref(addr), ctypes.byref(addr_size)) != 0: raise socket.error(ctypes.FormatError()) if address_family == socket.AF_INET: return ctypes.string_at(addr.ipv4_addr, 4) if address_family == socket.AF_INET6: return ctypes.string_at(addr.ipv6_addr, 16) raise socket.error('unknown address family')
def open(self): """ Open device to query properties :return: context """ handle = _setupapi.SetupDiCreateDeviceInfoList(None, None) if handle == -1: err_no = ctypes.GetLastError() raise WindowsError(err_no, ctypes.FormatError(err_no)) try: dev_info = DeviceInfoData() if not _setupapi.SetupDiOpenDeviceInfoW( handle, ctypes.create_unicode_buffer(self._instance_id), None, DIOD_INHERIT_CLASSDRVS, ctypes.byref(dev_info)): err_no = ctypes.GetLastError() raise WindowsError(err_no, ctypes.FormatError(err_no)) self._handle = (handle, dev_info, self._handle) # Stack yield self finally: if self._handle is not None and \ self._handle[0] == handle: # If last handle is opened in this function, pop it self._handle = self._handle[2] _setupapi.SetupDiDestroyDeviceInfoList(handle) # Close handle
def win_service_main(service_name, real_main, argc, argv_raw): try: # args = [argv_raw[i].value for i in range(argc)] stop_event = threading.Event() handler = HandlerEx(functools.partial(stop_event, win_service_handler)) h = advapi32.RegisterServiceCtrlHandlerExW(service_name, handler, None) if not h: raise OSError('Handler registration failed: %s' % ctypes.FormatError()) TODO except Exception as e: tb = traceback.format_exc() msg = str(e) + '\n' + tb win_service_report_event(service_name, msg, is_error=True) raise
def win_service_start(service_name, real_main): try: cb = START_CALLBACK( functools.partial(win_service_main, service_name, real_main)) dispatch_table = _ctypes_array(SERVICE_TABLE_ENTRY, [ SERVICE_TABLE_ENTRY(service_name, cb), SERVICE_TABLE_ENTRY(None, ctypes.cast(None, START_CALLBACK)) ]) if not advapi32.StartServiceCtrlDispatcherW(dispatch_table): raise OSError('ctypes start failed: %s' % ctypes.FormatError()) except Exception as e: tb = traceback.format_exc() msg = str(e) + '\n' + tb win_service_report_event(service_name, msg, is_error=True) raise
def get_device_interface_detail(interface): detail = None size = 0 length = ctypes.wintypes.DWORD(0) device = SP_DEVINFO_DATA(cbSize=ctypes.sizeof(SP_DEVINFO_DATA)) while not SetupDiGetDeviceInterfaceDetail( hDevInfo, ctypes.byref(interface), detail and ctypes.byref(detail) or None, size, ctypes.byref(length), ctypes.byref(device)): if ctypes.GetLastError() == ERROR_INSUFFICIENT_BUFFER: size = length.value detail = SP_DEVICE_INTERFACE_DETAIL_DATA(cbSize=6) else: warn('get_device_interface_detail', ctypes.GetLastError(), ctypes.FormatError()) return return detail.DevicePath, device
def get_property(self, key): """ Get device property. See SetupDiGetDeviceProperty from MSDN :param key: Key of property :return: Property value """ if self._handle is None: # If the device is not opened yet, with self.open(): # Open and retry return self.get_property(key) handle, dev_info, _ = self._handle prop_type = ctypes.c_ulong() required_size = ctypes.c_ulong() value = None if isinstance(key, DevicePropertyKey ): # If given key is an instance of DEVPROPKEY key_ = ctypes.byref(key) # Property query function is SetupDiGetDeviceProperty get_property_ = _setupapi.SetupDiGetDevicePropertyW else: raise TypeError( "Key must be DevPropKey instance, but {} given".format(key)) # To retrieve buffer size. if not get_property_(handle, ctypes.byref(dev_info), key_, ctypes.byref(prop_type), None, 0, ctypes.byref(required_size), 0): err_no = ctypes.GetLastError() if err_no == 122: # ERROR_INSUFFICIENT_BUFFER value_buffer = ctypes.create_string_buffer(required_size.value) if get_property_(handle, ctypes.byref(dev_info), key_, ctypes.byref(prop_type), ctypes.byref(value_buffer), required_size.value, ctypes.byref(required_size), 0): # Parse property value with retrieved property type value = Property(bytes(value_buffer), prop_type.value) err_no = ctypes.GetLastError() if err_no == 1168: # ERROR_NOT_FOUND: Attribute is not exist raise AttributeError(key) if err_no != 0: raise WindowsError(err_no, ctypes.FormatError(err_no)) return value
def _get_win32_uuid(self): """ Rather than use WNI which requires the win32 extensions we use raw ctypes and call the GetSystemFirmwareTable (http://msdn.microsoft.com/en-us/library/ms724379%28VS.85%29.aspx) function and then parse the raw SMBIOS table to the UUID. """ ##1381190978 == 'RSMB' FirmwareTableSig = ord('R') FirmwareTableSig = FirmwareTableSig << 8 | ord("S") FirmwareTableSig = FirmwareTableSig << 8 | ord("M") FirmwareTableSig = FirmwareTableSig << 8 | ord("B") kernel32 = ctypes.windll.kernel32 if kernel32 == None: raise GetUUIDError("cant load kernel32.dll") ##The function get_fw = kernel32.GetSystemFirmwareTable ##Get the size of the SMBIOS so we can allocate correctly bios_size = get_fw(ctypes.wintypes.DWORD(1381190978), 0, 0, 0) ##Buffer for BIOS to be written to FirmwareTableBuf = ctypes.create_string_buffer(b"\000" * bios_size) ##Now actually dump the Raw SMBIOS table ret = get_fw(ctypes.wintypes.DWORD(FirmwareTableSig), 0, FirmwareTableBuf, 0x1eba) if ctypes.GetLastError() != 0: raise GetUUIDError(ctypes.FormatError(ctypes.GetLastError())) ##Remove the 8 byte header MS seems to append SMBIOSTableData = FirmwareTableBuf.raw[8:] ##Now parse the SMBIOS table parse_bios = ParseSMBIOSTable(SMBIOSTableData) parse_bios() ##Format the UUID into the standard string repr raw_uuid = parse_bios.type1_data["UUID"] self.uuid = "%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x" % ( raw_uuid[0], raw_uuid[1], raw_uuid[2], raw_uuid[3], raw_uuid[4], raw_uuid[5], raw_uuid[6], raw_uuid[7], raw_uuid[8], raw_uuid[9], raw_uuid[10], raw_uuid[11], raw_uuid[12], raw_uuid[13], raw_uuid[14], raw_uuid[15])
def set_window_size(self, width, height): """ Change Windows console size. """ logging.debug('*** setting window size') # get current window size object window_size = SMALL_RECT(0, 0, 0, 0) # buffer info has maximum window size data buf_info = self.get_buffer_info() logging.debug(str(buf_info.to_str())) # set top left corner window_size.Top = 0 window_size.Left = 0 # set bottom right corner if buf_info.dwMaximumWindowSize.X < width: logging.debug( str(buf_info.dwMaximumWindowSize.X) + '<' + str(width)) window_size.Right = buf_info.dwMaximumWindowSize.X - 1 else: window_size.Right = width - 1 if buf_info.dwMaximumWindowSize.Y < height: logging.debug('b') window_size.Bottom = buf_info.dwMaximumWindowSize.Y - 1 else: window_size.Bottom = height - 1 logging.debug('window size: ' + str(window_size.to_str())) # set the window size! res = ctypes.windll.kernel32.SetConsoleWindowInfo( self.stdout, ctypes.c_bool(True), ctypes.byref(window_size)) logging.debug('win size result') logging.debug(str(res)) logging.debug(str(ctypes.GetLastError())) logging.debug(str(ctypes.FormatError(ctypes.GetLastError()))) # reread buffer info to get final console max lines buf_info = self.get_buffer_info() logging.debug('buffer size: ' + str(buf_info)) self.window_width = buf_info.srWindow.Right + 1 self.window_height = buf_info.srWindow.Bottom + 1
def elevate(params): hwnd = 0 # parent window lpOperation = 'runas' # force elevated UAC prompt lpFile = sys.executable # path to python lpFile = lpFile.replace( 'pythonw.exe', 'python.exe') # force console python, only way to see messages lpParameters = params # arguments to pass to python lpDirectory = tempfile.gettempdir() # working dir nShowCmd = 1 # window visibility, must be 1 for Leo. print(lpFile, lpParameters) #g.es(lpFile, lpParameters) retcode = ctypes.windll.shell32.ShellExecuteW(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd) msg = 'Exit code: {0} - {1}'.format(retcode, ctypes.FormatError(retcode)) print(msg)
def GetProcessImageFileName(handle): image_file_name = ctypes.create_unicode_buffer( wintypes.MAX_PATH ) string_length = psapi.GetProcessImageFileNameW( handle, image_file_name, len(image_file_name) ) if string_length == 0: err_no = kernel32.GetLastError() if err_no != 0: err = WindowsError( err_no, ctypes.FormatError(err_no) ) raise err return image_file_name.value
def inet_ntop(address_family, packed_ip): addr = sockaddr() addr.sa_family = address_family addr_size = ctypes.c_int(ctypes.sizeof(addr)) ip_string = ctypes.create_string_buffer(128) ip_string_size = ctypes.c_int(ctypes.sizeof(addr)) if address_family == socket.AF_INET: if len(packed_ip) != ctypes.sizeof(addr.ipv4_addr): raise socket.error('packed IP wrong length for inet_ntoa') ctypes.memmove(addr.ipv4_addr, packed_ip, 4) elif address_family == socket.AF_INET6: if len(packed_ip) != ctypes.sizeof(addr.ipv6_addr): raise socket.error('packed IP wrong length for inet_ntoa') ctypes.memmove(addr.ipv6_addr, packed_ip, 16) else: raise socket.error('unknown address family') if WSAAddressToStringA(ctypes.byref(addr), addr_size, None, ip_string, ctypes.byref(ip_string_size)) != 0: raise socket.error(ctypes.FormatError()) return ip_string[:ip_string_size.value]
def inet_pton(address_family, ip_string): if PY2 and isinstance(ip_string, unicode): # Add unicode input compatible ip_string = ip_string.encode('ascii') addr = sockaddr() addr.sa_family = address_family addr_size = ctypes.c_int(ctypes.sizeof(addr)) if WSAStringToAddressA(ip_string, address_family, None, ctypes.byref(addr), ctypes.byref(addr_size)) != 0: raise ValueError(ctypes.FormatError()) if address_family == socket.AF_INET: return ctypes.string_at(addr.ipv4_addr, 4) if address_family == socket.AF_INET6: return ctypes.string_at(addr.ipv6_addr, 16) raise ValueError('unknown address family')
def _inet_pton_win(address_family, ip_string): """ Window specific version of `inet_pton` based on: https://gist.github.com/nnemkin/4966028 """ addr = Sockaddr() addr.sa_family = address_family addr_size = ctypes.c_int(ctypes.sizeof(addr)) str_to_addr = ctypes.windll.ws2_32.WSAStringToAddressA if str_to_addr(ip_string, address_family, None, ctypes.byref(addr), ctypes.byref(addr_size)) != 0: raise socket.error(ctypes.FormatError()) if address_family == socket.AF_INET: return ctypes.string_at(addr.ipv4_addr, 4) if address_family == socket.AF_INET6: return ctypes.string_at(addr.ipv6_addr, 16) raise socket.error('unknown address family')
def by_pid(pid, access=PROCESS_ALL_ACCESS): process_handle = kernel32.OpenProcess( access, False, pid ) if process_handle is None: err_no = kernel32.GetLastError() raise ( WindowsError( err_no, ctypes.FormatError(err_no) ) ) process = Process( pid, process_handle ) return process
def is_ipv6(ip): try: if os.name == "nt": class sockaddr(ctypes.Structure): _fields_ = [("sa_family", ctypes.c_short), ("__pad1", ctypes.c_ushort), ("ipv4_addr", ctypes.c_byte * 4), ("ipv6_addr", ctypes.c_byte * 16), ("__pad2", ctypes.c_ulong)] WSAStringToAddressA = ctypes.windll.ws2_32.WSAStringToAddressA addr = sockaddr() addr.sa_family = socket.AF_INET6 addr_size = ctypes.c_int(ctypes.sizeof(addr)) if WSAStringToAddressA(ip, socket.AF_INET6, None, ctypes.byref(addr), ctypes.byref(addr_size)) != 0: raise socket.error(ctypes.FormatError()) return ctypes.string_at(addr.ipv6_addr, 16) else: return socket.inet_pton(socket.AF_INET6, ip) except: return False
def inet_pton(address_family, ip_string): # type: (int, str) -> bytes addr = SockAddr() ip_string_bytes = ip_string.encode('ascii') addr.sa_family = address_family addr_size = ctypes.c_int(ctypes.sizeof(addr)) try: attribute, size = { socket.AF_INET: ("ipv4_addr", 4), socket.AF_INET6: ("ipv6_addr", 16), }[address_family] except KeyError: raise socket.error("unknown address family") if WSAStringToAddressA(ip_string_bytes, address_family, None, ctypes.byref(addr), ctypes.byref(addr_size)) != 0: raise socket.error(ctypes.FormatError()) return ctypes.string_at(getattr(addr, attribute), size)
def _get_memory_win32(self, process_handle): """Get the current memory consumption using win32 apis.""" mem_struct = PROCESS_MEMORY_COUNTERS_EX() ret = ctypes.windll.psapi.GetProcessMemoryInfo( process_handle, ctypes.byref(mem_struct), ctypes.sizeof(mem_struct)) if not ret: raise RuntimeError('Failed to call GetProcessMemoryInfo: %s' % ctypes.FormatError()) return { 'PageFaultCount': mem_struct.PageFaultCount, 'PeakWorkingSetSize': mem_struct.PeakWorkingSetSize, 'WorkingSetSize': mem_struct.WorkingSetSize, 'QuotaPeakPagedPoolUsage': mem_struct.QuotaPeakPagedPoolUsage, 'QuotaPagedPoolUsage': mem_struct.QuotaPagedPoolUsage, 'QuotaPeakNonPagedPoolUsage': mem_struct.QuotaPeakNonPagedPoolUsage, 'QuotaNonPagedPoolUsage': mem_struct.QuotaNonPagedPoolUsage, 'PagefileUsage': mem_struct.PagefileUsage, 'PeakPagefileUsage': mem_struct.PeakPagefileUsage, 'PrivateUsage': mem_struct.PrivateUsage, }
def system_command_call(command, shell=True): if shell and isinstance(command, list): command = subprocess.list2cmdline(command) try: process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=shell) stdout, stderr = process.communicate() if process.returncode != 0: sys.stderr.write('{}\nRunning {} failed with exit code {}\n'.format(stderr, command, process.returncode)) return None return stdout if isinstance(stdout, str) else stdout.decode() except OSError as e: msg = e.strerror errcodes = 'error {}'.format(e.errno) if is_windows_host() and isinstance(e, WindowsError): errcodes += ', win-error {}'.format(e.winerror) try: import ctypes msg = unicode(ctypes.FormatError(e.winerror), locale.getdefaultlocale()[1]).encode('utf-8') except ImportError: pass sys.stderr.write('System command call {} failed [{}]: {}\n'.format(command, errcodes, msg)) return None
def inet_pton(address_family, ip_string): # Verify IP Address # This will catch IP Addresses such as 10.1.2 if address_family == socket.AF_INET: try: ipaddress.ip_address(six.u(ip_string)) except ValueError: raise socket.error('illegal IP address string passed to inet_pton') return socket.inet_aton(ip_string) # Verify IP Address # The `WSAStringToAddressA` function handles notations used by Berkeley # software which includes 3 part IP Addresses such as `10.1.2`. That's why # the above check is needed to enforce more strict IP Address validation as # used by the `inet_pton` function in Unix. # See the following: # https://stackoverflow.com/a/29286098 # Docs for the `inet_addr` function on MSDN # https://msdn.microsoft.com/en-us/library/windows/desktop/ms738563.aspx addr = sockaddr() addr.sa_family = address_family addr_size = ctypes.c_int(ctypes.sizeof(addr)) if WSAStringToAddressA( ip_string, address_family, None, ctypes.byref(addr), ctypes.byref(addr_size) ) != 0: raise socket.error(ctypes.FormatError()) if address_family == socket.AF_INET: return ctypes.string_at(addr.ipv4_addr, 4) if address_family == socket.AF_INET6: return ctypes.string_at(addr.ipv6_addr, 16) raise socket.error('unknown address family')
def acquire(self, mode): if mode not in "rw": raise ValueError("Invalid mode: %r" % mode) with open(self._path, "w+") as lock_file: if os.name == "nt": handle = msvcrt.get_osfhandle(lock_file.fileno()) flags = LOCKFILE_EXCLUSIVE_LOCK if mode == "w" else 0 overlapped = Overlapped() if not lock_file_ex(handle, flags, 0, 1, 0, overlapped): raise RuntimeError("Locking the storage failed: %s" % ctypes.FormatError()) elif os.name == "posix": _cmd = fcntl.LOCK_EX if mode == "w" else fcntl.LOCK_SH try: fcntl.flock(lock_file.fileno(), _cmd) except OSError as e: raise RuntimeError("Locking the storage failed: %s" % e) from e else: raise RuntimeError("Locking the storage failed: " "Unsupported operating system") with self._lock: if self._writer or mode == "w" and self._readers != 0: raise RuntimeError("Locking the storage failed: " "Guarantees failed") if mode == "r": self._readers += 1 else: self._writer = True try: yield finally: with self._lock: if mode == "r": self._readers -= 1 self._writer = False
def EvtGetPublisherMetadataProperty(metadata_handle, property_id): """A helper function to make calling EvtGetPublisherMetadataProperty easier. :param metadata_handle: (EVT_HANDLE) This is a handled returned by EvtOpenPublisherMetadata :param property_id: (EVT_PUBLISHER_METADATA_PROPERTY_ID) EvtPublisherMetadata* ENUM value :return: (EVT_VARIANT) """ buffer_size = 0 variant = None buffer_used = byref(DWORD()) result = wevtapi.EvtGetPublisherMetadataProperty(metadata_handle, property_id, 0, buffer_size, variant, buffer_used) if result == 0: # Check our last error status = kernel32.GetLastError() if status == ERROR_INSUFFICIENT_BUFFER: # If the error is ERROR_INSUFFICIENT_BUFFER, # we can now determine the buffer size needed. buffer_size = buffer_used._obj.value variant_buffer = ctypes.create_string_buffer(buffer_size) variant = EVT_VARIANT.from_buffer(variant_buffer) result = wevtapi.EvtGetPublisherMetadataProperty( metadata_handle, property_id, 0, buffer_size, variant, buffer_used) return variant else: error_msg = ctypes.FormatError(status) raise (Exception( "Unhandled error on EvtGetPublisherMetadataProperty. Error: {}; Message: {}" .format(status, error_msg)))
def _unlock_file(f): assert f._lock_file_overlapped_p handle = msvcrt.get_osfhandle(f.fileno()) if not UnlockFileEx(handle, 0, whole_low, whole_high, f._lock_file_overlapped_p): raise OSError('Unlocking file failed: %r' % ctypes.FormatError())
def win_error(error, filename): exc = WindowsError(error, ctypes.FormatError(error)) exc.filename = filename return exc
def __init__(self, winerr=None): if not winerr: winerr = ctypes.GetLastError() super().__init__(0, ctypes.FormatError(winerr), None, winerr)
def error_array_parser(buffer): return list((err_no, ctypes.FormatError(err_no)) for err_no in array.array('l', buffer))
def error_parser(buffer): err_no = struct.unpack("l", buffer[:4]) return err_no, ctypes.FormatError(err_no)
def get_error(): error = ctypes.GetLastError() return (error, ctypes.FormatError(error))
def format_error(error): if isinstance(error, WindowsError): error = error.winerror if not isinstance(error, int): return 'Unknown' return ctypes.FormatError(error)
def WinError(code=None, descr=None): if code is None: code = ctypes.GetLastError() if descr is None: descr = ctypes.FormatError(code).strip() return WindowsError(code, descr)