def ReadFile(handle, desired_bytes): """Calls kernel32.ReadFile().""" c_read = wintypes.DWORD() buff = wintypes.create_string_buffer(desired_bytes + 1) windll.kernel32.ReadFile(handle, buff, desired_bytes, wintypes.byref(c_read), None) # NULL terminate it. buff[c_read.value] = '\x00' return wintypes.GetLastError(), buff.value
def PeekNamedPipe(handle): """Calls kernel32.PeekNamedPipe(). Simplified version.""" c_avail = wintypes.DWORD() c_message = wintypes.DWORD() success = windll.kernel32.PeekNamedPipe(handle, None, 0, None, wintypes.byref(c_avail), wintypes.byref(c_message)) if not success: raise OSError(wintypes.GetLastError()) return c_avail.value
def ReadBytes(self, address, num_bytes): """Reads at most num_bytes starting from offset <address>.""" address = int(address) buf = ctypes.create_string_buffer(num_bytes) bytesread = ctypes.c_size_t(0) res = ReadProcessMemory(self.h_process, address, buf, num_bytes, ctypes.byref(bytesread)) if res == 0: err = wintypes.GetLastError() if err == 299: # Only part of ReadProcessMemory has been done, let's return it. return buf.raw[:bytesread.value] raise process_error.ProcessError("Error in ReadProcessMemory: %d" % err) return buf.raw[:bytesread.value]
def acquire(self): """Tries to acquire the singleton. Returns: True if there was no previous process, False if this process is a duplicate and should exit. """ if sys.platform == 'win32': # Create a global mutex. Make the mutex so that it disapear automatically # when the process dies. The handle is not inherited so task_runner # doesn't get to keep it alive. # pylint: disable=undefined-variable self.handle = wintypes.windll.kernel32.CreateMutexW( wintypes.c_int(0), wintypes.c_int(-1), wintypes.create_unicode_buffer(self.key)) last_error = wintypes.GetLastError() logging.info('[singleton] acquire: %s = %s ; %s', self.key, self.handle, last_error) if not self.handle: return False # ERROR_ALREADY_EXISTS if last_error == 183: self.release() return bool(self.handle) else: self.handle = open(self.key, 'a+b') try: fcntl.flock(self.handle, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError: # There's a small race condition where it could report a previous pid. logging.exception('Singleton "%s" is held by "%s"', self.key, self.handle.read()) self.handle.close() self.handle = None return False logging.info('[singleton] acquire: %s = %s', self.key, self.handle) self.handle.seek(0, os.SEEK_SET) self.handle.truncate(0) self.handle.write(str(os.getpid()).encode('utf-8')) return True