def __init__(self): # Create a pipe so we can write to stdin of the loader process. pipeReadOrig, self._pipeWrite = winKernel.CreatePipe(None, 0) # Make the read end of the pipe inheritable. pipeRead = self._duplicateAsInheritable(pipeReadOrig) winKernel.closeHandle(pipeReadOrig) # stdout/stderr of the loader process should go to nul. with file("nul", "w") as nul: nulHandle = self._duplicateAsInheritable(msvcrt.get_osfhandle(nul.fileno())) # Set the process to start with the appropriate std* handles. si = winKernel.STARTUPINFO(dwFlags=winKernel.STARTF_USESTDHANDLES, hSTDInput=pipeRead, hSTDOutput=nulHandle, hSTDError=nulHandle) pi = winKernel.PROCESS_INFORMATION() # Even if we have uiAccess privileges, they will not be inherited by default. # Therefore, explicitly specify our own process token, which causes them to be inherited. token = winKernel.OpenProcessToken(winKernel.GetCurrentProcess(), winKernel.MAXIMUM_ALLOWED) try: winKernel.CreateProcessAsUser(token, None, os.path.join(versionedLib64Path,u"nvdaHelperRemoteLoader.exe"), None, None, True, None, None, None, si, pi) # We don't need the thread handle. winKernel.closeHandle(pi.hThread) self._process = pi.hProcess except: winKernel.closeHandle(self._pipeWrite) raise finally: winKernel.closeHandle(pipeRead) winKernel.closeHandle(token)
def terminateRunningNVDA(window): processID, threadID = winUser.getWindowThreadProcessID(window) winUser.PostMessage(window, winUser.WM_QUIT, 0, 0) h = winKernel.openProcess(winKernel.SYNCHRONIZE, False, processID) if not h: # The process is already dead. return try: res = winKernel.waitForSingleObject(h, 4000) if res == 0: # The process terminated within the timeout period. return finally: winKernel.closeHandle(h) # The process is refusing to exit gracefully, so kill it forcefully. h = winKernel.openProcess( winKernel.PROCESS_TERMINATE | winKernel.SYNCHRONIZE, False, processID) if not h: raise OSError("Could not open process for termination") try: winKernel.TerminateProcess(h, 1) winKernel.waitForSingleObject(h, 2000) finally: winKernel.closeHandle(h)
def disconnectConsole(): global consoleObject, consoleOutputHandle, consoleWinEventHookHandles, checkDeadTimer if not consoleObject: log.debugWarning("console was not connected") return False checkDeadTimer.Stop() checkDeadTimer=None #Unregister any win events we are using for handle in consoleWinEventHookHandles: winUser.unhookWinEvent(handle) consoleEventHookHandles=[] consoleObject.stopMonitoring() winKernel.closeHandle(consoleOutputHandle) consoleOutputHandle=None consoleObject=None try: wincon.SetConsoleCtrlHandler(_consoleCtrlHandler,False) except WindowsError: pass #Try freeing NVDA from this console try: wincon.FreeConsole() except WindowsError: pass return True
def __init__(self): # Create a pipe so we can write to stdin of the loader process. pipeReadOrig, self._pipeWrite = winKernel.CreatePipe(None, 0) # Make the read end of the pipe inheritable. pipeRead = self._duplicateAsInheritable(pipeReadOrig) winKernel.closeHandle(pipeReadOrig) # stdout/stderr of the loader process should go to nul. with file("nul", "w") as nul: nulHandle = self._duplicateAsInheritable( msvcrt.get_osfhandle(nul.fileno())) # Set the process to start with the appropriate std* handles. si = winKernel.STARTUPINFO(dwFlags=winKernel.STARTF_USESTDHANDLES, hSTDInput=pipeRead, hSTDOutput=nulHandle, hSTDError=nulHandle) pi = winKernel.PROCESS_INFORMATION() # Even if we have uiAccess privileges, they will not be inherited by default. # Therefore, explicitly specify our own process token, which causes them to be inherited. token = winKernel.OpenProcessToken(winKernel.GetCurrentProcess(), winKernel.MAXIMUM_ALLOWED) try: winKernel.CreateProcessAsUser(token, None, u"lib64/nvdaHelperRemoteLoader.exe", None, None, True, None, None, None, si, pi) # We don't need the thread handle. winKernel.closeHandle(pi.hThread) self._process = pi.hProcess except: winKernel.closeHandle(self._pipeWrite) raise finally: winKernel.closeHandle(pipeRead) winKernel.closeHandle(token)
def execElevated(path, params=None, wait=False, handleAlreadyElevated=False): import subprocess import shellapi import winUser if params is not None: params = subprocess.list2cmdline(params) sei = shellapi.SHELLEXECUTEINFO(lpFile=os.path.abspath(path), lpParameters=params, nShow=winUser.SW_HIDE) #IsUserAnAdmin is apparently deprecated so may not work above Windows 8 if not handleAlreadyElevated or not ctypes.windll.shell32.IsUserAnAdmin(): sei.lpVerb = u"runas" if wait: sei.fMask = shellapi.SEE_MASK_NOCLOSEPROCESS shellapi.ShellExecuteEx(sei) if wait: try: h = ctypes.wintypes.HANDLE(sei.hProcess) msg = ctypes.wintypes.MSG() while ctypes.windll.user32.MsgWaitForMultipleObjects( 1, ctypes.byref(h), False, -1, 255) == 1: while ctypes.windll.user32.PeekMessageW( ctypes.byref(msg), None, 0, 0, 1): ctypes.windll.user32.TranslateMessage(ctypes.byref(msg)) ctypes.windll.user32.DispatchMessageW(ctypes.byref(msg)) return winKernel.GetExitCodeProcess(sei.hProcess) finally: winKernel.closeHandle(sei.hProcess)
def disconnectConsole(): global consoleObject, consoleOutputHandle, consoleWinEventHookHandles, checkDeadTimer if not consoleObject: log.debugWarning("console was not connected") return False checkDeadTimer.Stop() checkDeadTimer = None #Unregister any win events we are using for handle in consoleWinEventHookHandles: winUser.unhookWinEvent(handle) consoleEventHookHandles = [] consoleObject.stopMonitoring() winKernel.closeHandle(consoleOutputHandle) consoleOutputHandle = None consoleObject = None try: wincon.SetConsoleCtrlHandler(_consoleCtrlHandler, False) except WindowsError: pass #Try freeing NVDA from this console try: wincon.FreeConsole() except WindowsError: pass return True
def execElevated(path, params=None, wait=False,handleAlreadyElevated=False): import subprocess import shellapi import winKernel import winUser if params is not None: params = subprocess.list2cmdline(params) sei = shellapi.SHELLEXECUTEINFO(lpFile=os.path.abspath(path), lpParameters=params, nShow=winUser.SW_HIDE) #IsUserAnAdmin is apparently deprecated so may not work above Windows 8 if not handleAlreadyElevated or not ctypes.windll.shell32.IsUserAnAdmin(): sei.lpVerb=u"runas" if wait: sei.fMask = shellapi.SEE_MASK_NOCLOSEPROCESS shellapi.ShellExecuteEx(sei) if wait: try: h=ctypes.wintypes.HANDLE(sei.hProcess) msg=ctypes.wintypes.MSG() while ctypes.windll.user32.MsgWaitForMultipleObjects(1,ctypes.byref(h),False,-1,255)==1: while ctypes.windll.user32.PeekMessageW(ctypes.byref(msg),None,0,0,1): ctypes.windll.user32.TranslateMessage(ctypes.byref(msg)) ctypes.windll.user32.DispatchMessageW(ctypes.byref(msg)) return winKernel.GetExitCodeProcess(sei.hProcess) finally: winKernel.closeHandle(sei.hProcess)
def close(self): super(Bulk, self).close() if hasattr(self, "_file") and self._file is not INVALID_HANDLE_VALUE: winKernel.closeHandle(self._file) if hasattr( self, "_writeFile") and self._writeFile is not INVALID_HANDLE_VALUE: winKernel.closeHandle(self._writeFile)
def close(self): if _isDebug(): log.debug("Closing") self._onReceive = None if hasattr(self, "_file") and self._file is not INVALID_HANDLE_VALUE: ctypes.windll.kernel32.CancelIoEx(self._file, byref(self._readOl)) if hasattr(self, "_writeFile") and self._writeFile not in (self._file, INVALID_HANDLE_VALUE): ctypes.windll.kernel32.CancelIoEx(self._writeFile, byref(self._readOl)) winKernel.closeHandle(self._recvEvt)
def terminate(self): """Terminate this app module. This is called to perform any clean up when this app module is being destroyed. Subclasses should call the superclass method first. """ winKernel.closeHandle(self.processHandle) if self._inprocRegistrationHandle: ctypes.windll.rpcrt4.RpcSsDestroyClientContext(ctypes.byref(self._inprocRegistrationHandle)) if self.helperLocalBindingHandle: ctypes.windll.rpcrt4.RpcBindingFree(ctypes.byref(self.helperLocalBindingHandle))
def _getHidInfo(hwId, path): info = {"hardwareID": hwId, "devicePath": path} hwId = hwId.split("\\", 1)[1] if hwId.startswith("VID"): info["provider"] = "usb" info["usbID"] = hwId[:17] # VID_xxxx&PID_xxxx elif hwId.startswith("{00001124-0000-1000-8000-00805f9b34fb}"): info["provider"] = "bluetooth" else: # Unknown provider. info["provider"] = None return info # Fetch additional info about the HID device. from serial.win32 import CreateFile, INVALID_HANDLE_VALUE, FILE_FLAG_OVERLAPPED handle = CreateFile(path, 0, winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if handle == INVALID_HANDLE_VALUE: if _isDebug(): log.debugWarning( "Opening device {dev} to get additional info failed: {exc}". format(dev=path, exc=ctypes.WinError())) return info try: attribs = HIDD_ATTRIBUTES() if ctypes.windll.hid.HidD_GetAttributes(handle, ctypes.byref(attribs)): info["vendorID"] = attribs.VendorID info["productID"] = attribs.ProductID info["versionNumber"] = attribs.VersionNumber else: if _isDebug(): log.debugWarning("HidD_GetAttributes failed") buf = ctypes.create_unicode_buffer(128) bytes = ctypes.sizeof(buf) if ctypes.windll.hid.HidD_GetManufacturerString(handle, buf, bytes): info["manufacturer"] = buf.value if ctypes.windll.hid.HidD_GetProductString(handle, buf, bytes): info["product"] = buf.value pd = ctypes.c_void_p() if ctypes.windll.hid.HidD_GetPreparsedData(handle, ctypes.byref(pd)): try: caps = hidpi.HIDP_CAPS() ctypes.windll.hid.HidP_GetCaps(pd, ctypes.byref(caps)) info['HIDUsagePage'] = caps.UsagePage finally: ctypes.windll.hid.HidD_FreePreparsedData(pd) finally: winKernel.closeHandle(handle) return info
def getAppNameFromHost(processId): # Some apps that come with Windows 8 and 8.1 are hosted by wwahost.exe. # App modules for these are named after the hosted app name. processHandle = winKernel.openProcess(winKernel.SYNCHRONIZE|winKernel.PROCESS_QUERY_INFORMATION,False,processId) length = ctypes.c_uint() buf = winKernel.kernel32.GetApplicationUserModelId(processHandle, ctypes.byref(length), None) appModel = ctypes.create_unicode_buffer(buf) winKernel.kernel32.GetApplicationUserModelId(processHandle, ctypes.byref(length), appModel) winKernel.closeHandle(processHandle) # Sometimes app model might be empty, so raise errors and fall back to wwahost. if not appModel.value: raise LookupError # Convert this into lowercase to make the file name consistent with other NVDA app modules. return appModel.value.split("!")[-1].lower()
def _getHidInfo(hwId, path): info = {"hardwareID": hwId, "devicePath": path} hwId = hwId.split("\\", 1)[1] if hwId.startswith("VID"): info["provider"] = "usb" info["usbID"] = hwId[:17] # VID_xxxx&PID_xxxx return info if not hwId.startswith( "{00001124-0000-1000-8000-00805f9b34fb}"): # Not Bluetooth # Unknown provider. info["provider"] = None return info info["provider"] = "bluetooth" # Fetch additional info about the HID device. # This is a bit slow, so we only do it for Bluetooth, # as this info might be necessary to identify Bluetooth devices. from serial.win32 import CreateFile, INVALID_HANDLE_VALUE, FILE_FLAG_OVERLAPPED handle = CreateFile(path, 0, winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if handle == INVALID_HANDLE_VALUE: if _isDebug(): log.debug( u"Opening device {dev} to get additional info failed: {exc}". format(dev=path, exc=ctypes.WinError())) return info try: attribs = HIDD_ATTRIBUTES() if ctypes.windll.hid.HidD_GetAttributes(handle, ctypes.byref(attribs)): info["vendorID"] = attribs.VendorID info["productID"] = attribs.ProductID info["versionNumber"] = attribs.VersionNumber buf = ctypes.create_unicode_buffer(128) bytes = ctypes.sizeof(buf) if ctypes.windll.hid.HidD_GetManufacturerString(handle, buf, bytes): info["manufacturer"] = buf.value if ctypes.windll.hid.HidD_GetProductString(handle, buf, bytes): info["product"] = buf.value finally: winKernel.closeHandle(handle) return info
def getAppNameFromHost(processId): # Some apps that come with Windows 8 and 8.1 are hosted by wwahost.exe. # App modules for these are named after the hosted app name. processHandle = winKernel.openProcess( winKernel.SYNCHRONIZE | winKernel.PROCESS_QUERY_INFORMATION, False, processId) length = ctypes.c_uint() buf = winKernel.kernel32.GetApplicationUserModelId(processHandle, ctypes.byref(length), None) appModel = ctypes.create_unicode_buffer(buf) winKernel.kernel32.GetApplicationUserModelId(processHandle, ctypes.byref(length), appModel) winKernel.closeHandle(processHandle) # Sometimes app model might be empty, so raise errors and fall back to wwahost. if not appModel.value: raise LookupError # Convert this into lowercase to make the file name consistent with other NVDA app modules. return appModel.value.split("!")[-1].lower()
def _getHidInfo(hwId, path): info = { "hardwareID": hwId, "devicePath": path} hwId = hwId.split("\\", 1)[1] if hwId.startswith("VID"): info["provider"] = "usb" info["usbID"] = hwId[:17] # VID_xxxx&PID_xxxx return info if not hwId.startswith("{00001124-0000-1000-8000-00805f9b34fb}"): # Not Bluetooth # Unknown provider. info["provider"] = None return info info["provider"] = "bluetooth" # Fetch additional info about the HID device. # This is a bit slow, so we only do it for Bluetooth, # as this info might be necessary to identify Bluetooth devices. from serial.win32 import CreateFile, INVALID_HANDLE_VALUE, FILE_FLAG_OVERLAPPED handle = CreateFile(path, 0, winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE, None, winKernel.OPEN_EXISTING, FILE_FLAG_OVERLAPPED, None) if handle == INVALID_HANDLE_VALUE: if _isDebug(): log.debug(u"Opening device {dev} to get additional info failed: {exc}".format( dev=path, exc=ctypes.WinError())) return info try: attribs = HIDD_ATTRIBUTES() if ctypes.windll.hid.HidD_GetAttributes(handle, ctypes.byref(attribs)): info["vendorID"] = attribs.VendorID info["productID"] = attribs.ProductID info["versionNumber"] = attribs.VersionNumber buf = ctypes.create_unicode_buffer(128) bytes = ctypes.sizeof(buf) if ctypes.windll.hid.HidD_GetManufacturerString(handle, buf, bytes): info["manufacturer"] = buf.value if ctypes.windll.hid.HidD_GetProductString(handle, buf, bytes): info["product"] = buf.value finally: winKernel.closeHandle(handle) return info
def getListGroupInfo(windowHandle,groupIndex): (processID,threadID)=winUser.getWindowThreadProcessID(windowHandle) processHandle=oleacc.GetProcessHandleFromHwnd(windowHandle) localInfo=LVGROUP() localInfo.cbSize=sizeof(LVGROUP) localInfo.mask=LVGF_HEADER|LVGF_FOOTER|LVGF_STATE|LVGF_ALIGN|LVGF_GROUPID localInfo.stateMask=0xffffffff remoteInfo=winKernel.virtualAllocEx(processHandle,None,sizeof(LVGROUP),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE) winKernel.writeProcessMemory(processHandle,remoteInfo,byref(localInfo),sizeof(LVGROUP),None) messageRes=winUser.sendMessage(windowHandle,LVM_GETGROUPINFOBYINDEX,groupIndex,remoteInfo) winKernel.readProcessMemory(processHandle,remoteInfo,byref(localInfo),sizeof(LVGROUP),None) winKernel.virtualFreeEx(processHandle,remoteInfo,0,winKernel.MEM_RELEASE) localHeader=create_unicode_buffer(localInfo.cchHeader) winKernel.readProcessMemory(processHandle,localInfo.pszHeader,localHeader,localInfo.cchHeader*2,None) localFooter=create_unicode_buffer(localInfo.cchFooter) winKernel.readProcessMemory(processHandle,localInfo.pszFooter,localFooter,localInfo.cchFooter*2,None) winKernel.closeHandle(processHandle) if messageRes==1: return dict(header=localHeader.value,footer=localFooter.value,groupID=localInfo.iGroupId,state=localInfo.state,uAlign=localInfo.uAlign,groupIndex=groupIndex) else: return None
def close(self): super(Hid, self).close() winKernel.closeHandle(self._file) self._file = None hidDll.HidD_FreePreparsedData(self._pd)
def close(self): if not self._file: return super(Hid, self).close() winKernel.closeHandle(self._file) self._file = None
def close(self): super(Bulk, self).close() if hasattr(self, "_file") and self._file is not INVALID_HANDLE_VALUE: winKernel.closeHandle(self._file) if hasattr(self, "_writeFile") and self._writeFile is not INVALID_HANDLE_VALUE: winKernel.closeHandle(self._writeFile)
def __del__(self): winKernel.closeHandle(self.processHandle)
def close(self): super(Hid, self).close() winKernel.closeHandle(self._file)
def terminate(self): # Closing the write end of the pipe will cause EOF for the waiting loader process, which will then exit gracefully. winKernel.closeHandle(self._pipeWrite) # Wait until it's dead. winKernel.waitForSingleObject(self._process, winKernel.INFINITE) winKernel.closeHandle(self._process)
def close(self): super(Hid, self).close() winKernel.closeHandle(self._file) self._file = None