Example #1
0
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)
Example #2
0
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)
Example #3
0
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)
Example #4
0
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])
Example #5
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)
Example #6
0
 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)
Example #7
0
 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)
Example #8
0
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())
Example #9
0
 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)
Example #10
0
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)
Example #11
0
 def test_stderr_handle(self):
     _, library = dist.load()
     self.assertEqual(
         GetStdHandle(library.STD_ERROR_HANDLE),
         HANDLE(library.GetStdHandle(library.STD_ERROR_HANDLE)))
Example #12
0
 def test_stdout_handle(self):
     _, library = dist.load()
     self.assertEqual(
         GetStdHandle(library.STD_OUTPUT_HANDLE),
         HANDLE(library.GetStdHandle(library.STD_OUTPUT_HANDLE)))
Example #13
0
 def test_hStdError_set(self):
     info = STARTUPINFO()
     handle = HANDLE()
     info.hStdError = handle
     self.assertEqual(info.hStdError, handle)
Example #14
0
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)
Example #15
0
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])
Example #16
0
 def test_attr_hEvent_assign(self):
     o = OVERLAPPED()
     h = HANDLE()
     o.hEvent = h
     self.assertIsNot(o.hEvent, h)
     self.assertEqual(o.hEvent, h)
Example #17
0
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)
Example #18
0
 def test_hStdOutput_set(self):
     info = STARTUPINFO()
     handle = HANDLE()
     info.hStdOutput = handle
     self.assertEqual(info.hStdOutput, handle)