def process__get_executable_filename(thread_pid): psapi = WinDLL('psapi.dll') EnumProcesses = psapi.EnumProcesses EnumProcessModules = psapi.EnumProcessModules GetModuleBaseName = psapi.GetModuleBaseNameW # Alternate: GetModuleFileNameEx GetProcessImageFileName = psapi.GetProcessImageFileNameW hproc = windll.kernel32.OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, False, thread_pid) try: filename = create_unicode_buffer(MAX_FILENAME_LENGTH + 1) res = GetProcessImageFileName(hproc, None, byref(filename), MAX_FILENAME_LENGTH + 1) if res > 0: return filename.value[:res] finally: windll.kernel32.CloseHandle(hproc) # So, GetProcessImageFileName failed, as it's apt to do. # So, do this the hard way. process_list = (wintypes.DWORD * MAX_PROCESS_COUNT)() bytes_returned = wintypes.DWORD() res = EnumProcesses(process_list, c_sizeof(process_list), byref(bytes_returned)) if res != 0: return None # raise ctypes.WinError() for i in range(bytes_returned / c_sizeof(wintypes.DWORD)): pid = process_list[i] if pid == thread_pid: hproc = windll.kernel32.OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, None, pid) if hproc is None or 0 == hproc: continue try: buffer_index_count = 1024 count_allocated_space = wintypes.DWORD() hmod_list = (wintypes.HMODULE * buffer_index_count)() res = EnumProcessModules(hproc.value, hmod_list, wintypes.DWORD(c_sizeof(hmod_list)), byref(count_allocated_space)) if res == 0: # Error; ignore continue for j in range(count_allocated_space / c_sizeof(wintypes.HMODULE)): mod_name = create_unicode_buffer(MAX_FILENAME_LENGTH + 1) res = GetModuleBaseName(hproc, hmod_list[j], mod_name, MAX_FILENAME_LENGTH + 1) if res != 0: return str(mod_name.value[:res]) finally: windll.kernel32.CloseHandle(hproc) return None
def shell__set_window_metrics(metrics): SystemParametersInfoW = windll.user32.SystemParametersInfoW # Always restore the original user metrics at exit time. root_metrics = None if _BASE_OS_METRICS[0] is None: root_metrics = shell__get_raw_window_metrics() _BASE_OS_METRICS[0] = root_metrics atexit.register(shell__set_window_metrics, root_metrics) if isinstance(metrics, dict): m = root_metrics or shell__get_raw_window_metrics() m.cbSize = c_sizeof(NONCLIENTMETRICS) if 'border-width' in metrics: m.iBorderWidth = metrics['border-width'] if 'scroll-width' in metrics: m.iScrollWidth = metrics['scroll-width'] if 'scroll-height' in metrics: m.iScrollHeight = metrics['scroll-height'] if 'caption-width' in metrics: m.iCaptionWidth = metrics['caption-width'] if 'caption-height' in metrics: m.iCaptionHeight = metrics['caption-height'] if 'caption-font' in metrics: m.lfCaptionFont = _dict_to_font(metrics['caption-font'], m.lfCaptionFont) if 'sm-caption-width' in metrics: m.iSmCaptionWidth = metrics['sm-caption-width'] if 'sm-caption-height' in metrics: m.iSmCaptionHeight = metrics['sm-caption-height'] if 'sm-caption-font' in metrics: m.lfSmCaptionFont = _dict_to_font(metrics['sm-caption-font'], m.lfSmCaptionFont) if 'menu-width' in metrics: m.iMenuWidth = metrics['menu-width'] if 'menu-height' in metrics: m.iMenuHeight = metrics['menu-height'] if 'menu-font' in metrics: m.lfMenuFont = _dict_to_font(metrics[''], m.lfMenuFont) if 'status-font' in metrics: m.lfStatusFont = _dict_to_font(metrics['status-font'], m.lfStatusFont) if 'message-font' in metrics: m.lfMessageFont = _dict_to_font(metrics['message-font'], m.lfMessageFont) metrics = m assert isinstance(metrics, NONCLIENTMETRICS) metrics.cbSize = c_sizeof(NONCLIENTMETRICS) # TODO change 0 to SPIF_SENDCHANGE res = SystemParametersInfoW(SPI_SETNONCLIENTMETRICS, metrics.cbSize, byref(metrics), 0) if res != 0: raise WinError()
def process__get_all_pids(): process_buff = (wintypes.DWORD * 2048)() process_size = wintypes.DWORD() res = windll.psapi.EnumProcesses(process_buff, c_sizeof(process_buff), byref(process_size)) if res != 0: raise WinError() count = process_size / c_sizeof(wintypes.DWORD) ret = [] for i in range(count): ret.append(process_buff[i]) return ret
def _bind(s, addr): sa_addr = sockaddr_in() host, port = addr sa_addr.sin_family = socket.AF_INET sa_addr.sin_port = socket.htons(port) sa_addr.sin_addr.S_addr = unpack('<i', socket.inet_aton(host))[0] low_bind(s, byref(sa_addr), c_sizeof(sa_addr))
def _getsockname(s): sa_addr = sockaddr_in() sa_addr_len = c_int(c_sizeof(sa_addr)) low_getsockname(s, byref(sa_addr), byref(sa_addr_len)) port = socket.ntohs(sa_addr.sin_port) host = socket.inet_ntoa(pack('<i', sa_addr.sin_addr.S_addr)) addr = (host, port) return addr
def WSAAccept(s): sa_addr = sockaddr_in() sa_addr_len = c_int(c_sizeof(sa_addr)) rc = lowWSAAccept(s, byref(sa_addr), byref(sa_addr_len), None, None) port = socket.ntohs(sa_addr.sin_port) host = socket.inet_ntoa(pack('<i', sa_addr.sin_addr.S_addr)) addr = (host, port) return (rc, addr)
def shell__get_raw_window_metrics(): SystemParametersInfoW = windll.user32.SystemParametersInfoW metrics = NONCLIENTMETRICS() metrics.cbSize = c_sizeof(NONCLIENTMETRICS) res = SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, metrics.cbSize, byref(metrics), 0) if res != 0: raise WinError() return metrics
def __init__(self, value=None): self._owned = False if isinstance(value, c_void_p): self._c = _CObjectProxy(value, self._c_api) elif value is None or isinstance(value, str): _c_ptr = _new(c_sizeof(c_void_p)) self._c = _CObjectProxy(_c_ptr, self._c_api) self._c.QString(value) self._owned = True else: raise TypeError("QString can only be initialized with None, str, or a pointer")
def _from_bn_smart_ptr(ptr, c_type, new_ref): if new_ref not in _bn_new_ref_fns: _bn_new_ref_fns[new_ref] = _CStaticMethodProxy(new_ref, CFUNCTYPE(c_void_p, c_void_p)) new_ref_fn = _bn_new_ref_fns[new_ref] # The layout of class CoreRefCountObject is as follows: # void* vtbl; # int m_refs; # T* m_object; # We need m_object. c_object = c_cast(ptr + c_sizeof(c_void_p) * 2, CPOINTER(c_void_p)).contents return bnc.handle_of_type(c_cast(new_ref_fn(c_object), c_void_p), c_type)
def query_if(ifname): ifname = ifname.encode('ascii') sysctl_buf_len = c_uint(0) rval = libc.sysctl(mib, 6, None, byref(sysctl_buf_len), None, 0) if rval != 0: raise Exception(errno.errorcode[get_errno()]) sysctl_buf = create_string_buffer(sysctl_buf_len.value) rval = libc.sysctl(mib, 6, sysctl_buf, byref(sysctl_buf_len), None, 0) if rval != 0: raise Exception(errno.errorcode[get_errno()]) # walk the structure. you need to know the length from ifm_msglen idx = addressof(sysctl_buf) end = idx + sysctl_buf_len.value while idx < end: batch_off = idx - addressof(sysctl_buf) ifmsg = cast(c_void_p(idx), POINTER(if_msghdr2)) if ifmsg.contents.ifm_type != RTM_IFINFO2: idx += ifmsg.contents.ifm_msglen continue if ifmsg.contents.ifm_flags & IFF_LOOPBACK: idx += ifmsg.contents.ifm_msglen continue # 12 bytes to compensate for 32 bit alignment sdl = cast(c_void_p(idx + c_sizeof(if_msghdr2)), POINTER(sockaddr_dl)) if sdl.contents.sdl_family != AF_LINK: idx += ifmsg.contents.ifm_msglen continue if ifname != sdl.contents.sdl_data[0:sdl.contents.sdl_nlen]: idx += ifmsg.contents.ifm_msglen continue return ifmsg.contents.ifm_data.ifi_ibytes, ifmsg.contents.ifm_data.ifi_obytes #idx += ifmsg.contents.ifm_msglen raise Exception('ifname {0} not found'.format(ifname))
def process__get_all_service_information(): advapi32 = WinDLL('advapi32.dll') OpenSCManager = advapi32.OpenSCManagerW OpenSCManager.restype = wintypes.DWORD EnumServicesStatusEx = advapi32.EnumServicesStatusExW # EnumServicesStatusExW(SC_HANDLE,SC_ENUM_TYPE,DWORD,DWORD,LPBYTE,DWORD,LPDWORD,LPDWORD,LPDWORD,LPCWSTR); # EnumServicesStatusEx.argtypes = [ # c_int, # hSCManager (SC_HANDLE) # c_int, # InfoLevel (SC_ENUM_TYPE) # wintypes.DWORD, # dwServiceType # wintypes.DWORD, # dwServiceState # wintypes.LPBYTE, # lpServices # wintypes.DWORD, # cbBufSize # wintypes.LPDWORD, # pcbBytesNeeded # wintypes.LPDWORD, # lpServicesReturned # wintypes.LPDWORD, # lpResumeHandle # wintypes.LPCWSTR # pszGroupname # ] CloseServiceHandle = advapi32.CloseServiceHandle CloseServiceHandle.argtypes = [wintypes.HANDLE] sc = OpenSCManager(None, None, SC_MANAGER_ENUMERATE_SERVICE) if sc == 0: raise WinError() try: bytes_needed = wintypes.DWORD(0) service_byte_count = wintypes.DWORD(0) service_count = wintypes.DWORD(0) resume_handle = wintypes.DWORD(0) status_array = None # Start off with 0 bytes allocated, and increase from there. while True: res = EnumServicesStatusEx( sc, SC_ENUM_PROCESS_INFO, # SERVICE_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER | SERVICE_WIN32, SERVICE_WIN32, SERVICE_STATE_ALL, status_array, service_byte_count, byref(bytes_needed), byref(service_count), byref(resume_handle), None) if res != 0: break if GetLastError() != ERROR_MORE_DATA: # raise ctypes.WinError() return [] print("need {0} bytes".format(bytes_needed)) service_byte_count = bytes_needed count = bytes_needed.value // c_sizeof(ENUM_SERVICE_STATUS_PROCESS) status_array = (ENUM_SERVICE_STATUS_PROCESS * count)() ret = [] for i in range(service_count.value): status = status_array[i] controls_accepted = [] if status.dwControlsAccepted & SERVICE_ACCEPT_NETBINDCHANGE == SERVICE_ACCEPT_NETBINDCHANGE: controls_accepted.append('SERVICE_ACCEPT_NETBINDCHANGE') if status.dwControlsAccepted & SERVICE_ACCEPT_PARAMCHANGE == SERVICE_ACCEPT_PARAMCHANGE: controls_accepted.append('SERVICE_ACCEPT_PARAMCHANGE') if status.dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE == SERVICE_ACCEPT_PAUSE_CONTINUE: controls_accepted.append('SERVICE_ACCEPT_PAUSE_CONTINUE') if status.dwControlsAccepted & SERVICE_ACCEPT_PRESHUTDOWN == SERVICE_ACCEPT_PRESHUTDOWN: controls_accepted.append('SERVICE_ACCEPT_PRESHUTDOWN') if status.dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN == SERVICE_ACCEPT_SHUTDOWN: controls_accepted.append('SERVICE_ACCEPT_SHUTDOWN') if status.dwControlsAccepted & SERVICE_ACCEPT_STOP == SERVICE_ACCEPT_STOP: controls_accepted.append('SERVICE_ACCEPT_STOP') ret.append({ 'display_name': status.lpServiceName.value, 'service_name': status.lpDisplayName.value, 'service_type': (status.dwServiceType in _SERVICE_TYPES and _SERVICE_TYPES[status.dwServiceType] or None), 'current_state': (status.dwCurrentState in _SERVICE_CURRENT_STATES and _SERVICE_CURRENT_STATES[status.dwCurrentState] or None), 'controls_accepted': controls_accepted, 'exit_code': status.dwWin32ExitCode, 'service_exit_code': status.dwServiceSpecificExitCode, 'check_point': status.dwCheckPoint, 'wait_time_millis_hint': status.dwWaitHint, 'process_id': status.dwProcessId, 'flags': status.dwServiceFlags == 1 and ['SERVICE_RUNS_IN_SYSTEM_PROCESS'] or [], }) return ret finally: CloseServiceHandle(sc)
def thread_window_callback(hwnd, lparam): length = windll.user32.GetWindowTextLengthW(hwnd) if length > 0: buff = create_unicode_buffer(length + 1) windll.user32.GetWindowTextW(hwnd, buff, length + 1) # print("DEBUG - Inspecting {0} = {1}".format(hwnd, buff.value)) if buff.value == "Start": # Found the window # print("DEBUG sending Click message") m_res = windll.user32.SendMessageW(hwnd, BM_CLICK, 0, 0) if m_res != 0: # Don't look anymore triggered_start[0] = True return False else: try: print("<<ERROR pressing start button>>") raise WinError() except OSError: import traceback traceback.print_exc() if buff.value == "Start menu": triggered_start[0] = True if windll.user32.IsWindowVisible(hwnd): p = WINDOWPLACEMENT() p.length = c_sizeof(WINDOWPLACEMENT) val = windll.user32.GetWindowPlacement(hwnd, byref(p)) if val is not None: show_cmd = p.showCmd if (show_cmd == SW_SHOWNORMAL or show_cmd == SW_MAXIMIZE or show_cmd == SW_SHOWMAXIMIZED or show_cmd == SW_SHOWNOACTIVATE or show_cmd == SW_SHOW or show_cmd == SW_SHOWNA or show_cmd == SW_RESTORE): # Hide the window # print("DEBUG hiding the start menu {0}".format(show_cmd)) windll.user32.ShowWindow(hwnd, SW_HIDE) return False # print("DEBUG showing the start menu ({0})".format(placement.showCmd)) windll.user32.ShowWindow(hwnd, SW_SHOW) # If the task bar is hidden, then part of the start window is not shown fully. # SW_MAXIMIZE will show it fully, but the rendering becomes messed up. taskbar_rect = wintypes.RECT() windll.user32.GetClientRect(taskbar_hwnd, byref(taskbar_rect)) client_rect = wintypes.RECT() windll.user32.GetClientRect(hwnd, byref(client_rect)) overlap_rect = wintypes.RECT() if windll.user32.IntersectRect(byref(overlap_rect), byref(taskbar_rect), byref(client_rect)) != 0: # The taskbar and the start window rectangles overlap each other. # Adjust the start window to be outside of this. # Remember: the taskbar can be anywhere on the edge of the screen. new_x = client_rect.left new_y = client_rect.top if overlap_rect.left == client_rect.left and overlap_rect.right == client_rect.right: # Adjust along the y axis if overlap_rect.top <= client_rect.top <= overlap_rect.bottom: # Adjust down new_y = overlap_rect.bottom else: # Adjust up new_y = client_rect.top - (overlap_rect.bottom - overlap_rect.top) else: # Adjust along the x axis if overlap_rect.left <= client_rect.left <= overlap_rect.right: # Adjust to the right new_x = overlap_rect.right else: new_x = client_rect.left - (overlap_rect.right - overlap_rect.left) windll.user32.SetWindowPos( hwnd, None, new_x, new_y, 0, 0, SWP_NOSIZE) # Give the window the focus. This is the Microsoft Magic Focus Dance. current_hwnd = windll.user32.GetForegroundWindow() current_thread_id = windll.kernel32.GetCurrentThreadId() thread_process_id = windll.user32.GetWindowThreadProcessId(current_hwnd, None) windll.user32.AttachThreadInput(thread_process_id, current_thread_id, True) windll.user32.SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE) windll.user32.SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE) windll.user32.SetForegroundWindow(hwnd) windll.user32.AttachThreadInput(thread_process_id, current_thread_id, False) windll.user32.SetFocus(hwnd) windll.user32.SetActiveWindow(hwnd) return False # else: # print("DEBUG - Inspecting {0} => no title, ignoring".format(hwnd)) return True
def shell__open_start_menu(show_taskbar): # Find the task bar window taskbar_hwnd = windll.user32.FindWindowW("Shell_TrayWnd", None) if taskbar_hwnd is None or 0 == taskbar_hwnd: raise WinError() taskbar_size = wintypes.RECT() windll.user32.GetWindowRect(taskbar_hwnd, byref(taskbar_size)) # if show_taskbar: # if windll.user32.IsWindowVisible(taskbar_hwnd): # placement = WINDOWPLACEMENT() # placement.length = c_sizeof(WINDOWPLACEMENT) # val = windll.user32.GetWindowPlacement(taskbar_hwnd, byref(placement)) # if val is not None: # show_cmd = placement.showCmd # if (show_cmd == SW_SHOWNORMAL or show_cmd == SW_MAXIMIZE or show_cmd == SW_SHOWMAXIMIZED # or show_cmd == SW_SHOWNOACTIVATE or show_cmd == SW_SHOW or show_cmd == SW_SHOWNA # or show_cmd == SW_RESTORE): # show_taskbar = False if show_taskbar: # The task bar is auto-hide. It's always present, but not on screen. # The trick Windows uses is pushing it off-screen, so it's just barely # visible. windll.user32.GetWindowRect(taskbar_hwnd, byref(taskbar_size)) # Figure out which corner it's in. It's either top, left, right, or bottom. # We do this by finding a "0", which indicates where on the screen it's # located. However, with strange, multi-monitor setups, this isn't always # correct. But it's a good guess. # windll.user32.SetWindowPos(taskbar_hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW) # TODO show the task bar. # print("<<Don't know how to show the task bar>>") # Find the process ID of the taskbar window. taskbar_pid = wintypes.DWORD() windll.user32.GetWindowThreadProcessId(taskbar_hwnd, byref(taskbar_pid)) # Find a thread in that process that has a "Start" button triggered_start = [False] # noinspection PyUnusedLocal def thread_window_callback(hwnd, lparam): length = windll.user32.GetWindowTextLengthW(hwnd) if length > 0: buff = create_unicode_buffer(length + 1) windll.user32.GetWindowTextW(hwnd, buff, length + 1) # print("DEBUG - Inspecting {0} = {1}".format(hwnd, buff.value)) if buff.value == "Start": # Found the window # print("DEBUG sending Click message") m_res = windll.user32.SendMessageW(hwnd, BM_CLICK, 0, 0) if m_res != 0: # Don't look anymore triggered_start[0] = True return False else: try: print("<<ERROR pressing start button>>") raise WinError() except OSError: import traceback traceback.print_exc() if buff.value == "Start menu": triggered_start[0] = True if windll.user32.IsWindowVisible(hwnd): p = WINDOWPLACEMENT() p.length = c_sizeof(WINDOWPLACEMENT) val = windll.user32.GetWindowPlacement(hwnd, byref(p)) if val is not None: show_cmd = p.showCmd if (show_cmd == SW_SHOWNORMAL or show_cmd == SW_MAXIMIZE or show_cmd == SW_SHOWMAXIMIZED or show_cmd == SW_SHOWNOACTIVATE or show_cmd == SW_SHOW or show_cmd == SW_SHOWNA or show_cmd == SW_RESTORE): # Hide the window # print("DEBUG hiding the start menu {0}".format(show_cmd)) windll.user32.ShowWindow(hwnd, SW_HIDE) return False # print("DEBUG showing the start menu ({0})".format(placement.showCmd)) windll.user32.ShowWindow(hwnd, SW_SHOW) # If the task bar is hidden, then part of the start window is not shown fully. # SW_MAXIMIZE will show it fully, but the rendering becomes messed up. taskbar_rect = wintypes.RECT() windll.user32.GetClientRect(taskbar_hwnd, byref(taskbar_rect)) client_rect = wintypes.RECT() windll.user32.GetClientRect(hwnd, byref(client_rect)) overlap_rect = wintypes.RECT() if windll.user32.IntersectRect(byref(overlap_rect), byref(taskbar_rect), byref(client_rect)) != 0: # The taskbar and the start window rectangles overlap each other. # Adjust the start window to be outside of this. # Remember: the taskbar can be anywhere on the edge of the screen. new_x = client_rect.left new_y = client_rect.top if overlap_rect.left == client_rect.left and overlap_rect.right == client_rect.right: # Adjust along the y axis if overlap_rect.top <= client_rect.top <= overlap_rect.bottom: # Adjust down new_y = overlap_rect.bottom else: # Adjust up new_y = client_rect.top - (overlap_rect.bottom - overlap_rect.top) else: # Adjust along the x axis if overlap_rect.left <= client_rect.left <= overlap_rect.right: # Adjust to the right new_x = overlap_rect.right else: new_x = client_rect.left - (overlap_rect.right - overlap_rect.left) windll.user32.SetWindowPos( hwnd, None, new_x, new_y, 0, 0, SWP_NOSIZE) # Give the window the focus. This is the Microsoft Magic Focus Dance. current_hwnd = windll.user32.GetForegroundWindow() current_thread_id = windll.kernel32.GetCurrentThreadId() thread_process_id = windll.user32.GetWindowThreadProcessId(current_hwnd, None) windll.user32.AttachThreadInput(thread_process_id, current_thread_id, True) windll.user32.SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE) windll.user32.SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE) windll.user32.SetForegroundWindow(hwnd) windll.user32.AttachThreadInput(thread_process_id, current_thread_id, False) windll.user32.SetFocus(hwnd) windll.user32.SetActiveWindow(hwnd) return False # else: # print("DEBUG - Inspecting {0} => no title, ignoring".format(hwnd)) return True # Find the threads for the process ID thread_ids = [] hsnapshot = windll.kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, taskbar_pid) if hsnapshot == INVALID_HANDLE_VALUE: raise WinError() try: thread_entry = THREADENTRY32() thread_entry.dwSize = c_sizeof(THREADENTRY32) # print("DEBUG Getting threads for pid {0}".format(taskbar_pid)) res = windll.kernel32.Thread32First(hsnapshot, byref(thread_entry)) # print("DEBUG :: first: {0}".format(res)) if res == 0: raise WinError() while res != 0: if thread_entry.dwSize > THREADENTRY32.th32OwnerProcessID.offset: thread_ids.append(thread_entry.th32ThreadID) # else: # print("DEBUG - returned too small size {0}".format(thread_entry.dwSize)) thread_entry.dwSize = c_sizeof(THREADENTRY32) res = windll.kernel32.Thread32Next(hsnapshot, byref(thread_entry)) # print("DEBUG :: next: {0}".format(res)) finally: windll.kernel32.CloseHandle(hsnapshot) callback_type = CFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM) callback_ptr = callback_type(thread_window_callback) for thread_id in thread_ids: # print("DEBUG Iterating over windows for thread {0} in pid {1}".format(thread_id, taskbar_pid)) windll.user32.EnumThreadWindows(thread_id, callback_ptr, 0) if triggered_start[0]: return raise OSError("Could not find start button")