def Main(pipeName, debugLevel): if debugLevel: def Debug(msg): sys.stdout.write(msg + "\n") else: def Debug(msg): pass if not WaitNamedPipe(pipeName, 5000): raise WinError() hPipe = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, None, OPEN_EXISTING, 0, None) if hPipe == INVALID_HANDLE_VALUE: raise WinError() try: # The pipe connected; change to message-read mode. dwMode = DWORD(PIPE_READMODE_MESSAGE) if not SetNamedPipeHandleState(hPipe, byref(dwMode), None, None): raise WinError() sys.stderr = PipeStream(hPipe, MESSAGE_STDERR) sys.stdout = PipeStream(hPipe, MESSAGE_STDOUT) Debug("reading startup message") code, (scriptPath, funcName, args, kwargs) = ReadPipeMessage(hPipe) Debug("got startup message:\n" " path: %r\n" " funcName: %r\n" " args: %r\n" " kwargs: %r" % (scriptPath, funcName, args, kwargs)) if code != MESSAGE_ARGS: raise Exception("Unexpected message type") try: moduleName = splitext(basename(scriptPath))[0] try: moduleInfo = imp.find_module(moduleName, [dirname(scriptPath)]) except ImportError: import zipimport for entry in sys.path: if entry.endswith('.zip'): zipImporter = zipimport.zipimporter(entry) try: module = zipImporter.load_module(moduleName) except zipimport.ZipImportError: continue else: module = imp.load_module(moduleName, *moduleInfo) func = getattr(module, funcName) result = func(*args, **kwargs) Debug("result: %r" % result) except: WritePipeMessage(hPipe, MESSAGE_EXCEPTION, FormatException(sys.exc_info())) else: WritePipeMessage(hPipe, MESSAGE_RESULT, result) finally: CloseHandle(hPipe)
def ExecAs(scriptPath, asAdministrator, funcName, *args, **kwargs): pipeName = "\\\\.\\pipe\\" + str(GUID.create_new()) Msg("creating named pipe") hPipe = CreateNamedPipe( pipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE, 0, None ) if hPipe == INVALID_HANDLE_VALUE: raise Exception("Error in creating Named Pipe") overlapped = OVERLAPPED() overlapped.hEvent = CreateEvent(None, 1, 0, None) try: Msg("calling ConnectNamedPipe") ConnectNamedPipe(hPipe, byref(overlapped)) localPath = dirname(__file__.decode('mbcs')) Msg("starting subprocess") hProcess = RunAs( abspath(join(localPath, "..", "..", "EventGhost.exe")), asAdministrator, "-execfile", GetUncPathOf(join(localPath, "PipedProcessClient.py")), pipeName, str(eg.debugLevel) ) Msg("waiting for subprocess to connect") pHandles = (HANDLE * 2)(overlapped.hEvent, hProcess) ret = WaitForMultipleObjects(2, pHandles, 0, 25000) if ret == WAIT_OBJECT_0: # connect event Msg("got connect event") elif ret == WAIT_OBJECT_0 + 1: raise Exception("Unexpected end of subprocess.") elif ret == WAIT_TIMEOUT: raise Exception("Timeout in waiting for subprocess.") else: raise Exception("Unknown return value") Msg("sending startup message") WritePipeMessage( hPipe, MESSAGE_ARGS, (GetUncPathOf(scriptPath), funcName, args, kwargs) ) chBuf = create_string_buffer(BUFSIZE) cbRead = DWORD(0) while True: fSuccess = ReadFile(hPipe, chBuf, BUFSIZE, byref(cbRead), None) if ((fSuccess == 1) or (cbRead.value != 0)): code, data = loads(chBuf.value) if code == MESSAGE_STDERR: sys.stderr.write(data) elif code == MESSAGE_STDOUT: sys.stdout.write(data) elif code == MESSAGE_RESULT: result = data break elif code == MESSAGE_EXCEPTION: break else: raise Exception("Unknown message type %r" % code) FlushFileBuffers(hPipe) DisconnectNamedPipe(hPipe) finally: CloseHandle(hPipe) CloseHandle(overlapped.hEvent) if code == MESSAGE_EXCEPTION: raise Exception("Child process raised an exception\n" + data) return result