Skip to content

Commit

Permalink
Merge pull request #94 from opalmer/sal_annotations
Browse files Browse the repository at this point in the history
Support SAL Annotations In functions.h
  • Loading branch information
opalmer authored Jun 11, 2016
2 parents 3acaad5 + a6d0e7c commit 98fcc78
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 45 deletions.
10 changes: 8 additions & 2 deletions docs/source/dev/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,17 @@ The C header for function definitions is located in
:blob:`pywincffi/core/cdefs/headers/functions.h` and is sometimes referred to
the 'cdef'. When creating a new function you should essentially match what the
msdn documentation defines. If you're implementing `WriteFile` for example
you'd look at :msdn:`aa365747` and translate this to:
you'd look at :msdn:`aa365747` and copy this into `functions.h` as:

.. code-block:: c
BOOL WriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
BOOL WINAPI WriteFile(
_In_ HANDLE hFile,
_In_ LPCVOID lpBuffer,
_In_ DWORD nNumberOfBytesToWrite,
_Out_opt_ LPDWORD lpNumberOfBytesWritten,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
It's important to note here that all inputs, output, optional arguments, etc
are included in the header definition even if you don't plan on exposing them
Expand Down
251 changes: 215 additions & 36 deletions pywincffi/core/cdefs/headers/functions.h
Original file line number Diff line number Diff line change
@@ -1,48 +1,227 @@
//
// NOTE: The tests for this file, tests/test_core/test_cdefs/test_functions.py
// depend on a function's format to be the following:
// RETURN_TYPE FunctionName(...
//
///////////////////////
// Misc functions
///////////////////////

// Custom functions
VOID SetLastError(DWORD);
// https://msdn.microsoft.com/en-us/ms680627
void WINAPI SetLastError(
_In_ DWORD dwErrCode
);

///////////////////////
// Processes
HANDLE OpenProcess(DWORD, BOOL, DWORD);
BOOL GetExitCodeProcess(HANDLE, LPDWORD);
HANDLE GetCurrentProcess();
DWORD GetProcessId(HANDLE);
BOOL TerminateProcess(HANDLE, UINT);
///////////////////////

// https://msdn.microsoft.com/en-us/ms684320
HANDLE WINAPI OpenProcess(
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ DWORD dwProcessId
);

// https://msdn.microsoft.com/en-us/ms683189
BOOL WINAPI GetExitCodeProcess(
_In_ HANDLE hProcess,
_Out_ LPDWORD lpExitCode
);

// https://msdn.microsoft.com/en-us/ms683179
HANDLE WINAPI GetCurrentProcess(void);


// https://msdn.microsoft.com/en-us/ms683215
DWORD WINAPI GetProcessId(
_In_ HANDLE Process
);

// https://msdn.microsoft.com/en-us/ms686714
BOOL WINAPI TerminateProcess(
_In_ HANDLE hProcess,
_In_ UINT uExitCode
);

///////////////////////
// Pipes
BOOL CreatePipe(PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD);
BOOL PeekNamedPipe(HANDLE, LPVOID, DWORD, LPDWORD, LPDWORD, LPDWORD);
BOOL SetNamedPipeHandleState(HANDLE, LPDWORD, LPDWORD, LPDWORD);
///////////////////////

// https://msdn.microsoft.com/en-us/aa365152
BOOL WINAPI CreatePipe(
_Out_ PHANDLE hReadPipe,
_Out_ PHANDLE hWritePipe,
_In_opt_ LPSECURITY_ATTRIBUTES lpPipeAttributes,
_In_ DWORD nSize
);

// https://msdn.microsoft.com/en-us/aa365779
BOOL WINAPI PeekNamedPipe(
_In_ HANDLE hNamedPipe,
_Out_opt_ LPVOID lpBuffer,
_In_ DWORD nBufferSize,
_Out_opt_ LPDWORD lpBytesRead,
_Out_opt_ LPDWORD lpTotalBytesAvail,
_Out_opt_ LPDWORD lpBytesLeftThisMessage
);

// https://msdn.microsoft.com/en-us/aa365787
BOOL WINAPI SetNamedPipeHandleState(
_In_ HANDLE hNamedPipe,
_In_opt_ LPDWORD lpMode,
_In_opt_ LPDWORD lpMaxCollectionCount,
_In_opt_ LPDWORD lpCollectDataTimeout
);


///////////////////////
// Files
HANDLE CreateFile(
LPCTSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
BOOL WriteFile(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
BOOL FlushFileBuffers(HANDLE);
BOOL ReadFile(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
BOOL MoveFileEx(LPCTSTR, LPCTSTR, DWORD);
BOOL LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED);
BOOL UnlockFileEx(HANDLE, DWORD, DWORD, DWORD, LPOVERLAPPED);

// Handles
///////////////////////

// https://msdn.microsoft.com/en-us/aa363858
HANDLE WINAPI CreateFile(
_In_ LPCTSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
);

// https://msdn.microsoft.com/en-us/aa365747
BOOL WINAPI WriteFile(
_In_ HANDLE hFile,
_In_ LPCVOID lpBuffer,
_In_ DWORD nNumberOfBytesToWrite,
_Out_opt_ LPDWORD lpNumberOfBytesWritten,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);

// https://msdn.microsoft.com/en-us/aa364439
BOOL WINAPI FlushFileBuffers(
_In_ HANDLE hFile
);

// https://msdn.microsoft.com/en-us/aa365467
BOOL WINAPI ReadFile(
_In_ HANDLE hFile,
_Out_ LPVOID lpBuffer,
_In_ DWORD nNumberOfBytesToRead,
_Out_opt_ LPDWORD lpNumberOfBytesRead,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);

// https://msdn.microsoft.com/en-us/aa365240
BOOL WINAPI MoveFileEx(
_In_ LPCTSTR lpExistingFileName,
_In_opt_ LPCTSTR lpNewFileName,
_In_ DWORD dwFlags
);

// https://msdn.microsoft.com/en-us/aa365203
BOOL WINAPI LockFileEx(
_In_ HANDLE hFile,
_In_ DWORD dwFlags,
_Reserved_ DWORD dwReserved,
_In_ DWORD nNumberOfBytesToLockLow,
_In_ DWORD nNumberOfBytesToLockHigh,
_Inout_ LPOVERLAPPED lpOverlapped
);

// https://msdn.microsoft.com/en-us/aa365716
BOOL WINAPI UnlockFileEx(
_In_ HANDLE hFile,
_Reserved_ DWORD dwReserved,
_In_ DWORD nNumberOfBytesToUnlockLow,
_In_ DWORD nNumberOfBytesToUnlockHigh,
_Inout_ LPOVERLAPPED lpOverlapped
);

///////////////////////
// Files
///////////////////////

HANDLE handle_from_fd(int);
BOOL CloseHandle(HANDLE);
HANDLE GetStdHandle(DWORD);
DWORD WaitForSingleObject(HANDLE, DWORD);
BOOL GetHandleInformation(HANDLE, LPDWORD);
BOOL SetHandleInformation(HANDLE, DWORD, DWORD);
BOOL DuplicateHandle(HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD);
DWORD MsgWaitForMultipleObjects(DWORD, HANDLE, BOOL, DWORD, DWORD);

// https://msdn.microsoft.com/en-us/ms724211
BOOL WINAPI CloseHandle(
_In_ HANDLE hObject
);

// https://msdn.microsoft.com/en-us/ms683231
HANDLE WINAPI GetStdHandle(
_In_ DWORD nStdHandle
);

// https://msdn.microsoft.com/en-us/ms687032
DWORD WINAPI WaitForSingleObject(
_In_ HANDLE hHandle,
_In_ DWORD dwMilliseconds
);

// https://msdn.microsoft.com/en-us/ms724329
BOOL WINAPI GetHandleInformation(
_In_ HANDLE hObject,
_Out_ LPDWORD lpdwFlags
);

// https://msdn.microsoft.com/en-us/ms724935
BOOL WINAPI SetHandleInformation(
_In_ HANDLE hObject,
_In_ DWORD dwMask,
_In_ DWORD dwFlags
);

// https://msdn.microsoft.com/en-us/ms724251
BOOL WINAPI DuplicateHandle(
_In_ HANDLE hSourceProcessHandle,
_In_ HANDLE hSourceHandle,
_In_ HANDLE hTargetProcessHandle,
_Out_ LPHANDLE lpTargetHandle,
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ DWORD dwOptions
);

// https://msdn.microsoft.com/en-us/ms684242
DWORD WINAPI MsgWaitForMultipleObjects(
_In_ DWORD nCount,
_In_ const HANDLE *pHandles,
_In_ BOOL bWaitAll,
_In_ DWORD dwMilliseconds,
_In_ DWORD dwWakeMask
);


///////////////////////
// Events
HANDLE CreateEvent(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCTSTR);
HANDLE OpenEvent(DWORD, BOOL, LPCTSTR);
BOOL ResetEvent(HANDLE);
///////////////////////

// https://msdn.microsoft.com/en-us/ms682396
HANDLE WINAPI CreateEvent(
_In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
_In_ BOOL bManualReset,
_In_ BOOL bInitialState,
_In_opt_ LPCTSTR lpName
);

// https://msdn.microsoft.com/en-us/ms684305
HANDLE WINAPI OpenEvent(
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ LPCTSTR lpName
);

// https://msdn.microsoft.com/en-us/ms685081
BOOL WINAPI ResetEvent(
_In_ HANDLE hEvent
);


///////////////////////
// Communications
BOOL ClearCommError(HANDLE, LPDWORD, LPCOMSTAT);
///////////////////////

// https://msdn.microsoft.com/en-us/aa363180
BOOL WINAPI ClearCommError(
_In_ HANDLE hFile,
_Out_opt_ LPDWORD lpErrors,
_Out_opt_ LPCOMSTAT lpStat
);
9 changes: 8 additions & 1 deletion pywincffi/core/dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
for distribution.
"""

import re
import shutil
import tempfile
import warnings
Expand Down Expand Up @@ -58,6 +59,8 @@
resource_filename(
"pywincffi", join("core", "cdefs", "sources", "main.c")), )
LIBRARIES = ("kernel32", "user32")
REGEX_SAL_ANNOTATION = re.compile(
r"\b(_In_|_Inout_|_Out_|_Outptr_|_Reserved_)(opt_)?\b")


class Module(object): # pylint: disable=too-few-public-methods
Expand Down Expand Up @@ -172,7 +175,11 @@ def _ffi(
ffi = FFI()
ffi.set_unicode(True)
ffi.set_source(module_name, source, libraries=libraries)
ffi.cdef(header)

# Windows uses SAL annotations which can provide some helpful information
# about the inputs and outputs to a function. Rather than require these
# to be stripped out manually we should strip them out programmatically.
ffi.cdef(REGEX_SAL_ANNOTATION.sub(" ", header))

return ffi

Expand Down
6 changes: 0 additions & 6 deletions tests/test_core/test_dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,6 @@ def test_default_source_files(self):
mocked_set_source.assert_called_once_with(
self.module_name, _read(*SOURCE_FILES), libraries=LIBRARIES)

def test_default_cdefs(self):
with patch.object(FFI, "cdef") as mocked_cdef:
_ffi(module_name=self.module_name)

mocked_cdef.assert_called_with(_read(*HEADER_FILES))

def test_alternate_source_files(self):
_, path = tempfile.mkstemp(suffix=".h")

Expand Down

0 comments on commit 98fcc78

Please sign in to comment.