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 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]
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 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]
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 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]
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 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 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
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
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)
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
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
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)
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)
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)
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 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)
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]
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])
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)
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)
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])
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])
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 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)
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)
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)
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] )
def GetTempPath(): """ Retrieves the path of the directory designated for temporary files. .. seealso:: https://msdn.microsoft.com/en-us/aa364992 :returns: Returns a string containing the value produced by the underlying C function. """ ffi, library = dist.load() lpBuffer = ffi.new("TCHAR[{}]".format(library.MAX_PATH + 1)) code = library.GetTempPath(library.MAX_PATH + 1, lpBuffer) error_check("GetTempPath", code=code, expected=NON_ZERO) return ffi.string(lpBuffer)
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] )
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)
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
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)
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)
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 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)
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)
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]
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
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)
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
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 CreateProcess( # pylint: disable=too-many-arguments,too-many-branches lpApplicationName=None, lpCommandLine=None, lpProcessAttributes=None, lpThreadAttributes=None, bInheritHandles=True, dwCreationFlags=None, lpEnvironment=None, lpCurrentDirectory=None, lpStartupInfo=None): """ Creates a new process and its primary thread. The process will be created in the same security context as the original process. .. seealso:: https://msdn.microsoft.com/en-us/library/ms682425 :keyword pywincffi.wintypes.STARTUPINFO lpStartupInfo: See Microsoft's documentation for additional information. .. warning:: The STARTUPINFOEX structure is not currently supported for this input. :keyword str lpCommandLine: The command line to be executed. The maximum length of this parameter is 32768. If no value is provided for ``lpApplicationName`` then the module name portion of ``lpCommandLine`` cannot exceed ``MAX_PATH``. :keyword str lpApplicationName: The name of the module or application to be executed. This can be either the fully qualified path name or a partial name. The system path will not be searched. If no value is provided for this keyword then the input to ``lpCommandLine`` will be used by Windows instead. :keyword pywincffi.wintypes.SECUREITY_ATTRIBUTES lpProcessAttributes: Determines whether the returned handle to the new process object can be inherited by child processes. By default, the handle cannot be inherited. :keyword pywincffi.wintypes.SECUREITY_ATTRIBUTES lpThreadAttributes: Determines if the returned handle to the new thread object can be inherited by child processes. By default, the thread cannot be inherited. :keyword bool bInheritHandles: If True (the default) the handles inherited by the calling process are inherited by the new process. :keyword int dwCreationFlags: Controls the priority class and creation of the process. By default the process will flag will default to ``NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT`` :keyword dict lpEnvironment: The environment for the new process. By default the the process will be created with the same environment as the parent process. .. note:: All keys and values in the environment must be either unicode (Python 2) or strings (Python 3). .. note:: This keyword will completely override the current if you wish to update the current environment instead then you will need to make and update a copy. .. warning:: Excluding certain system environment variables such as ``PATH`` or ``SYSTEMROOT`` may result in crashes or unexpected behaviors depending on the program being run. :keyword str lpCurrentDirectory: The full path to the current directory for the process. If not provided then the process will have the same working directory as the parent process. :raises InputError: Raised if ``lpCommandLine`` is too long or there are other input problems. :rtype: :class:`pywincffi.kernel32.process.CreateProcessResult` :return: Returns a named tuple containing ``lpCommandLine`` and ``lpProcessInformation``. The ``lpProcessInformation`` will be an instance of :class:`pywincffi.wintypes.structures.PROCESS_INFORMATION` """ if lpCommandLine is None: raise InputError( "lpCommandLine", None, message="lpCommandLine in call to CreateProcess() may not be " "None.") ffi, library = dist.load() if len(lpCommandLine) > library.MAX_COMMAND_LINE: raise InputError( "lpCommandLine", lpCommandLine, text_type, message="lpCommandLine's length " "cannot exceed {0}".format(library.MAX_COMMAND_LINE)) if lpApplicationName is None: lpApplicationName = ffi.NULL # If lpApplication name is not set then lpCommandLine's # module name cannot exceed MAX_PATH. Rather than letting # this hit the Windows API and possibly fail we're check # before hand so we can provide a better exception. module = module_name(text_type(lpCommandLine)) if len(module) > library.MAX_PATH: raise InputError( "lpCommandLine", lpCommandLine, text_type, message="lpCommandLine's module name length cannot " "exceed {0} if `lpApplicationName` " "is not set. Module name was {1!r}".format( library.MAX_PATH, module)) else: input_check( "lpApplicationName", lpApplicationName, allowed_types=(text_type,)) input_check( "lpProcessAttributes", lpProcessAttributes, allowed_types=(SECURITY_ATTRIBUTES, NoneType)) lpProcessAttributes = wintype_to_cdata(lpProcessAttributes) input_check( "lpThreadAttributes", lpThreadAttributes, allowed_types=(SECURITY_ATTRIBUTES, NoneType)) lpThreadAttributes = wintype_to_cdata(lpThreadAttributes) input_check( "bInheritHandles", bInheritHandles, allowed_values=(True, False)) if dwCreationFlags is None: dwCreationFlags = \ library.NORMAL_PRIORITY_CLASS | library.CREATE_UNICODE_ENVIRONMENT input_check( "dwCreationFlags", dwCreationFlags, allowed_types=(integer_types, )) if lpEnvironment is not None: lpEnvironment = _text_to_wchar(_environment_to_string(lpEnvironment)) dwCreationFlags = dwCreationFlags | library.CREATE_UNICODE_ENVIRONMENT else: lpEnvironment = ffi.NULL if lpCurrentDirectory is not None: input_check( "lpCurrentDirectory", lpCurrentDirectory, allowed_types=(text_type, )) else: lpCurrentDirectory = ffi.NULL if lpStartupInfo is not None: # TODO need to add support for STARTUPINFOEX (undocumented) input_check( "lpStartupInfo", lpStartupInfo, allowed_types=(STARTUPINFO, )) else: lpStartupInfo = STARTUPINFO() lpProcessInformation = PROCESS_INFORMATION() code = library.CreateProcess( lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, wintype_to_cdata(lpStartupInfo), wintype_to_cdata(lpProcessInformation) ) error_check("CreateProcess", code=code, expected=NON_ZERO) return CreateProcessResult( lpCommandLine=lpCommandLine, lpProcessInformation=lpProcessInformation)
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 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 CreateProcess( # pylint: disable=too-many-arguments,too-many-branches lpCommandLine, lpApplicationName=None, lpProcessAttributes=None, lpThreadAttributes=None, bInheritHandles=True, dwCreationFlags=None, lpEnvironment=None, lpCurrentDirectory=None, lpStartupInfo=None): """ Creates a new process and its primary thread. The process will be created in the same security context as the original process. .. seealso:: https://msdn.microsoft.com/en-us/library/ms682425 :param str lpCommandLine: The command line to be executed. The maximum length of this parameter is 32768. If no value is provided for ``lpApplicationName`` then the module name portion of ``lpCommandLine`` cannot exceed ``MAX_PATH``. :keyword pywincffi.wintypes.STARTUPINFO lpStartupInfo: See Microsoft's documentation for additional information. .. warning:: The STARTUPINFOEX structure is not currently supported for this input. :keyword str lpApplicationName: The name of the module or application to be executed. This can be either the fully qualified path name or a partial name. The system path will not be searched. If no value is provided for this keyword then the input to ``lpCommandLine`` will be used by Windows instead. :keyword pywincffi.wintypes.SECUREITY_ATTRIBUTES lpProcessAttributes: Determines whether the returned handle to the new process object can be inherited by child processes. By default, the handle cannot be inherited. :keyword pywincffi.wintypes.SECUREITY_ATTRIBUTES lpThreadAttributes: Determines if the returned handle to the new thread object can be inherited by child processes. By default, the thread cannot be inherited. :keyword bool bInheritHandles: If True (the default) the handles inherited by the calling process are inherited by the new process. :keyword int dwCreationFlags: Controls the priority class and creation of the process. By default the process will flag will default to ``NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT`` :keyword dict lpEnvironment: The environment for the new process. By default the the process will be created with the same environment as the parent process. .. note:: All keys and values in the environment must be either unicode (Python 2) or strings (Python 3). .. note:: This keyword will completely override the current if you wish to update the current environment instead then you will need to make and update a copy. .. warning:: Excluding certain system environment variables such as ``PATH`` or ``SYSTEMROOT`` may result in crashes or unexpected behaviors depending on the program being run. :keyword str lpCurrentDirectory: The full path to the current directory for the process. If not provided then the process will have the same working directory as the parent process. :raises InputError: Raised if ``lpCommandLine`` is too long or there are other input problems. :rtype: :class:`pywincffi.kernel32.process.CreateProcessResult` :return: Returns a named tuple containing ``lpCommandLine`` and ``lpProcessInformation``. The ``lpProcessInformation`` will be an instance of :class:`pywincffi.wintypes.structures.PROCESS_INFORMATION` """ ffi, library = dist.load() if len(lpCommandLine) > library.MAX_COMMAND_LINE: raise InputError("lpCommandLine", lpCommandLine, text_type, message="lpCommandLine's length " "cannot exceed %s" % library.MAX_COMMAND_LINE) if lpApplicationName is None: lpApplicationName = ffi.NULL # If lpApplication name is not set then lpCommandLine's # module name cannot exceed MAX_PATH. Rather than letting # this hit the Windows API and possibly fail we're check # before hand so we can provide a better exception. module = module_name(text_type(lpCommandLine)) if len(module) > library.MAX_PATH: raise InputError( "lpCommandLine", lpCommandLine, text_type, message="lpCommandLine's module name length cannot " "exceed %s if `lpApplicationName` " "is not set. Module name was %r" % (library.MAX_PATH, module)) else: input_check("lpApplicationName", lpApplicationName, allowed_types=(text_type, )) input_check("lpProcessAttributes", lpProcessAttributes, allowed_types=(SECURITY_ATTRIBUTES, NoneType)) lpProcessAttributes = wintype_to_cdata(lpProcessAttributes) input_check("lpThreadAttributes", lpThreadAttributes, allowed_types=(SECURITY_ATTRIBUTES, NoneType)) lpThreadAttributes = wintype_to_cdata(lpThreadAttributes) input_check("bInheritHandles", bInheritHandles, allowed_values=(True, False)) if dwCreationFlags is None: dwCreationFlags = \ library.NORMAL_PRIORITY_CLASS | library.CREATE_UNICODE_ENVIRONMENT input_check("dwCreationFlags", dwCreationFlags, allowed_types=(integer_types, )) if lpEnvironment is not None: lpEnvironment = _text_to_wchar(_environment_to_string(lpEnvironment)) else: lpEnvironment = ffi.NULL if lpCurrentDirectory is not None: input_check("lpCurrentDirectory", lpCurrentDirectory, allowed_types=(text_type, )) else: lpCurrentDirectory = ffi.NULL if lpStartupInfo is not None: # TODO need to add support for STARTUPINFOEX (undocumented) input_check("lpStartupInfo", lpStartupInfo, allowed_types=(STARTUPINFO, )) else: lpStartupInfo = STARTUPINFO() lpProcessInformation = PROCESS_INFORMATION() code = library.CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, wintype_to_cdata(lpStartupInfo), wintype_to_cdata(lpProcessInformation)) error_check("CreateProcess", code=code, expected=NON_ZERO) return CreateProcessResult(lpCommandLine=lpCommandLine, lpProcessInformation=lpProcessInformation)
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)