def GetStdHandle(nStdHandle): """ Retrieves a handle to the specified standard device (standard input, standard output, or standard error). .. seealso:: https://msdn.microsoft.com/en-us/library/ms683231 :param int nStdHandle: The standard device to retrieve. :rtype: pywincffi.wintypes.HANDLE :return: Returns a handle to the standard device retrieved. """ _, library = dist.load() input_check("nStdHandle", nStdHandle, allowed_values=(library.STD_INPUT_HANDLE, library.STD_OUTPUT_HANDLE, library.STD_ERROR_HANDLE)) handle = library.GetStdHandle(nStdHandle) if handle == library.INVALID_HANDLE_VALUE: # pragma: no cover raise WindowsAPIError( "GetStdHandle", "Invalid Handle", library.INVALID_HANDLE_VALUE, expected_return_code="not %r" % library.INVALID_HANDLE_VALUE) return HANDLE(handle)
def OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId): """ Opens an existing local process object. .. seealso:: https://msdn.microsoft.com/en-us/library/ms684320 :param int dwDesiredAccess: The required access to the process object. :param bool bInheritHandle: Enables or disable handle inheritance for child processes. :param int dwProcessId: The id of the local process to be opened. :returns: Returns a :class:`pywincffi.wintypes.HANDLE` to the opened process. This value can be used by other functions such as :func:`TerminateProcess`. """ input_check("dwDesiredAccess", dwDesiredAccess, integer_types) input_check("bInheritHandle", bInheritHandle, bool) input_check("dwProcessId", dwProcessId, integer_types) ffi, library = dist.load() handle = library.OpenProcess(ffi.cast("DWORD", dwDesiredAccess), ffi.cast("BOOL", bInheritHandle), ffi.cast("DWORD", dwProcessId)) error_check("OpenProcess") return HANDLE(handle)
def OpenEvent(dwDesiredAccess, bInheritHandle, lpName): """ Opens an existing named event. .. seealso:: https://msdn.microsoft.com/en-us/library/ms684305 :param int dwDesiredAccess: The access desired for the event object. :param bool bInheritHandle: :param str lpName: Type is ``unicode`` on Python 2, ``str`` on Python 3. :return: Returns a :class:`pywincffi.wintypes.HANDLE` to the event. """ input_check("dwDesiredAccess", dwDesiredAccess, integer_types) input_check("bInheritHandle", bInheritHandle, bool) input_check("lpName", lpName, text_type) ffi, library = dist.load() handle = library.OpenEvent(ffi.cast("DWORD", dwDesiredAccess), ffi.cast("BOOL", bInheritHandle), lpName) error_check("OpenEvent") return HANDLE(handle)
def CreatePipe(nSize=0, lpPipeAttributes=None): """ Creates an anonymous pipe and returns the read and write handles. .. seealso:: https://msdn.microsoft.com/en-us/library/aa365152 https://msdn.microsoft.com/en-us/library/aa379560 >>> from pywincffi.core import dist >>> from pywincffi.kernel32 import CreatePipe >>> from pywincffi.wintypes import SECURITY_ATTRIBUTES >>> lpPipeAttributes = SECURITY_ATTRIBUTES() >>> lpPipeAttributes.bInheritHandle = True >>> reader, writer = CreatePipe(lpPipeAttributes=lpPipeAttributes) :keyword int nSize: The size of the buffer in bytes. Passing in 0, which is the default will cause the system to use the default buffer size. :keyword pywincffi.wintypes.SECURITY_ATTRIBUTES lpPipeAttributes: The security attributes to apply to the handle. By default ``NULL`` will be passed in, meaning the handle we create cannot be inherited. For more detailed information see the links below. :return: Returns a tuple of :class:`pywincffi.wintype.HANDLE` containing the reader and writer ends of the pipe that was created. The user of this function is responsible for calling CloseHandle at some point. """ input_check("nSize", nSize, integer_types) input_check( "lpPipeAttributes", lpPipeAttributes, allowed_types=(NoneType, SECURITY_ATTRIBUTES) ) lpPipeAttributes = wintype_to_cdata(lpPipeAttributes) ffi, library = dist.load() hReadPipe = ffi.new("PHANDLE") hWritePipe = ffi.new("PHANDLE") code = library.CreatePipe(hReadPipe, hWritePipe, lpPipeAttributes, nSize) error_check("CreatePipe", code=code, expected=NON_ZERO) return HANDLE(hReadPipe[0]), HANDLE(hWritePipe[0])
def CreateEvent(bManualReset, bInitialState, lpEventAttributes=None, lpName=None): """ Creates or opens an named or unnamed event object. .. seealso:: https://msdn.microsoft.com/en-us/library/ms682396 :param bool bManualReset: If True then this function will create a manual reset event which must be manually reset with :func:`ResetEvent`. Refer to the msdn documentation for full information. :param bool bInitialState: If True the initial state will be 'signaled'. :keyword :class:`pywincffi.wintypes.SECURITY_ATTRIBUTES` lpEventAttributes: If not provided then, by default, the handle cannot be inherited by a subprocess. :keyword str lpName: Type is ``unicode`` on Python 2, ``str`` on Python 3. The optional case-sensitive name of the event. If not provided then the event will be created without an explicit name. :returns: Returns a :class:`pywincffi.wintypes.HANDLE` to the event. If an event by the given name already exists then it will be returned instead of creating a new event. """ input_check("bManualReset", bManualReset, bool) input_check("bInitialState", bInitialState, bool) ffi, library = dist.load() if lpName is None: lpName = ffi.NULL else: input_check("lpName", lpName, text_type) input_check("lpEventAttributes", lpEventAttributes, allowed_types=(SECURITY_ATTRIBUTES, NoneType)) handle = library.CreateEvent(wintype_to_cdata(lpEventAttributes), ffi.cast("BOOL", bManualReset), ffi.cast("BOOL", bInitialState), lpName) try: error_check("CreateEvent") except WindowsAPIError as error: if error.errno != library.ERROR_ALREADY_EXISTS: raise return HANDLE(handle)
def _set_handle_info_socket(self, inherit, check=False): ffi, library = dist.load() sock = socket.socket() self.addCleanup(sock.close) sock_handle = HANDLE(ffi.cast("void *", sock.fileno())) SetHandleInformation(sock_handle, library.HANDLE_FLAG_INHERIT, inherit) if check: result = GetHandleInformation(sock_handle) self.assertEqual(inherit, result)
def test_get_handle_info_socket(self): ffi, library = dist.load() sock = socket.socket() self.addCleanup(sock.close) sock_handle = HANDLE(ffi.cast("void *", sock.fileno())) handle_flags = GetHandleInformation(sock_handle) inherit = handle_flags & library.HANDLE_FLAG_INHERIT expected = self._expected_inheritance() self.assertEqual(inherit, expected)
def GetCurrentProcess(): """ Returns a handle to the current thread. .. seealso:: https://msdn.microsoft.com/en-us/library/ms683179 .. note:: Calling :func:`pywincffi.kernel32.handle.CloseHandle` on the handle produced by this function will produce an exception. :returns: The :class:`pywincffi.wintypes.HANDLE` to the current process. """ _, library = dist.load() return HANDLE(library.GetCurrentProcess())
def test_socket_rebind_after_spawn(self): ffi, library = dist.load() bind_addr = (('127.0.0.1', 0)) sock = socket.socket() try: sock.bind(bind_addr) bind_addr = sock.getsockname() sock_handle = HANDLE(ffi.cast("void *", sock.fileno())) # prevent file_handle inheritance SetHandleInformation(sock_handle, library.HANDLE_FLAG_INHERIT, 0) # spawn child while sock is bound child = self._spawn_child() self.addCleanup(self._cleanup_child, child) finally: sock.close() sock = socket.socket() self.addCleanup(sock.close) # re-bind to same address: works if not inherited by child sock.bind(bind_addr)
def CreateToolhelp32Snapshot(dwFlags, th32ProcessID): """ Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes. .. seealso:: https://msdn.microsoft.com/en-us/ms682489 :param int dwFlags: The portions of the system to be included in the snapshot. :param int th32ProcessID: The process identifier of the process to be included in the snapshot. :rtype: :class:`pywincffi.wintypes.HANDLE` :return: If the function succeeds, it returns an open handle to the specified snapshot. """ input_check("dwFlags", dwFlags, integer_types) input_check("th32ProcessID", th32ProcessID, integer_types) ffi, library = dist.load() process_list = library.CreateToolhelp32Snapshot( ffi.cast("DWORD", dwFlags), ffi.cast("DWORD", th32ProcessID) ) if process_list == library.INVALID_HANDLE_VALUE: # pragma: no cover raise WindowsAPIError( "CreateToolhelp32Snapshot", "Invalid Handle", library.INVALID_HANDLE_VALUE, expected_return_code="not %r" % library.INVALID_HANDLE_VALUE) error_check("CreateToolhelp32Snapshot") return HANDLE(process_list)
def test_stderr_handle(self): _, library = dist.load() self.assertEqual( GetStdHandle(library.STD_ERROR_HANDLE), HANDLE(library.GetStdHandle(library.STD_ERROR_HANDLE)))
def test_stdout_handle(self): _, library = dist.load() self.assertEqual( GetStdHandle(library.STD_OUTPUT_HANDLE), HANDLE(library.GetStdHandle(library.STD_OUTPUT_HANDLE)))
def test_hStdError_set(self): info = STARTUPINFO() handle = HANDLE() info.hStdError = handle self.assertEqual(info.hStdError, handle)
def CreateConsoleScreenBuffer( dwDesiredAccess, dwShareMode, lpSecurityAttributes=None, dwFlags=None): """ Creates a console screen buffer. .. seealso:: https://docs.microsoft.com/en-us/windows/console/createconsolescreenbuffer :type dwDesiredAccess: int or None :param dwDesiredAccess: The access to the console screen buffer. If `None` is provided then the Windows APIs will use a default security descriptor. :type dwShareMode: int or None :param dwShareMode: Controls the options for sharing the resulting handle. If `None` or 0 then the resulting buffer cannot be shared. :keyword pywincffi.wintypes.SECURITY_ATTRIBUTES lpSecurityAttributes: Extra security attributes that determine if the resulting handle can be inherited. If `None` is provided, which is the default, then the handle cannot be inherited. :keyword int dwFlags: The type of console buffer to create. The flag is superficial because it only accepts None or ``CONSOLE_TEXTMODE_BUFFER`` as inputs. If no value is provided, which is the default, then ``CONSOLE_TEXTMODE_BUFFER`` is automatically used. :rtype: :class:`pywincffi.wintypes.HANDLE`` :returns: Returns the handle created by the underlying C function. :func:`pywincffi.kernel32.CloseHandle` should be called on the handle when you are done with it. """ ffi, library = dist.load() if dwDesiredAccess is None: dwDesiredAccess = ffi.NULL if dwShareMode is None: dwShareMode = 0 if dwFlags is None: dwFlags = library.CONSOLE_TEXTMODE_BUFFER input_check( "dwDesiredAccess", dwDesiredAccess, allowed_values=( ffi.NULL, library.GENERIC_READ, library.GENERIC_WRITE, library.GENERIC_READ | library.GENERIC_WRITE )) input_check( "dwShareMode", dwShareMode, allowed_values=( 0, library.FILE_SHARE_READ, library.FILE_SHARE_WRITE, library.FILE_SHARE_READ | library.FILE_SHARE_WRITE, )) input_check( "dwFlags", dwFlags, allowed_values=( library.CONSOLE_TEXTMODE_BUFFER, )) input_check( "lpSecurityAttributes", lpSecurityAttributes, allowed_types=(NoneType, SECURITY_ATTRIBUTES)) if lpSecurityAttributes is None: lpSecurityAttributes = ffi.NULL handle = library.CreateConsoleScreenBuffer( ffi.cast("DWORD", dwDesiredAccess), ffi.cast("DWORD", dwShareMode), lpSecurityAttributes, ffi.cast("DWORD", dwFlags), ffi.NULL # _reserved_ ) if handle == library.INVALID_HANDLE_VALUE: # pragma: no cover raise WindowsAPIError( "CreateConsoleScreenBuffer", "Invalid Handle", library.INVALID_HANDLE_VALUE, expected_return_code="not INVALID_HANDLE_VALUE") return HANDLE(handle)
def DuplicateHandle( # pylint: disable=too-many-arguments hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, dwDesiredAccess, bInheritHandle, dwOptions): """ Duplicates an object handle. .. seealso:: https://msdn.microsoft.com/en-us/ms724251 :param pywincffi.wintypes.HANDLE hSourceProcessHandle: A handle to the process which owns the handle to be duplicated. :param pywincffi.wintypes.HANDLE hSourceHandle: The handle to be duplicated. :param pywincffi.wintypes.HANDLE hTargetProcessHandle: A handle to the process which should receive the duplicated handle. :param int dwDesiredAccess: The access requested for the new handle. :param bool bInheritHandle: True if the handle should be inheritable by new processes. :param int dwOptions: Options which control how the handle is duplicated. Valid values are any of the below (or a combination of): * ``DUPLICATE_CLOSE_SOURCE`` - Closes the source handle, even if there's an error. * ``DUPLICATE_SAME_ACCESS`` - Ignores the ``dwDesiredAccess`` parameter duplicates with the same access as the original handle. :rtype: pywincffi.wintypes.HANDLE :return: Returns the duplicated handle. """ ffi, library = dist.load() input_check("hSourceProcessHandle", hSourceProcessHandle, HANDLE) input_check("hSourceHandle", hSourceHandle, HANDLE) input_check("hTargetProcessHandle", hTargetProcessHandle, HANDLE) input_check("dwDesiredAccess", dwDesiredAccess, integer_types) input_check("bInheritHandle", bInheritHandle, bool) input_check("dwOptions", dwOptions, allowed_values=( library.DUPLICATE_CLOSE_SOURCE, library.DUPLICATE_SAME_ACCESS, library.DUPLICATE_CLOSE_SOURCE | library.DUPLICATE_SAME_ACCESS )) lpTargetHandle = ffi.new("LPHANDLE") code = library.DuplicateHandle( wintype_to_cdata(hSourceProcessHandle), wintype_to_cdata(hSourceHandle), wintype_to_cdata(hTargetProcessHandle), lpTargetHandle, ffi.cast("DWORD", dwDesiredAccess), ffi.cast("BOOL", bInheritHandle), ffi.cast("DWORD", dwOptions) ) error_check("DuplicateHandle", code, expected=Enums.NON_ZERO) return HANDLE(lpTargetHandle[0])
def test_attr_hEvent_assign(self): o = OVERLAPPED() h = HANDLE() o.hEvent = h self.assertIsNot(o.hEvent, h) self.assertEqual(o.hEvent, h)
def CreateFile( # pylint: disable=too-many-arguments lpFileName, dwDesiredAccess, dwShareMode=None, lpSecurityAttributes=None, dwCreationDisposition=None, dwFlagsAndAttributes=None, hTemplateFile=None): """ Creates or opens a file or other I/O device. Default values are provided for some of the default arguments for CreateFile() so its behavior is close to Pythons :func:`open` function. .. seealso:: https://msdn.microsoft.com/en-us/library/aa363858 https://msdn.microsoft.com/en-us/library/gg258116 :param str lpFileName: Type is ``unicode`` on Python 2, ``str`` on Python 3. The path to the file or device being created or opened. :param int dwDesiredAccess: The requested access to the file or device. Microsoft's documentation has extensive notes on this parameter in the seealso links above. :keyword int dwShareMode: Access and sharing rights to the handle being created. If not provided with an explicit value, ``FILE_SHARE_READ`` will be used which will other open operations or process to continue to read from the file. :keyword pywincffi.wintypes.SECURITY_ATTRIBUTES lpSecurityAttributes: See Microsoft's documentation for more detailed information. :keyword int dwCreationDisposition: Action to take when the file or device does not exist. If not provided with an explicit value, ``CREATE_ALWAYS`` will be used which means existing files will be overwritten. :keyword int dwFlagsAndAttributes: The file or device attributes and flags. If not provided an explict value, ``FILE_ATTRIBUTE_NORMAL`` will be used giving the handle essentially no special attributes. :keyword pywincffi.wintypes.HANDLE hTemplateFile: A handle to a template file with the ``GENERIC_READ`` access right. See Microsoft's documentation for more information. If not provided an explicit value, ``NULL`` will be used instead. :return: The file :class:`pywincffi.wintypes.HANDLE` created by ``CreateFile``. """ _, library = dist.load() if dwShareMode is None: dwShareMode = library.FILE_SHARE_READ if dwCreationDisposition is None: dwCreationDisposition = library.CREATE_ALWAYS if dwFlagsAndAttributes is None: dwFlagsAndAttributes = library.FILE_ATTRIBUTE_NORMAL input_check("lpFileName", lpFileName, text_type) input_check("dwDesiredAccess", dwDesiredAccess, integer_types) input_check("dwShareMode", dwShareMode, integer_types) input_check("lpSecurityAttributes", lpSecurityAttributes, allowed_types=(NoneType, SECURITY_ATTRIBUTES)) input_check("dwCreationDisposition", dwCreationDisposition, allowed_values=(library.CREATE_ALWAYS, library.CREATE_NEW, library.OPEN_ALWAYS, library.OPEN_EXISTING, library.TRUNCATE_EXISTING)) input_check("dwFlagsAndAttributes", dwFlagsAndAttributes, integer_types) input_check("hTemplateFile", hTemplateFile, (NoneType, HANDLE)) handle = library.CreateFile(lpFileName, dwDesiredAccess, dwShareMode, wintype_to_cdata(lpSecurityAttributes), dwCreationDisposition, dwFlagsAndAttributes, wintype_to_cdata(hTemplateFile)) try: error_check("CreateFile") except WindowsAPIError as error: # ERROR_ALREADY_EXISTS may be a normal condition depending # on the creation disposition. if (dwCreationDisposition == library.CREATE_ALWAYS and error.errno == library.ERROR_ALREADY_EXISTS): return HANDLE(handle) raise return HANDLE(handle)
def test_hStdOutput_set(self): info = STARTUPINFO() handle = HANDLE() info.hStdOutput = handle self.assertEqual(info.hStdOutput, handle)