Ejemplo n.º 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)
Ejemplo n.º 2
0
def SetConsoleTextAttribute(hConsoleOutput, wAttributes):
    """
    Sets the attributes of characters written to a console buffer.

    .. seealso::

        https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute

    :param pywincffi.wintypes.HANDLE hConsoleOutput:
        A handle to the console screen buffer. The handle must have the
        ``GENERIC_READ`` access right.

    :param int wAttributes:
        The character attribute(s) to set.
    """
    input_check("hConsoleOutput", hConsoleOutput, HANDLE)
    input_check("wAttributes", wAttributes, integer_types)
    ffi, library = dist.load()
    # raise Exception(type(wAttributes))
    # info = ffi.new("PCHAR_INFO")
    code = library.SetConsoleTextAttribute(
        wintype_to_cdata(hConsoleOutput),
        ffi.cast("ATOM", wAttributes)
    )
    error_check("SetConsoleTextAttribute", code=code, expected=NON_ZERO)
Ejemplo n.º 3
0
def ClearCommError(hFile):
    """
    Retrieves information about a communications error and reports the
    current status of a communications device.

    .. seealso::

        https://msdn.microsoft.com/en-us/aa363180

    :param pywincffi.wintypes.HANDLE hFile:
        A handle to the communications device, typically created by
        :func:`CreateFile`

    :rtype: tuple
    :return:
        Returns a two element tuple containing the ``lpErrors`` and
        ``lpStat`` result objects.

            * ``lpErrors`` - Contains the mast indicating the type of error
            * ``lpStat`` - A ``COMSTAT`` structure which contains the device's
               information.
    """
    input_check("hFile", hFile, HANDLE)

    ffi, library = dist.load()

    lpErrors = ffi.new("LPDWORD")
    lpStat = ffi.new("LPCOMSTAT")
    code = library.ClearCommError(wintype_to_cdata(hFile), lpErrors, lpStat)
    error_check("ClearCommError", code=code, expected=Enums.NON_ZERO)

    # TODO: Build Python instance of COMSTAT here!
    return lpErrors, lpStat
Ejemplo n.º 4
0
def WaitForSingleObject(hHandle, dwMilliseconds):
    """
    Waits for the specified object to be in a signaled state
    or for ``dwMiliseconds`` to elapse.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms687032

    :param pywincffi.wintypes.HANDLE hHandle:
        The handle to wait on.

    :param int dwMilliseconds:
        The time-out interval.
    """
    input_check("hHandle", hHandle, HANDLE)
    input_check("dwMilliseconds", dwMilliseconds, integer_types)

    ffi, library = dist.load()
    result = library.WaitForSingleObject(
        wintype_to_cdata(hHandle), ffi.cast("DWORD", dwMilliseconds)
    )

    if result == library.WAIT_FAILED:
        raise WindowsAPIError(
            "WaitForSingleObject", "Wait Failed", ffi.getwinerror()[-1],
            return_code=result, expected_return_code="not %s" % result)

    error_check("WaitForSingleObject")

    return result
Ejemplo n.º 5
0
def WSAEnumNetworkEvents(socket, hEventObject=None):
    """
    Discovers occurrences of network events on the indicated ``socket``, clears
    internal events and optionally resets event objects.

    .. seealso::
        https://msdn.microsoft.com/en-us/ms741572

    :param pywincffi.wintypes.objects.SOCKET socket:
        The socket object to enumerate events for.

    :keyword pywincffi.wintypes.objects.WSAEVENT hEventObject:
        An optional handle identify an associated event object
        to be reset.

    :rtype: :class:`pywincffi.wintypes.structures.LPWSANETWORKEVENTS`
    :return:
    """
    input_check("socket", socket, allowed_types=(SOCKET, ))

    ffi, library = dist.load()
    if hEventObject is not None:
        input_check("hEventObject", hEventObject, allowed_types=(WSAEVENT, ))
        hEventObject = wintype_to_cdata(hEventObject)
    else:
        hEventObject = ffi.NULL

    lpNetworkEvents = LPWSANETWORKEVENTS()
    code = library.WSAEnumNetworkEvents(wintype_to_cdata(socket), hEventObject,
                                        wintype_to_cdata(lpNetworkEvents))
    error_check("WSAEnumNetworkEvents", code=code, expected=0)

    return lpNetworkEvents
Ejemplo n.º 6
0
def GetExitCodeProcess(hProcess):
    """
    Retrieves the exit code of the given process handle.  To retrieve
    a process handle use :func:`OpenProcess`.

    .. warning::

        You may want to use :func:`process_exit_code` instead of this
        function if you're just checking to see if a process has
        exited at all.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms683189

    :param pywincffi.wintypes.HANDLE hProcess:
        The handle of the process to retrieve the exit code for.

    :returns:
        Returns the exit code of the requested process if one
        can be found.
    """
    input_check("hProcess", hProcess, HANDLE)

    ffi, library = dist.load()
    lpExitCode = ffi.new("LPDWORD")
    code = library.GetExitCodeProcess(wintype_to_cdata(hProcess), lpExitCode)
    error_check("GetExitCodeProcess", code=code, expected=Enums.NON_ZERO)
    return lpExitCode[0]
Ejemplo n.º 7
0
def GetExitCodeProcess(hProcess):
    """
    Retrieves the exit code of the given process handle.  To retrieve
    a process handle use :func:`OpenProcess`.

    .. warning::

        You may want to use :func:`process_exit_code` instead of this
        function if you're just checking to see if a process has
        exited at all.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms683189

    :param pywincffi.wintypes.HANDLE hProcess:
        The handle of the process to retrieve the exit code for.

    :returns:
        Returns the exit code of the requested process if one
        can be found.
    """
    input_check("hProcess", hProcess, HANDLE)

    ffi, library = dist.load()
    lpExitCode = ffi.new("LPDWORD")
    code = library.GetExitCodeProcess(wintype_to_cdata(hProcess), lpExitCode)
    error_check("GetExitCodeProcess", code=code, expected=NON_ZERO)
    return lpExitCode[0]
Ejemplo n.º 8
0
def WaitForSingleObject(hHandle, dwMilliseconds):
    """
    Waits for the specified object to be in a signaled state
    or for ``dwMiliseconds`` to elapse.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms687032

    :param pywincffi.wintypes.HANDLE hHandle:
        The handle to wait on.

    :param int dwMilliseconds:
        The time-out interval.
    """
    input_check("hHandle", hHandle, HANDLE)
    input_check("dwMilliseconds", dwMilliseconds, integer_types)

    ffi, library = dist.load()
    result = library.WaitForSingleObject(wintype_to_cdata(hHandle),
                                         ffi.cast("DWORD", dwMilliseconds))

    if result == library.WAIT_FAILED:
        raise WindowsAPIError("WaitForSingleObject",
                              "Wait Failed",
                              ffi.getwinerror()[-1],
                              return_code=result,
                              expected_return_code="not %s" % result)

    error_check("WaitForSingleObject")

    return result
Ejemplo n.º 9
0
    def test_invalid(self):
        fd, path = tempfile.mkstemp()
        os.close(fd)
        self.addCleanup(os.remove, path)

        with self.assertRaises(InputError):
            input_check("", path, Enums.PYFILE)
Ejemplo n.º 10
0
def LockFileEx(hFile,
               dwFlags,
               nNumberOfBytesToLockLow,
               nNumberOfBytesToLockHigh,
               lpOverlapped=None):
    """
    Locks ``hFile`` for exclusive access by the calling process.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365203

    :param pywincffi.wintypes.HANDLE hFile:
        The handle to the file to lock.  This handle must have been
        created with either the ``GENERIC_READ`` or ``GENERIC_WRITE``
        right.

    :param int dwFlags:
        One or more of the following flags:

            * ``LOCKFILE_EXCLUSIVE_LOCK`` - Request an exclusive lock.
            * ``LOCKFILE_FAIL_IMMEDIATELY`` - Return immediately if the lock
              could not be acquired.  Otherwise :func:`LockFileEx` will wait.

    :param int nNumberOfBytesToLockLow:
        The start of the byte range to lock.

    :param int nNumberOfBytesToLockHigh:
        The end of the byte range to lock.

    :keyword pywincffi.wintypes.OVERLAPPED lpOverlapped:
        The underlying Windows API requires lpOverlapped, which acts both
        an input argument and may contain results after calling. If None is
        provided, a throw-away zero-filled instance will be created to
        support such call. See Microsoft's documentation for intended usage.
    """
    input_check("hFile", hFile, HANDLE)
    input_check("dwFlags", dwFlags, integer_types)
    input_check("nNumberOfBytesToLockLow", nNumberOfBytesToLockLow,
                integer_types)
    input_check("nNumberOfBytesToLockHigh", nNumberOfBytesToLockHigh,
                integer_types)

    ffi, library = dist.load()

    if lpOverlapped is None:
        # Required by Windows API, create a throw-away zero-filled instance.
        lpOverlapped = OVERLAPPED()
    else:
        input_check("lpOverlapped", lpOverlapped, allowed_types=OVERLAPPED)

    code = library.LockFileEx(
        wintype_to_cdata(hFile),
        ffi.cast("DWORD", dwFlags),
        ffi.cast("DWORD", 0),  # "_Reserveved_"
        ffi.cast("DWORD", nNumberOfBytesToLockLow),
        ffi.cast("DWORD", nNumberOfBytesToLockHigh),
        wintype_to_cdata(lpOverlapped))
    error_check("LockFileEx", code=code, expected=NON_ZERO)
Ejemplo n.º 11
0
def LockFileEx(
        hFile, dwFlags, nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh,
        lpOverlapped=None):
    """
    Locks ``hFile`` for exclusive access by the calling process.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365203

    :param pywincffi.wintypes.HANDLE hFile:
        The handle to the file to lock.  This handle must have been
        created with either the ``GENERIC_READ`` or ``GENERIC_WRITE``
        right.

    :param int dwFlags:
        One or more of the following flags:

            * ``LOCKFILE_EXCLUSIVE_LOCK`` - Request an exclusive lock.
            * ``LOCKFILE_FAIL_IMMEDIATELY`` - Return immediately if the lock
              could not be acquired.  Otherwise :func:`LockFileEx` will wait.

    :param int nNumberOfBytesToLockLow:
        The start of the byte range to lock.

    :param int nNumberOfBytesToLockHigh:
        The end of the byte range to lock.

    :keyword pywincffi.wintypes.OVERLAPPED lpOverlapped:
        The underlying Windows API requires lpOverlapped, which acts both
        an input argument and may contain results after calling. If None is
        provided, a throw-away zero-filled instance will be created to
        support such call. See Microsoft's documentation for intended usage.
    """
    input_check("hFile", hFile, HANDLE)
    input_check("dwFlags", dwFlags, integer_types)
    input_check(
        "nNumberOfBytesToLockLow", nNumberOfBytesToLockLow, integer_types)
    input_check(
        "nNumberOfBytesToLockHigh", nNumberOfBytesToLockHigh, integer_types)

    ffi, library = dist.load()

    if lpOverlapped is None:
        # Required by Windows API, create a throw-away zero-filled instance.
        lpOverlapped = OVERLAPPED()
    else:
        input_check("lpOverlapped", lpOverlapped, allowed_types=OVERLAPPED)

    code = library.LockFileEx(
        wintype_to_cdata(hFile),
        ffi.cast("DWORD", dwFlags),
        ffi.cast("DWORD", 0),  # "_Reserveved_"
        ffi.cast("DWORD", nNumberOfBytesToLockLow),
        ffi.cast("DWORD", nNumberOfBytesToLockHigh),
        wintype_to_cdata(lpOverlapped)
    )
    error_check("LockFileEx", code=code, expected=NON_ZERO)
Ejemplo n.º 12
0
    def test_exception_attribute(self):
        try:
            input_check("", 1, allowed_values=(2, ))

        except InputError as error:
            self.assertEqual(error.allowed_values, (2, ))

        else:
            self.fail("InputError not raised")
Ejemplo n.º 13
0
    def test_invalid_message(self):
        try:
            input_check("foo", 1, allowed_values=(2, ))

        except InputError as error:
            self.assertEqual(
                error.message,
                "Expected value for foo to be in (2,). Got 1 instead."
            )

        else:
            self.fail("InputError not raised")
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
def WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite=None, lpOverlapped=None):
    """
    Writes data to ``hFile`` which may be an I/O device for file.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365747

    :param pywincffi.wintypes.HANDLE hFile:
        The handle to write to.

    :type lpBuffer: str/bytes
    :param lpBuffer:
        Type is ``str`` on Python 2, ``bytes`` on Python 3.
        The data to be written to the file or device.

    :keyword int nNumberOfBytesToWrite:
        The number of bytes to be written.  Defaults to len(lpBuffer).

    :keyword pywincffi.wintypes.OVERLAPPED lpOverlapped:
        See Microsoft's documentation for intended usage and below for
        an example.

        >>> from pywincffi.core import dist
        >>> from pywincffi.kernel32 import WriteFile, CreateEvent
        >>> from pywincffi.wintypes import OVERLAPPED
        >>> hEvent = CreateEvent(...)
        >>> lpOverlapped = OVERLAPPED()
        >>> lpOverlapped.hEvent = hEvent
        >>> bytes_written = WriteFile(
        ...     hFile, "Hello world", lpOverlapped=lpOverlapped)

    :returns:
        Returns the number of bytes written.
    """
    ffi, library = dist.load()

    input_check("hFile", hFile, HANDLE)
    input_check("lpBuffer", lpBuffer, binary_type)
    input_check(
        "lpOverlapped", lpOverlapped,
        allowed_types=(NoneType, OVERLAPPED)
    )

    if nNumberOfBytesToWrite is None:
        nNumberOfBytesToWrite = len(lpBuffer)
    else:
        input_check(
            "nNumberOfBytesToWrite", nNumberOfBytesToWrite,
            integer_types
        )

    bytes_written = ffi.new("LPDWORD")
    code = library.WriteFile(
        wintype_to_cdata(hFile), lpBuffer, nNumberOfBytesToWrite,
        bytes_written, wintype_to_cdata(lpOverlapped)
    )
    error_check("WriteFile", code=code, expected=Enums.NON_ZERO)

    return bytes_written[0]
Ejemplo n.º 16
0
def SetNamedPipeHandleState(hNamedPipe,
                            lpMode=None,
                            lpMaxCollectionCount=None,
                            lpCollectDataTimeout=None):
    """
    Sets the read and blocking mode of the specified ``hNamedPipe``.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365787

    :param pywincffi.wintypes.HANDLE hNamedPipe:
        A handle to the named pipe instance.

    :keyword int lpMode:
        The new pipe mode which is a combination of read mode:

            * ``PIPE_READMODE_BYTE``
            * ``PIPE_READMODE_MESSAGE``

        And a wait-mode flag:

            * ``PIPE_WAIT``
            * ``PIPE_NOWAIT``

    :keyword int lpMaxCollectionCount:
        The maximum number of bytes collected.

    :keyword int lpCollectDataTimeout:
        The maximum time, in milliseconds, that can pass before a
        remote named pipe transfers information
    """
    input_check("hNamedPipe", hNamedPipe, HANDLE)
    ffi, library = dist.load()

    if lpMode is None:
        lpMode = ffi.NULL
    else:
        input_check("lpMode", lpMode, integer_types)
        lpMode = ffi.new("LPDWORD", lpMode)

    if lpMaxCollectionCount is None:
        lpMaxCollectionCount = ffi.NULL
    else:
        input_check("lpMaxCollectionCount", lpMaxCollectionCount,
                    integer_types)
        lpMaxCollectionCount = ffi.new("LPDWORD", lpMaxCollectionCount)

    if lpCollectDataTimeout is None:
        lpCollectDataTimeout = ffi.NULL
    else:
        input_check("lpCollectDataTimeout", lpCollectDataTimeout,
                    integer_types)
        lpCollectDataTimeout = ffi.new("LPDWORD", lpCollectDataTimeout)

    code = library.SetNamedPipeHandleState(wintype_to_cdata(hNamedPipe),
                                           lpMode, lpMaxCollectionCount,
                                           lpCollectDataTimeout)
    error_check("SetNamedPipeHandleState", code=code, expected=NON_ZERO)
Ejemplo n.º 17
0
def FlushFileBuffers(hFile):
    """
    Flushes the buffer of the specified file to disk.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa364439

    :param pywincffi.wintypes.HANDLE hFile:
        The handle to flush to disk.
    """
    input_check("hFile", hFile, HANDLE)
    _, library = dist.load()
    code = library.FlushFileBuffers(wintype_to_cdata(hFile))
    error_check("FlushFileBuffers", code=code, expected=NON_ZERO)
Ejemplo n.º 18
0
def FlushFileBuffers(hFile):
    """
    Flushes the buffer of the specified file to disk.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa364439

    :param pywincffi.wintypes.HANDLE hFile:
        The handle to flush to disk.
    """
    input_check("hFile", hFile, HANDLE)
    _, library = dist.load()
    code = library.FlushFileBuffers(wintype_to_cdata(hFile))
    error_check("FlushFileBuffers", code=code, expected=NON_ZERO)
Ejemplo n.º 19
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)
Ejemplo n.º 20
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=Enums.NON_ZERO)

    return HANDLE(hReadPipe[0]), HANDLE(hWritePipe[0])
Ejemplo n.º 21
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])
Ejemplo n.º 22
0
def WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite=None, lpOverlapped=None):
    """
    Writes data to ``hFile`` which may be an I/O device for file.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365747

    :param pywincffi.wintypes.HANDLE hFile:
        The handle to write to.

    :type lpBuffer: str/bytes
    :param lpBuffer:
        Type is ``str`` on Python 2, ``bytes`` on Python 3.
        The data to be written to the file or device.

    :keyword int nNumberOfBytesToWrite:
        The number of bytes to be written.  Defaults to len(lpBuffer).

    :keyword pywincffi.wintypes.OVERLAPPED lpOverlapped:
        See Microsoft's documentation for intended usage and below for
        an example.

        >>> from pywincffi.core import dist
        >>> from pywincffi.kernel32 import WriteFile, CreateEvent
        >>> from pywincffi.wintypes import OVERLAPPED
        >>> hEvent = CreateEvent(...)
        >>> lpOverlapped = OVERLAPPED()
        >>> lpOverlapped.hEvent = hEvent
        >>> bytes_written = WriteFile(
        ...     hFile, "Hello world", lpOverlapped=lpOverlapped)

    :returns:
        Returns the number of bytes written.
    """
    ffi, library = dist.load()

    input_check("hFile", hFile, HANDLE)
    input_check("lpBuffer", lpBuffer, binary_type)
    input_check("lpOverlapped",
                lpOverlapped,
                allowed_types=(NoneType, OVERLAPPED))

    if nNumberOfBytesToWrite is None:
        nNumberOfBytesToWrite = len(lpBuffer)
    else:
        input_check("nNumberOfBytesToWrite", nNumberOfBytesToWrite,
                    integer_types)

    bytes_written = ffi.new("LPDWORD")
    code = library.WriteFile(wintype_to_cdata(hFile), lpBuffer,
                             nNumberOfBytesToWrite, bytes_written,
                             wintype_to_cdata(lpOverlapped))
    expected = NON_ZERO if lpOverlapped is None else 0
    error_check("WriteFile", code=code, expected=expected)

    return bytes_written[0]
Ejemplo n.º 23
0
def ResetEvent(hEvent):
    """
    Sets the specified event object to the nonsignaled state.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms684305

    :param pywincffi.wintypes.HANDLE hEvent:
        A handle to the event object to be reset. The handle must
        have the ``EVENT_MODIFY_STATE`` access right.
    """
    input_check("hEvent", hEvent, HANDLE)

    _, library = dist.load()
    code = library.ResetEvent(wintype_to_cdata(hEvent))
    error_check("ResetEvent", code=code, expected=NON_ZERO)
Ejemplo n.º 24
0
def PeekNamedPipe(hNamedPipe, nBufferSize):
    """
    Copies data from a pipe into a buffer without removing it
    from the pipe.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365779

    :param pywincffi.wintypes.HANDLE hNamedPipe:
        The handele to the pipe object we want to peek into.

    :param int nBufferSize:
        The number of bytes to 'peek' into the pipe.

    :rtype: PeekNamedPipeResult
    :return:
        Returns an instance of :class:`PeekNamedPipeResult` which
        contains the buffer read, number of bytes read and the result.
    """
    input_check("hNamedPipe", hNamedPipe, HANDLE)
    input_check("nBufferSize", nBufferSize, integer_types)
    ffi, library = dist.load()

    # Outputs
    lpBuffer = ffi.new("LPVOID[%d]" % nBufferSize)
    lpBytesRead = ffi.new("LPDWORD")
    lpTotalBytesAvail = ffi.new("LPDWORD")
    lpBytesLeftThisMessage = ffi.new("LPDWORD")

    code = library.PeekNamedPipe(
        wintype_to_cdata(hNamedPipe),
        lpBuffer,
        nBufferSize,
        lpBytesRead,
        lpTotalBytesAvail,
        lpBytesLeftThisMessage
    )
    error_check("PeekNamedPipe", code=code, expected=NON_ZERO)

    return PeekNamedPipeResult(
        lpBuffer=lpBuffer,
        lpBytesRead=lpBytesRead[0],
        lpTotalBytesAvail=lpTotalBytesAvail[0],
        lpBytesLeftThisMessage=lpBytesLeftThisMessage[0]
    )
Ejemplo n.º 25
0
def CloseHandle(hObject):
    """
    Closes an open object handle.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms724211

    :type hObject: pywincffi.wintypes.HANDLE or pywincffi.wintypes.SOCKET
    :param hObject:
        The handle object to close.
    """
    input_check("hObject", hObject, (HANDLE, SOCKET))
    _, library = dist.load()

    code = library.CloseHandle(wintype_to_cdata(hObject))
    error_check("CloseHandle", code=code, expected=Enums.NON_ZERO)
Ejemplo n.º 26
0
def PeekNamedPipe(hNamedPipe, nBufferSize):
    """
    Copies data from a pipe into a buffer without removing it
    from the pipe.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365779

    :param pywincffi.wintypes.HANDLE hNamedPipe:
        The handele to the pipe object we want to peek into.

    :param int nBufferSize:
        The number of bytes to 'peek' into the pipe.

    :rtype: PeekNamedPipeResult
    :return:
        Returns an instance of :class:`PeekNamedPipeResult` which
        contains the buffer read, number of bytes read and the result.
    """
    input_check("hNamedPipe", hNamedPipe, HANDLE)
    input_check("nBufferSize", nBufferSize, integer_types)
    ffi, library = dist.load()

    # Outputs
    lpBuffer = ffi.new("LPVOID[%d]" % nBufferSize)
    lpBytesRead = ffi.new("LPDWORD")
    lpTotalBytesAvail = ffi.new("LPDWORD")
    lpBytesLeftThisMessage = ffi.new("LPDWORD")

    code = library.PeekNamedPipe(
        wintype_to_cdata(hNamedPipe),
        lpBuffer,
        nBufferSize,
        lpBytesRead,
        lpTotalBytesAvail,
        lpBytesLeftThisMessage
    )
    error_check("PeekNamedPipe", code=code, expected=Enums.NON_ZERO)

    return PeekNamedPipeResult(
        lpBuffer=lpBuffer,
        lpBytesRead=lpBytesRead[0],
        lpTotalBytesAvail=lpTotalBytesAvail[0],
        lpBytesLeftThisMessage=lpBytesLeftThisMessage[0]
    )
Ejemplo n.º 27
0
def ResetEvent(hEvent):
    """
    Sets the specified event object to the nonsignaled state.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms684305

    :param pywincffi.wintypes.HANDLE hEvent:
        A handle to the event object to be reset. The handle must
        have the ``EVENT_MODIFY_STATE`` access right.
    """
    input_check("hEvent", hEvent, HANDLE)

    _, library = dist.load()
    code = library.ResetEvent(wintype_to_cdata(hEvent))
    error_check("ResetEvent", code=code, expected=Enums.NON_ZERO)
Ejemplo n.º 28
0
def GetProcessId(Process):  # pylint: disable=invalid-name
    """
    Returns the pid of the process handle provided in ``Process``.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms683215

    :param pywincffi.wintypes.HANDLE Process:
        The handle of the process.

    :return:
        Returns an integer which represents the pid of the given
        process handle.
    """
    input_check("Process", Process, HANDLE)
    _, library = dist.load()
    pid = library.GetProcessId(wintype_to_cdata(Process))
    error_check("GetProcessId")
    return pid
Ejemplo n.º 29
0
def GetProcessId(Process):  # pylint: disable=invalid-name
    """
    Returns the pid of the process handle provided in ``Process``.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms683215

    :param pywincffi.wintypes.HANDLE Process:
        The handle of the process.

    :return:
        Returns an integer which represents the pid of the given
        process handle.
    """
    input_check("Process", Process, HANDLE)
    _, library = dist.load()
    pid = library.GetProcessId(wintype_to_cdata(Process))
    error_check("GetProcessId")
    return pid
Ejemplo n.º 30
0
def UnlockFileEx(
        hFile, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh,
        lpOverlapped=None):
    """
    Unlocks a region in the specified file.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365716

    :param pywincffi.wintypes.HANDLE hFile:
        The handle to the file to unlock.  This handle must have been
        created with either the ``GENERIC_READ`` or ``GENERIC_WRITE``
        right.

    :param int nNumberOfBytesToUnlockLow:
        The start of the byte range to unlock.

    :param int nNumberOfBytesToUnlockHigh:
        The end of the byte range to unlock.

    :keyword pywincffi.wintypes.OVERLAPPED lpOverlapped:
        The underlying Windows API requires lpOverlapped, which acts both
        an input argument and may contain results after calling. If None is
        provided, a throw-away zero-filled instance will be created to
        support such call. See Microsoft's documentation for intended usage.
    """
    input_check("hFile", hFile, HANDLE)
    input_check(
        "nNumberOfBytesToUnlockLow",
        nNumberOfBytesToUnlockLow, integer_types)
    input_check(
        "nNumberOfBytesToUnlockHigh",
        nNumberOfBytesToUnlockHigh, integer_types)

    ffi, library = dist.load()

    if lpOverlapped is None:
        # Required by Windows API, create a throw-away zero-filled instance.
        lpOverlapped = OVERLAPPED()
    else:
        input_check("lpOverlapped", lpOverlapped, allowed_types=OVERLAPPED)

    code = library.UnlockFileEx(
        wintype_to_cdata(hFile),
        ffi.cast("DWORD", 0),  # "_Reserveved_"
        ffi.cast("DWORD", nNumberOfBytesToUnlockLow),
        ffi.cast("DWORD", nNumberOfBytesToUnlockHigh),
        wintype_to_cdata(lpOverlapped)
    )
    error_check("UnlockFileEx", code=code, expected=NON_ZERO)
Ejemplo n.º 31
0
def UnlockFileEx(
        hFile, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh,
        lpOverlapped=None):
    """
    Unlocks a region in the specified file.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365716

    :param pywincffi.wintypes.HANDLE hFile:
        The handle to the file to unlock.  This handle must have been
        created with either the ``GENERIC_READ`` or ``GENERIC_WRITE``
        right.

    :param int nNumberOfBytesToUnlockLow:
        The start of the byte range to unlock.

    :param int nNumberOfBytesToUnlockHigh:
        The end of the byte range to unlock.

    :keyword pywincffi.wintypes.OVERLAPPED lpOverlapped:
        The underlying Windows API requires lpOverlapped, which acts both
        an input argument and may contain results after calling. If None is
        provided, a throw-away zero-filled instance will be created to
        support such call. See Microsoft's documentation for intended usage.
    """
    input_check("hFile", hFile, HANDLE)
    input_check(
        "nNumberOfBytesToUnlockLow",
        nNumberOfBytesToUnlockLow, integer_types)
    input_check(
        "nNumberOfBytesToUnlockHigh",
        nNumberOfBytesToUnlockHigh, integer_types)

    ffi, library = dist.load()

    if lpOverlapped is None:
        # Required by Windows API, create a throw-away zero-filled instance.
        lpOverlapped = OVERLAPPED()
    else:
        input_check("lpOverlapped", lpOverlapped, allowed_types=OVERLAPPED)

    code = library.UnlockFileEx(
        wintype_to_cdata(hFile),
        ffi.cast("DWORD", 0),  # "_Reserveved_"
        ffi.cast("DWORD", nNumberOfBytesToUnlockLow),
        ffi.cast("DWORD", nNumberOfBytesToUnlockHigh),
        wintype_to_cdata(lpOverlapped)
    )
    error_check("UnlockFileEx", code=code, expected=NON_ZERO)
Ejemplo n.º 32
0
def TerminateProcess(hProcess, uExitCode):
    """
    Terminates the specified process and all of its threads.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms686714

    :param pywincffi.wintypes.HANDLE hProcess:
        A handle to the process to be terminated.

    :param int uExitCode:
        The exit code of the processes and threads as a result of calling
        this function.
    """
    input_check("hProcess", hProcess, HANDLE)
    input_check("uExitCode", uExitCode, integer_types)
    ffi, library = dist.load()
    code = library.TerminateProcess(wintype_to_cdata(hProcess),
                                    ffi.cast("UINT", uExitCode))
    error_check("TerminateProcess", code=code, expected=NON_ZERO)
Ejemplo n.º 33
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)
Ejemplo n.º 34
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)
Ejemplo n.º 35
0
def SetHandleInformation(hObject, dwMask, dwFlags):
    """
    Sets properties of an object handle.

    .. seealso::

        https://msdn.microsoft.com/en-us/ms724935

    :param pywincffi.wintypes.HANDLE hObject:
        A handle to an object whose information is to be set.

    :param int dwMask:
        A mask that specifies the bit flags to be changed.

    :param int dwFlags:
        Set of bit flags that specifies properties of ``hObject``.
    """
    input_check("hObject", hObject, HANDLE)
    input_check("dwMask", dwMask, integer_types)
    input_check("dwFlags", dwFlags, integer_types)
    ffi, library = dist.load()

    code = library.SetHandleInformation(
        wintype_to_cdata(hObject),
        ffi.cast("DWORD", dwMask),
        ffi.cast("DWORD", dwFlags)
    )
    error_check("SetHandleInformation", code=code, expected=Enums.NON_ZERO)
Ejemplo n.º 36
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)
Ejemplo n.º 37
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)
Ejemplo n.º 38
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 {0!r}".format(
                library.INVALID_HANDLE_VALUE))

    error_check("CreateToolhelp32Snapshot")

    return HANDLE(process_list)
Ejemplo n.º 39
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)
Ejemplo n.º 40
0
def GetConsoleScreenBufferInfo(hConsoleOutput):
    """
    Retrieves information about the specified console screen buffer.

    .. seealso::

        https://docs.microsoft.com/en-us/windows/console/getconsolescreenbufferinfo

    :param pywincffi.wintypes.HANDLE hConsoleOutput:
        A handle to the console screen buffer. The handle must have the
        ``GENERIC_READ`` access right.

    :returns:
        Returns a ffi data structure with attributes corresponding to
        the fields on the ``PCONSOLE_SCREEN_BUFFER_INFO`` struct.
    """
    input_check("hConsoleOutput", hConsoleOutput, HANDLE)
    ffi, library = dist.load()
    info = ffi.new("PCONSOLE_SCREEN_BUFFER_INFO")
    code = library.GetConsoleScreenBufferInfo(
        wintype_to_cdata(hConsoleOutput), info)
    error_check("GetConsoleScreenBufferInfo", code, expected=NON_ZERO)
    return info
Ejemplo n.º 41
0
def TerminateProcess(hProcess, uExitCode):
    """
    Terminates the specified process and all of its threads.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms686714

    :param pywincffi.wintypes.HANDLE hProcess:
        A handle to the process to be terminated.

    :param int uExitCode:
        The exit code of the processes and threads as a result of calling
        this function.
    """
    input_check("hProcess", hProcess, HANDLE)
    input_check("uExitCode", uExitCode, integer_types)
    ffi, library = dist.load()
    code = library.TerminateProcess(
        wintype_to_cdata(hProcess),
        ffi.cast("UINT", uExitCode)
    )
    error_check("TerminateProcess", code=code, expected=Enums.NON_ZERO)
Ejemplo n.º 42
0
def GetHandleInformation(hObject):
    """
    Returns properties of an object handle.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms724329

    :param pywincffi.wintypes.HANDLE hObject:
        A handle to an object whose information is to be retrieved.

    :rtype: int
    :return:
        Returns the set of bit flags that specify properties of ``hObject``.
    """
    input_check("hObject", hObject, HANDLE)
    ffi, library = dist.load()

    lpdwFlags = ffi.new("LPDWORD")
    code = library.GetHandleInformation(wintype_to_cdata(hObject), lpdwFlags)
    error_check("GetHandleInformation", code=code, expected=Enums.NON_ZERO)

    return lpdwFlags[0]
Ejemplo n.º 43
0
def WSAEnumNetworkEvents(socket, hEventObject=None):
    """
    Discovers occurrences of network events on the indicated ``socket``, clears
    internal events and optionally resets event objects.

    .. seealso::
        https://msdn.microsoft.com/en-us/ms741572

    :param pywincffi.wintypes.objects.SOCKET socket:
        The socket object to enumerate events for.

    :keyword pywincffi.wintypes.objects.WSAEVENT hEventObject:
        An optional handle identify an associated event object
        to be reset.

    :rtype: :class:`pywincffi.wintypes.structures.LPWSANETWORKEVENTS`
    :return:
    """
    input_check("socket", socket, allowed_types=(SOCKET, ))

    ffi, library = dist.load()
    if hEventObject is not None:
        input_check("hEventObject", hEventObject, allowed_types=(WSAEVENT, ))
        hEventObject = wintype_to_cdata(hEventObject)
    else:
        hEventObject = ffi.NULL

    lpNetworkEvents = LPWSANETWORKEVENTS()
    code = library.WSAEnumNetworkEvents(
        wintype_to_cdata(socket),
        hEventObject,
        wintype_to_cdata(lpNetworkEvents)
    )
    error_check("WSAEnumNetworkEvents", code=code, expected=0)

    return lpNetworkEvents
Ejemplo n.º 44
0
def GetOverlappedResult(hFile, lpOverlapped, bWait):
    """
    Retrieves the results of an overlapped operation on the specified file,
    named pipe, or communications device. To specify a timeout interval or
    wait on an alertable thread, use GetOverlappedResultEx.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms683209

    :param pywincffi.wintypes.HANDLE hFile:
        A handle to the file, named pipe, or communications device.
        This is the same handle that was specified when the overlapped
        operation was started by a call to the ReadFile, WriteFile,
        ConnectNamedPipe, TransactNamedPipe, DeviceIoControl, or WaitCommEvent
        function.

    :param pywincffi.wintypes.OVERLAPPED lpOverlapped:
        The an OVERLAPPED object that was specified when the overlapped
        operation was started

    :param bool bWait:
        If this parameter is TRUE, and the Internal member of the lpOverlapped
        structure is STATUS_PENDING, the function does not return until the
        operation has been completed. If this parameter is FALSE and the
        operation is still pending, the function returns FALSE and the
        GetLastError function returns ERROR_IO_INCOMPLETE

    :returns:
        The number of bytes that were actually transferred by a read or write
        operation. For a TransactNamedPipe operation, this is the number of
        bytes that were read from the pipe. For a DeviceIoControl operation,
        this is the number of bytes of output data returned by the device
        driver. For a ConnectNamedPipe or WaitCommEvent operation, this value
        is undefined.
    """
    input_check("hFile", hFile, HANDLE)
    input_check("lpOverlapped", lpOverlapped, OVERLAPPED)
    input_check("bWait", bWait, allowed_values=(True, False))

    ffi, library = dist.load()

    lpNumberOfBytesTransferred = ffi.new("DWORD[1]")

    result = library.GetOverlappedResult(
        wintype_to_cdata(hFile),
        wintype_to_cdata(lpOverlapped),
        lpNumberOfBytesTransferred,
        ffi.cast("BOOL", bWait),
    )

    error_check("GetOverlappedResult", result, NON_ZERO)

    return int(lpNumberOfBytesTransferred[0])
Ejemplo n.º 45
0
def ReadFile(hFile, nNumberOfBytesToRead, lpOverlapped=None):
    """
    Read the specified number of bytes from ``hFile``.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365467

    :param pywincffi.wintypes.HANDLE hFile:
        The handle to read from.

    :param int nNumberOfBytesToRead:
        The number of bytes to read from ``hFile``

    :keyword pywincffi.wintypes.OVERLAPPED lpOverlapped:
        See Microsoft's documentation for intended usage and below for
        an example.

        >>> from pywincffi.core import dist
        >>> from pywincffi.kernel32 import ReadFile, CreateEvent
        >>> from pywincffi.wintypes import OVERLAPPED
        >>> hEvent = CreateEvent(...)
        >>> lpOverlapped = OVERLAPPED()
        >>> lpOverlapped.hEvent = hEvent
        >>> read_data = ReadFile(  # read 12 bytes from hFile
        ...     hFile, 12, lpOverlapped=lpOverlapped)

    :returns:
        Returns the binary data read from ``hFile``
        Type is ``str`` on Python 2, ``bytes`` on Python 3.
    """
    ffi, library = dist.load()

    input_check("hFile", hFile, HANDLE)
    input_check("nNumberOfBytesToRead", nNumberOfBytesToRead, integer_types)
    input_check(
        "lpOverlapped", lpOverlapped,
        allowed_types=(NoneType, OVERLAPPED)
    )

    lpBuffer = ffi.new("char []", nNumberOfBytesToRead)
    bytes_read = ffi.new("LPDWORD")
    code = library.ReadFile(
        wintype_to_cdata(hFile), lpBuffer, nNumberOfBytesToRead, bytes_read,
        wintype_to_cdata(lpOverlapped)
    )
    error_check("ReadFile", code=code, expected=NON_ZERO)
    return ffi.unpack(lpBuffer, bytes_read[0])
Ejemplo n.º 46
0
def ReadFile(hFile, nNumberOfBytesToRead, lpOverlapped=None):
    """
    Read the specified number of bytes from ``hFile``.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365467

    :param pywincffi.wintypes.HANDLE hFile:
        The handle to read from.

    :param int nNumberOfBytesToRead:
        The number of bytes to read from ``hFile``

    :keyword pywincffi.wintypes.OVERLAPPED lpOverlapped:
        See Microsoft's documentation for intended usage and below for
        an example.

        >>> from pywincffi.core import dist
        >>> from pywincffi.kernel32 import ReadFile, CreateEvent
        >>> from pywincffi.wintypes import OVERLAPPED
        >>> hEvent = CreateEvent(...)
        >>> lpOverlapped = OVERLAPPED()
        >>> lpOverlapped.hEvent = hEvent
        >>> read_data = ReadFile(  # read 12 bytes from hFile
        ...     hFile, 12, lpOverlapped=lpOverlapped)

    :returns:
        Returns the binary data read from ``hFile``
        Type is ``str`` on Python 2, ``bytes`` on Python 3.
    """
    ffi, library = dist.load()

    input_check("hFile", hFile, HANDLE)
    input_check("nNumberOfBytesToRead", nNumberOfBytesToRead, integer_types)
    input_check(
        "lpOverlapped", lpOverlapped,
        allowed_types=(NoneType, OVERLAPPED)
    )

    lpBuffer = ffi.new("char []", nNumberOfBytesToRead)
    bytes_read = ffi.new("LPDWORD")
    code = library.ReadFile(
        wintype_to_cdata(hFile), lpBuffer, nNumberOfBytesToRead, bytes_read,
        wintype_to_cdata(lpOverlapped)
    )
    error_check("ReadFile", code=code, expected=NON_ZERO)
    return ffi.unpack(lpBuffer, bytes_read[0])
Ejemplo n.º 47
0
def MoveFileEx(lpExistingFileName, lpNewFileName, dwFlags=None):
    """
    Moves an existing file or directory, including its children,
    see the MSDN documentation for full options.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365240

    :param str lpExistingFileName:
        Type is ``unicode`` on Python 2, ``str`` on Python 3.
        Name of the file or directory to perform the operation on.

    :param str lpNewFileName:
        Type is ``unicode`` on Python 2, ``str`` on Python 3.
        Optional new name of the path or directory.  This value may be
        ``None``.

    :keyword int dwFlags:
        Parameters which control the operation of :func:`MoveFileEx`.  See
        the MSDN documentation for full details.  By default
        ``MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH`` is used.
    """
    ffi, library = dist.load()

    if dwFlags is None:
        dwFlags = \
            library.MOVEFILE_REPLACE_EXISTING | library.MOVEFILE_WRITE_THROUGH

    input_check("lpExistingFileName", lpExistingFileName, text_type)
    input_check("dwFlags", dwFlags, integer_types)

    if lpNewFileName is not None:
        input_check("lpNewFileName", lpNewFileName, text_type)
    else:
        lpNewFileName = ffi.NULL

    code = library.MoveFileEx(
        lpExistingFileName,
        lpNewFileName,
        ffi.cast("DWORD", dwFlags)
    )
    error_check("MoveFileEx", code=code, expected=NON_ZERO)
Ejemplo n.º 48
0
def MoveFileEx(lpExistingFileName, lpNewFileName, dwFlags=None):
    """
    Moves an existing file or directory, including its children,
    see the MSDN documentation for full options.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365240

    :param str lpExistingFileName:
        Type is ``unicode`` on Python 2, ``str`` on Python 3.
        Name of the file or directory to perform the operation on.

    :param str lpNewFileName:
        Type is ``unicode`` on Python 2, ``str`` on Python 3.
        Optional new name of the path or directory.  This value may be
        ``None``.

    :keyword int dwFlags:
        Parameters which control the operation of :func:`MoveFileEx`.  See
        the MSDN documentation for full details.  By default
        ``MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH`` is used.
    """
    ffi, library = dist.load()

    if dwFlags is None:
        dwFlags = \
            library.MOVEFILE_REPLACE_EXISTING | library.MOVEFILE_WRITE_THROUGH

    input_check("lpExistingFileName", lpExistingFileName, text_type)
    input_check("dwFlags", dwFlags, integer_types)

    if lpNewFileName is not None:
        input_check("lpNewFileName", lpNewFileName, text_type)
    else:
        lpNewFileName = ffi.NULL

    code = library.MoveFileEx(
        lpExistingFileName,
        lpNewFileName,
        ffi.cast("DWORD", dwFlags)
    )
    error_check("MoveFileEx", code=code, expected=NON_ZERO)
Ejemplo n.º 49
0
def WSAEventSelect(socket, hEventObject, lNetworkEvents):
    """
    Specifies an event object to be associated with the specified set of
    FD_XXX network events.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms741576

    :param pywincffi.wintypes.objects.SOCKET socket:
        The socket object to associate the selected network events with.

    :param pywincffi.wintypes.objects.WSAEVENT hEventObject:
        A handle which identifies the event object to be associated
        with the network events.

    :param int lNetworkEvents:
        A bitmask which specifies the combination of ``FD_XXX`` network
        events which the application has interest in.
    """
    input_check("socket", socket, allowed_types=(SOCKET, ))
    input_check("hEventObject", hEventObject, allowed_types=(HANDLE, ))
    input_check("lNetworkEvents", lNetworkEvents, integer_types)

    ffi, library = dist.load()

    code = library.WSAEventSelect(
        wintype_to_cdata(socket),
        wintype_to_cdata(hEventObject),
        ffi.cast("long", lNetworkEvents)
    )

    if code == library.SOCKET_ERROR:
        errno = WSAGetLastError()
        raise WindowsAPIError(
            "WSAEventSelect", "Socket error %d" % errno, errno)

    error_check("WSAEventSelect", code, expected=0)
Ejemplo n.º 50
0
def MsgWaitForMultipleObjects(
        pHandles, bWaitAll, dwMilliseconds, dwWakeMask, nCount=None):
    """
    Waits until one or all of the specified objects are in a singled state
    or the timeout elapses.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/ms684242

    :param list pHandles:
        A list or tuple of :class:`pywincffi.wintypes.HANDLE` to wait on.
        See Microsoft's documentation for more information about the contents
        of this argument.

    :param bool bWaitAll:
        If True then this function will return when the states of all
        objects in ``pHandles`` are signaled.

    :param int dwMilliseconds:
        The timeout interval in milliseconds.

    :param int dwWakeMask:
        The input types for which an input event object handle will be added
        to the array of handles.  See Microsoft's documentation for more
        detailed information.

    :keyword int nCount:
        The number of object handles in ``pHandles``.  By default this will
        be determined by checking the length of the input to ``pHandles``.

    :raises WindowsAPIError:
        Raised if the underlying Windows function returns ``WAIT_FAILED``.

    :rtype: int
    :return:
        Returns the value of the event which caused the function to
        return.  See Microsoft's documentation for full details on what
        this could be.
    """
    input_check("pHandles", pHandles, (list, tuple))

    if nCount is None:
        nCount = len(pHandles)

    input_check("bWaitAll", bWaitAll, bool)
    input_check("dwMilliseconds", dwMilliseconds, integer_types)
    input_check("dwWakeMask", dwWakeMask, integer_types)
    input_check("nCount", nCount, integer_types)

    ffi, library = dist.load()

    # Verify input types and build a <cdata HANDLE> array out of the
    # input Python HANDLE list/tuple to be passed to the underlying API.
    pHandles_cdata = ffi.new("HANDLE[]", nCount)
    for i, handle in enumerate(pHandles):
        input_check("pHandles[%d]" % i, handle, HANDLE)
        pHandles_cdata[i] = wintype_to_cdata(handle)

    code = library.MsgWaitForMultipleObjects(
        nCount,
        pHandles_cdata,
        bWaitAll,
        dwMilliseconds,
        dwWakeMask
    )

    if code == library.WAIT_FAILED:
        code, message = ffi.getwinerror()
        raise WindowsAPIError(
            "MsgWaitForMultipleObjects", message, code)

    return code
Ejemplo n.º 51
0
def SetNamedPipeHandleState(
        hNamedPipe,
        lpMode=None, lpMaxCollectionCount=None, lpCollectDataTimeout=None):
    """
    Sets the read and blocking mode of the specified ``hNamedPipe``.

    .. seealso::

        https://msdn.microsoft.com/en-us/library/aa365787

    :param pywincffi.wintypes.HANDLE hNamedPipe:
        A handle to the named pipe instance.

    :keyword int lpMode:
        The new pipe mode which is a combination of read mode:

            * ``PIPE_READMODE_BYTE``
            * ``PIPE_READMODE_MESSAGE``

        And a wait-mode flag:

            * ``PIPE_WAIT``
            * ``PIPE_NOWAIT``

    :keyword int lpMaxCollectionCount:
        The maximum number of bytes collected.

    :keyword int lpCollectDataTimeout:
        The maximum time, in milliseconds, that can pass before a
        remote named pipe transfers information
    """
    input_check("hNamedPipe", hNamedPipe, HANDLE)
    ffi, library = dist.load()

    if lpMode is None:
        lpMode = ffi.NULL
    else:
        input_check("lpMode", lpMode, integer_types)
        lpMode = ffi.new("LPDWORD", lpMode)

    if lpMaxCollectionCount is None:
        lpMaxCollectionCount = ffi.NULL
    else:
        input_check(
            "lpMaxCollectionCount", lpMaxCollectionCount, integer_types)
        lpMaxCollectionCount = ffi.new("LPDWORD", lpMaxCollectionCount)

    if lpCollectDataTimeout is None:
        lpCollectDataTimeout = ffi.NULL
    else:
        input_check(
            "lpCollectDataTimeout", lpCollectDataTimeout, integer_types)
        lpCollectDataTimeout = ffi.new("LPDWORD", lpCollectDataTimeout)

    code = library.SetNamedPipeHandleState(
        wintype_to_cdata(hNamedPipe),
        lpMode,
        lpMaxCollectionCount,
        lpCollectDataTimeout
    )
    error_check("SetNamedPipeHandleState", code=code, expected=Enums.NON_ZERO)
Ejemplo n.º 52
0
 def test_valid_allowed_values(self):
     input_check("", 1, allowed_values=(1,))
Ejemplo n.º 53
0
def pid_exists(pid, wait=0):
    """
    Returns True if there's a process associated with ``pid``.

    :param int pid:
        The id of the process to check for.

    :keyword int wait:
        An optional keyword that controls how long we tell
        :func:`WaitForSingleObject` to wait on the process.

    :raises ValidationError:
        Raised if there's a problem with the value provided for ``pid``.
    """
    input_check("pid", pid, integer_types)

    # Process IDs which always exist shouldn't need to continue
    # further.
    if pid in RESERVED_PIDS:
        return True

    _, library = dist.load()

    try:
        hProcess = OpenProcess(
            library.PROCESS_QUERY_INFORMATION | library.SYNCHRONIZE,
            False, pid)

    except WindowsAPIError as error:
        # If we can't access the process then it must exist
        # otherwise there would be nothing to access.  We
        # reach this bit of code if the pid in question
        # is owned by another user or the system and
        # the process running this code does not have the
        # rights to query the other process's information.
        if error.errno == library.ERROR_ACCESS_DENIED:
            library.SetLastError(0)
            return True

        # Sometimes the PID we're asking about no longer exists
        # in the stack anywhere so we'll get ERROR_INVALID_PARAMETER
        # so there's not any reason to continue further.
        if error.errno == library.ERROR_INVALID_PARAMETER:
            library.SetLastError(0)
            return False

        raise

    try:
        process_exit_code = GetExitCodeProcess(hProcess)

        # Process may or may not still be running.  If process_exit_code
        # seem to indicate the process is still alive then run one
        # last check to be certain.
        if process_exit_code == library.STILL_ACTIVE:
            wait_result = WaitForSingleObject(hProcess, wait)

            # The process was still running.
            if wait_result == library.WAIT_TIMEOUT:
                return True

            # The process exited while we were waiting
            # on it so it no longer exists.
            elif wait_result == library.WAIT_OBJECT_0:
                return False

            elif wait_result == library.WAIT_ABANDONED:
                raise PyWinCFFINotImplementedError(
                    "An unknown error occurred while running "
                    "pid_exists(%r).  It appears that the call to "
                    "WaitForSingleObject may be been terminated." % pid)

            else:
                raise PyWinCFFINotImplementedError(
                    "Unhandled result from "
                    "WaitForSingleObject(): %r" % wait_result)

        return False

    finally:
        CloseHandle(hProcess)