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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
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)
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)