summaryrefslogtreecommitdiffstats
path: root/Modules/_winapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_winapi.c')
-rw-r--r--Modules/_winapi.c991
1 files changed, 606 insertions, 385 deletions
diff --git a/Modules/_winapi.c b/Modules/_winapi.c
index d472c9e..3e7f187 100644
--- a/Modules/_winapi.c
+++ b/Modules/_winapi.c
@@ -40,6 +40,7 @@
#define WINDOWS_LEAN_AND_MEAN
#include "windows.h"
#include <crtdbg.h>
+#include "winreparse.h"
#if defined(MS_WIN32) && !defined(MS_WIN64)
#define HANDLE_TO_PYNUM(handle) \
@@ -57,8 +58,6 @@
#define F_HANDLE F_POINTER
#define F_DWORD "k"
-#define F_BOOL "i"
-#define F_UINT "I"
#define T_HANDLE T_POINTER
@@ -146,17 +145,68 @@ overlapped_dealloc(OverlappedObject *self)
PyObject_Del(self);
}
+/*[clinic input]
+module _winapi
+class _winapi.Overlapped "OverlappedObject *" "&OverlappedType"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c13d3f5fd1dabb84]*/
+
+/*[python input]
+def create_converter(type_, format_unit):
+ name = type_ + '_converter'
+ # registered upon creation by CConverter's metaclass
+ type(name, (CConverter,), {'type': type_, 'format_unit': format_unit})
+
+# format unit differs between platforms for these
+create_converter('HANDLE', '" F_HANDLE "')
+create_converter('HMODULE', '" F_HANDLE "')
+create_converter('LPSECURITY_ATTRIBUTES', '" F_POINTER "')
+
+create_converter('BOOL', 'i') # F_BOOL used previously (always 'i')
+create_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter)
+create_converter('LPCTSTR', 's')
+create_converter('LPWSTR', 'u')
+create_converter('UINT', 'I') # F_UINT used previously (always 'I')
+
+class HANDLE_return_converter(CReturnConverter):
+ type = 'HANDLE'
+
+ def render(self, function, data):
+ self.declare(data)
+ self.err_occurred_if("_return_value == INVALID_HANDLE_VALUE", data)
+ data.return_conversion.append(
+ 'if (_return_value == NULL)\n Py_RETURN_NONE;\n')
+ data.return_conversion.append(
+ 'return_value = HANDLE_TO_PYNUM(_return_value);\n')
+
+class DWORD_return_converter(CReturnConverter):
+ type = 'DWORD'
+
+ def render(self, function, data):
+ self.declare(data)
+ self.err_occurred_if("_return_value == DWORD_MAX", data)
+ data.return_conversion.append(
+ 'return_value = Py_BuildValue("k", _return_value);\n')
+[python start generated code]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=374076979596ebba]*/
+
+#include "clinic/_winapi.c.h"
+
+/*[clinic input]
+_winapi.Overlapped.GetOverlappedResult
+
+ wait: bool
+ /
+[clinic start generated code]*/
+
static PyObject *
-overlapped_GetOverlappedResult(OverlappedObject *self, PyObject *waitobj)
+_winapi_Overlapped_GetOverlappedResult_impl(OverlappedObject *self, int wait)
+/*[clinic end generated code: output=bdd0c1ed6518cd03 input=194505ee8e0e3565]*/
{
- int wait;
BOOL res;
DWORD transferred = 0;
DWORD err;
- wait = PyObject_IsTrue(waitobj);
- if (wait < 0)
- return NULL;
Py_BEGIN_ALLOW_THREADS
res = GetOverlappedResult(self->handle, &self->overlapped, &transferred,
wait != 0);
@@ -185,8 +235,13 @@ overlapped_GetOverlappedResult(OverlappedObject *self, PyObject *waitobj)
return Py_BuildValue("II", (unsigned) transferred, (unsigned) err);
}
+/*[clinic input]
+_winapi.Overlapped.getbuffer
+[clinic start generated code]*/
+
static PyObject *
-overlapped_getbuffer(OverlappedObject *self)
+_winapi_Overlapped_getbuffer_impl(OverlappedObject *self)
+/*[clinic end generated code: output=95a3eceefae0f748 input=347fcfd56b4ceabd]*/
{
PyObject *res;
if (!self->completed) {
@@ -200,8 +255,13 @@ overlapped_getbuffer(OverlappedObject *self)
return res;
}
+/*[clinic input]
+_winapi.Overlapped.cancel
+[clinic start generated code]*/
+
static PyObject *
-overlapped_cancel(OverlappedObject *self)
+_winapi_Overlapped_cancel_impl(OverlappedObject *self)
+/*[clinic end generated code: output=fcb9ab5df4ebdae5 input=cbf3da142290039f]*/
{
BOOL res = TRUE;
@@ -222,10 +282,9 @@ overlapped_cancel(OverlappedObject *self)
}
static PyMethodDef overlapped_methods[] = {
- {"GetOverlappedResult", (PyCFunction) overlapped_GetOverlappedResult,
- METH_O, NULL},
- {"getbuffer", (PyCFunction) overlapped_getbuffer, METH_NOARGS, NULL},
- {"cancel", (PyCFunction) overlapped_cancel, METH_NOARGS, NULL},
+ _WINAPI_OVERLAPPED_GETOVERLAPPEDRESULT_METHODDEF
+ _WINAPI_OVERLAPPED_GETBUFFER_METHODDEF
+ _WINAPI_OVERLAPPED_CANCEL_METHODDEF
{NULL}
};
@@ -299,22 +358,23 @@ new_overlapped(HANDLE handle)
/* -------------------------------------------------------------------- */
/* windows API functions */
-PyDoc_STRVAR(CloseHandle_doc,
-"CloseHandle(handle) -> None\n\
-\n\
-Close handle.");
+/*[clinic input]
+_winapi.CloseHandle
+
+ handle: HANDLE
+ /
+
+Close handle.
+[clinic start generated code]*/
static PyObject *
-winapi_CloseHandle(PyObject *self, PyObject *args)
+_winapi_CloseHandle_impl(PyModuleDef *module, HANDLE handle)
+/*[clinic end generated code: output=0548595c71cb4bf7 input=7f0e4ac36e0352b8]*/
{
- HANDLE hObject;
BOOL success;
- if (!PyArg_ParseTuple(args, F_HANDLE ":CloseHandle", &hObject))
- return NULL;
-
Py_BEGIN_ALLOW_THREADS
- success = CloseHandle(hObject);
+ success = CloseHandle(handle);
Py_END_ALLOW_THREADS
if (!success)
@@ -323,28 +383,29 @@ winapi_CloseHandle(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+/*[clinic input]
+_winapi.ConnectNamedPipe
+
+ handle: HANDLE
+ overlapped as use_overlapped: int(c_default='0') = False
+[clinic start generated code]*/
+
static PyObject *
-winapi_ConnectNamedPipe(PyObject *self, PyObject *args, PyObject *kwds)
+_winapi_ConnectNamedPipe_impl(PyModuleDef *module, HANDLE handle,
+ int use_overlapped)
+/*[clinic end generated code: output=fed3b165d1bca95a input=edc83da007ebf3be]*/
{
- HANDLE hNamedPipe;
- int use_overlapped = 0;
BOOL success;
OverlappedObject *overlapped = NULL;
- static char *kwlist[] = {"handle", "overlapped", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds,
- F_HANDLE "|" F_BOOL, kwlist,
- &hNamedPipe, &use_overlapped))
- return NULL;
if (use_overlapped) {
- overlapped = new_overlapped(hNamedPipe);
+ overlapped = new_overlapped(handle);
if (!overlapped)
return NULL;
}
Py_BEGIN_ALLOW_THREADS
- success = ConnectNamedPipe(hNamedPipe,
+ success = ConnectNamedPipe(handle,
overlapped ? &overlapped->overlapped : NULL);
Py_END_ALLOW_THREADS
@@ -368,94 +429,238 @@ winapi_ConnectNamedPipe(PyObject *self, PyObject *args, PyObject *kwds)
Py_RETURN_NONE;
}
-static PyObject *
-winapi_CreateFile(PyObject *self, PyObject *args)
+/*[clinic input]
+_winapi.CreateFile -> HANDLE
+
+ file_name: LPCTSTR
+ desired_access: DWORD
+ share_mode: DWORD
+ security_attributes: LPSECURITY_ATTRIBUTES
+ creation_disposition: DWORD
+ flags_and_attributes: DWORD
+ template_file: HANDLE
+ /
+[clinic start generated code]*/
+
+static HANDLE
+_winapi_CreateFile_impl(PyModuleDef *module, LPCTSTR file_name,
+ DWORD desired_access, DWORD share_mode,
+ LPSECURITY_ATTRIBUTES security_attributes,
+ DWORD creation_disposition,
+ DWORD flags_and_attributes, HANDLE template_file)
+/*[clinic end generated code: output=c6e1d78f8affd10c input=6423c3e40372dbd5]*/
{
- LPCTSTR lpFileName;
- DWORD dwDesiredAccess;
- DWORD dwShareMode;
- LPSECURITY_ATTRIBUTES lpSecurityAttributes;
- DWORD dwCreationDisposition;
- DWORD dwFlagsAndAttributes;
- HANDLE hTemplateFile;
HANDLE handle;
- if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_POINTER
- F_DWORD F_DWORD F_HANDLE,
- &lpFileName, &dwDesiredAccess, &dwShareMode,
- &lpSecurityAttributes, &dwCreationDisposition,
- &dwFlagsAndAttributes, &hTemplateFile))
- return NULL;
-
Py_BEGIN_ALLOW_THREADS
- handle = CreateFile(lpFileName, dwDesiredAccess,
- dwShareMode, lpSecurityAttributes,
- dwCreationDisposition,
- dwFlagsAndAttributes, hTemplateFile);
+ handle = CreateFile(file_name, desired_access,
+ share_mode, security_attributes,
+ creation_disposition,
+ flags_and_attributes, template_file);
Py_END_ALLOW_THREADS
if (handle == INVALID_HANDLE_VALUE)
- return PyErr_SetFromWindowsErr(0);
+ PyErr_SetFromWindowsErr(0);
- return Py_BuildValue(F_HANDLE, handle);
+ return handle;
}
+/*[clinic input]
+_winapi.CreateJunction
+
+ src_path: LPWSTR
+ dst_path: LPWSTR
+ /
+[clinic start generated code]*/
+
static PyObject *
-winapi_CreateNamedPipe(PyObject *self, PyObject *args)
+_winapi_CreateJunction_impl(PyModuleDef *module, LPWSTR src_path,
+ LPWSTR dst_path)
+/*[clinic end generated code: output=eccae9364e46f6da input=8cd1f9964b6e3d36]*/
{
- LPCTSTR lpName;
- DWORD dwOpenMode;
- DWORD dwPipeMode;
- DWORD nMaxInstances;
- DWORD nOutBufferSize;
- DWORD nInBufferSize;
- DWORD nDefaultTimeOut;
- LPSECURITY_ATTRIBUTES lpSecurityAttributes;
- HANDLE handle;
+ /* Privilege adjustment */
+ HANDLE token = NULL;
+ TOKEN_PRIVILEGES tp;
+
+ /* Reparse data buffer */
+ const USHORT prefix_len = 4;
+ USHORT print_len = 0;
+ USHORT rdb_size = 0;
+ PREPARSE_DATA_BUFFER rdb = NULL;
+
+ /* Junction point creation */
+ HANDLE junction = NULL;
+ DWORD ret = 0;
+
+ if (src_path == NULL || dst_path == NULL)
+ return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER);
+
+ if (wcsncmp(src_path, L"\\??\\", prefix_len) == 0)
+ return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER);
+
+ /* Adjust privileges to allow rewriting directory entry as a
+ junction point. */
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
+ goto cleanup;
+
+ if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid))
+ goto cleanup;
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
+ NULL, NULL))
+ goto cleanup;
+
+ if (GetFileAttributesW(src_path) == INVALID_FILE_ATTRIBUTES)
+ goto cleanup;
+
+ /* Store the absolute link target path length in print_len. */
+ print_len = (USHORT)GetFullPathNameW(src_path, 0, NULL, NULL);
+ if (print_len == 0)
+ goto cleanup;
+
+ /* NUL terminator should not be part of print_len. */
+ --print_len;
+
+ /* REPARSE_DATA_BUFFER usage is heavily under-documented, especially for
+ junction points. Here's what I've learned along the way:
+ - A junction point has two components: a print name and a substitute
+ name. They both describe the link target, but the substitute name is
+ the physical target and the print name is shown in directory listings.
+ - The print name must be a native name, prefixed with "\??\".
+ - Both names are stored after each other in the same buffer (the
+ PathBuffer) and both must be NUL-terminated.
+ - There are four members defining their respective offset and length
+ inside PathBuffer: SubstituteNameOffset, SubstituteNameLength,
+ PrintNameOffset and PrintNameLength.
+ - The total size we need to allocate for the REPARSE_DATA_BUFFER, thus,
+ is the sum of:
+ - the fixed header size (REPARSE_DATA_BUFFER_HEADER_SIZE)
+ - the size of the MountPointReparseBuffer member without the PathBuffer
+ - the size of the prefix ("\??\") in bytes
+ - the size of the print name in bytes
+ - the size of the substitute name in bytes
+ - the size of two NUL terminators in bytes */
+ rdb_size = REPARSE_DATA_BUFFER_HEADER_SIZE +
+ sizeof(rdb->MountPointReparseBuffer) -
+ sizeof(rdb->MountPointReparseBuffer.PathBuffer) +
+ /* Two +1's for NUL terminators. */
+ (prefix_len + print_len + 1 + print_len + 1) * sizeof(WCHAR);
+ rdb = (PREPARSE_DATA_BUFFER)PyMem_RawMalloc(rdb_size);
+ if (rdb == NULL)
+ goto cleanup;
+
+ memset(rdb, 0, rdb_size);
+ rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
+ rdb->ReparseDataLength = rdb_size - REPARSE_DATA_BUFFER_HEADER_SIZE;
+ rdb->MountPointReparseBuffer.SubstituteNameOffset = 0;
+ rdb->MountPointReparseBuffer.SubstituteNameLength =
+ (prefix_len + print_len) * sizeof(WCHAR);
+ rdb->MountPointReparseBuffer.PrintNameOffset =
+ rdb->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR);
+ rdb->MountPointReparseBuffer.PrintNameLength = print_len * sizeof(WCHAR);
+
+ /* Store the full native path of link target at the substitute name
+ offset (0). */
+ wcscpy(rdb->MountPointReparseBuffer.PathBuffer, L"\\??\\");
+ if (GetFullPathNameW(src_path, print_len + 1,
+ rdb->MountPointReparseBuffer.PathBuffer + prefix_len,
+ NULL) == 0)
+ goto cleanup;
+
+ /* Copy everything but the native prefix to the print name offset. */
+ wcscpy(rdb->MountPointReparseBuffer.PathBuffer +
+ prefix_len + print_len + 1,
+ rdb->MountPointReparseBuffer.PathBuffer + prefix_len);
+
+ /* Create a directory for the junction point. */
+ if (!CreateDirectoryW(dst_path, NULL))
+ goto cleanup;
+
+ junction = CreateFileW(dst_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (junction == INVALID_HANDLE_VALUE)
+ goto cleanup;
+
+ /* Make the directory entry a junction point. */
+ if (!DeviceIoControl(junction, FSCTL_SET_REPARSE_POINT, rdb, rdb_size,
+ NULL, 0, &ret, NULL))
+ goto cleanup;
+
+cleanup:
+ ret = GetLastError();
+
+ CloseHandle(token);
+ CloseHandle(junction);
+ PyMem_RawFree(rdb);
+
+ if (ret != 0)
+ return PyErr_SetFromWindowsErr(ret);
- if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_DWORD
- F_DWORD F_DWORD F_DWORD F_POINTER,
- &lpName, &dwOpenMode, &dwPipeMode,
- &nMaxInstances, &nOutBufferSize,
- &nInBufferSize, &nDefaultTimeOut,
- &lpSecurityAttributes))
- return NULL;
+ Py_RETURN_NONE;
+}
+
+/*[clinic input]
+_winapi.CreateNamedPipe -> HANDLE
+
+ name: LPCTSTR
+ open_mode: DWORD
+ pipe_mode: DWORD
+ max_instances: DWORD
+ out_buffer_size: DWORD
+ in_buffer_size: DWORD
+ default_timeout: DWORD
+ security_attributes: LPSECURITY_ATTRIBUTES
+ /
+[clinic start generated code]*/
+
+static HANDLE
+_winapi_CreateNamedPipe_impl(PyModuleDef *module, LPCTSTR name,
+ DWORD open_mode, DWORD pipe_mode,
+ DWORD max_instances, DWORD out_buffer_size,
+ DWORD in_buffer_size, DWORD default_timeout,
+ LPSECURITY_ATTRIBUTES security_attributes)
+/*[clinic end generated code: output=44ca2a06a219b523 input=5a73530b84d8bc37]*/
+{
+ HANDLE handle;
Py_BEGIN_ALLOW_THREADS
- handle = CreateNamedPipe(lpName, dwOpenMode, dwPipeMode,
- nMaxInstances, nOutBufferSize,
- nInBufferSize, nDefaultTimeOut,
- lpSecurityAttributes);
+ handle = CreateNamedPipe(name, open_mode, pipe_mode,
+ max_instances, out_buffer_size,
+ in_buffer_size, default_timeout,
+ security_attributes);
Py_END_ALLOW_THREADS
if (handle == INVALID_HANDLE_VALUE)
- return PyErr_SetFromWindowsErr(0);
+ PyErr_SetFromWindowsErr(0);
- return Py_BuildValue(F_HANDLE, handle);
+ return handle;
}
-PyDoc_STRVAR(CreatePipe_doc,
-"CreatePipe(pipe_attrs, size) -> (read_handle, write_handle)\n\
-\n\
-Create an anonymous pipe, and return handles to the read and\n\
-write ends of the pipe.\n\
-\n\
-pipe_attrs is ignored internally and can be None.");
+/*[clinic input]
+_winapi.CreatePipe
+
+ pipe_attrs: object
+ Ignored internally, can be None.
+ size: DWORD
+ /
+
+Create an anonymous pipe.
+
+Returns a 2-tuple of handles, to the read and write ends of the pipe.
+[clinic start generated code]*/
static PyObject *
-winapi_CreatePipe(PyObject* self, PyObject* args)
+_winapi_CreatePipe_impl(PyModuleDef *module, PyObject *pipe_attrs,
+ DWORD size)
+/*[clinic end generated code: output=fef99f3b4222bc78 input=c4f2cfa56ef68d90]*/
{
HANDLE read_pipe;
HANDLE write_pipe;
BOOL result;
- PyObject* pipe_attributes; /* ignored */
- DWORD size;
-
- if (! PyArg_ParseTuple(args, "O" F_DWORD ":CreatePipe",
- &pipe_attributes, &size))
- return NULL;
-
Py_BEGIN_ALLOW_THREADS
result = CreatePipe(&read_pipe, &write_pipe, NULL, size);
Py_END_ALLOW_THREADS
@@ -586,20 +791,36 @@ getenvironment(PyObject* environment)
return NULL;
}
-PyDoc_STRVAR(CreateProcess_doc,
-"CreateProcess(app_name, cmd_line, proc_attrs, thread_attrs,\n\
- inherit, flags, env_mapping, curdir,\n\
- startup_info) -> (proc_handle, thread_handle,\n\
- pid, tid)\n\
-\n\
-Create a new process and its primary thread. The return\n\
-value is a tuple of the process handle, thread handle,\n\
-process ID, and thread ID.\n\
-\n\
-proc_attrs and thread_attrs are ignored internally and can be None.");
+/*[clinic input]
+_winapi.CreateProcess
+
+ application_name: Py_UNICODE(accept={str, NoneType})
+ command_line: Py_UNICODE(accept={str, NoneType})
+ proc_attrs: object
+ Ignored internally, can be None.
+ thread_attrs: object
+ Ignored internally, can be None.
+ inherit_handles: BOOL
+ creation_flags: DWORD
+ env_mapping: object
+ current_directory: Py_UNICODE(accept={str, NoneType})
+ startup_info: object
+ /
+
+Create a new process and its primary thread.
+
+The return value is a tuple of the process handle, thread handle,
+process ID, and thread ID.
+[clinic start generated code]*/
static PyObject *
-winapi_CreateProcess(PyObject* self, PyObject* args)
+_winapi_CreateProcess_impl(PyModuleDef *module, Py_UNICODE *application_name,
+ Py_UNICODE *command_line, PyObject *proc_attrs,
+ PyObject *thread_attrs, BOOL inherit_handles,
+ DWORD creation_flags, PyObject *env_mapping,
+ Py_UNICODE *current_directory,
+ PyObject *startup_info)
+/*[clinic end generated code: output=874bb350ff9ed4ef input=4a43b05038d639bb]*/
{
BOOL result;
PROCESS_INFORMATION pi;
@@ -607,28 +828,6 @@ winapi_CreateProcess(PyObject* self, PyObject* args)
PyObject* environment;
wchar_t *wenvironment;
- wchar_t* application_name;
- wchar_t* command_line;
- PyObject* process_attributes; /* ignored */
- PyObject* thread_attributes; /* ignored */
- BOOL inherit_handles;
- DWORD creation_flags;
- PyObject* env_mapping;
- wchar_t* current_directory;
- PyObject* startup_info;
-
- if (! PyArg_ParseTuple(args, "ZZOO" F_BOOL F_DWORD "OZO:CreateProcess",
- &application_name,
- &command_line,
- &process_attributes,
- &thread_attributes,
- &inherit_handles,
- &creation_flags,
- &env_mapping,
- &current_directory,
- &startup_info))
- return NULL;
-
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
@@ -682,41 +881,36 @@ winapi_CreateProcess(PyObject* self, PyObject* args)
pi.dwThreadId);
}
-PyDoc_STRVAR(DuplicateHandle_doc,
-"DuplicateHandle(source_proc_handle, source_handle,\n\
- target_proc_handle, target_handle, access,\n\
- inherit[, options]) -> handle\n\
-\n\
-Return a duplicate handle object.\n\
-\n\
-The duplicate handle refers to the same object as the original\n\
-handle. Therefore, any changes to the object are reflected\n\
-through both handles.");
+/*[clinic input]
+_winapi.DuplicateHandle -> HANDLE
-static PyObject *
-winapi_DuplicateHandle(PyObject* self, PyObject* args)
+ source_process_handle: HANDLE
+ source_handle: HANDLE
+ target_process_handle: HANDLE
+ desired_access: DWORD
+ inherit_handle: BOOL
+ options: DWORD = 0
+ /
+
+Return a duplicate handle object.
+
+The duplicate handle refers to the same object as the original
+handle. Therefore, any changes to the object are reflected
+through both handles.
+[clinic start generated code]*/
+
+static HANDLE
+_winapi_DuplicateHandle_impl(PyModuleDef *module,
+ HANDLE source_process_handle,
+ HANDLE source_handle,
+ HANDLE target_process_handle,
+ DWORD desired_access, BOOL inherit_handle,
+ DWORD options)
+/*[clinic end generated code: output=0799515b68b5237b input=b933e3f2356a8c12]*/
{
HANDLE target_handle;
BOOL result;
- HANDLE source_process_handle;
- HANDLE source_handle;
- HANDLE target_process_handle;
- DWORD desired_access;
- BOOL inherit_handle;
- DWORD options = 0;
-
- if (! PyArg_ParseTuple(args,
- F_HANDLE F_HANDLE F_HANDLE F_DWORD F_BOOL F_DWORD
- ":DuplicateHandle",
- &source_process_handle,
- &source_handle,
- &target_process_handle,
- &desired_access,
- &inherit_handle,
- &options))
- return NULL;
-
Py_BEGIN_ALLOW_THREADS
result = DuplicateHandle(
source_process_handle,
@@ -729,98 +923,111 @@ winapi_DuplicateHandle(PyObject* self, PyObject* args)
);
Py_END_ALLOW_THREADS
- if (! result)
- return PyErr_SetFromWindowsErr(GetLastError());
+ if (! result) {
+ PyErr_SetFromWindowsErr(GetLastError());
+ return INVALID_HANDLE_VALUE;
+ }
- return HANDLE_TO_PYNUM(target_handle);
+ return target_handle;
}
-static PyObject *
-winapi_ExitProcess(PyObject *self, PyObject *args)
-{
- UINT uExitCode;
+/*[clinic input]
+_winapi.ExitProcess
- if (!PyArg_ParseTuple(args, F_UINT, &uExitCode))
- return NULL;
+ ExitCode: UINT
+ /
+
+[clinic start generated code]*/
+static PyObject *
+_winapi_ExitProcess_impl(PyModuleDef *module, UINT ExitCode)
+/*[clinic end generated code: output=25f3b499c24cedc8 input=4f05466a9406c558]*/
+{
#if defined(Py_DEBUG)
SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|
SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
#endif
- ExitProcess(uExitCode);
+ ExitProcess(ExitCode);
return NULL;
}
-PyDoc_STRVAR(GetCurrentProcess_doc,
-"GetCurrentProcess() -> handle\n\
-\n\
-Return a handle object for the current process.");
+/*[clinic input]
+_winapi.GetCurrentProcess -> HANDLE
-static PyObject *
-winapi_GetCurrentProcess(PyObject* self, PyObject* args)
-{
- if (! PyArg_ParseTuple(args, ":GetCurrentProcess"))
- return NULL;
+Return a handle object for the current process.
+[clinic start generated code]*/
- return HANDLE_TO_PYNUM(GetCurrentProcess());
+static HANDLE
+_winapi_GetCurrentProcess_impl(PyModuleDef *module)
+/*[clinic end generated code: output=be29ac3ad5f8291e input=b213403fd4b96b41]*/
+{
+ return GetCurrentProcess();
}
-PyDoc_STRVAR(GetExitCodeProcess_doc,
-"GetExitCodeProcess(handle) -> Exit code\n\
-\n\
-Return the termination status of the specified process.");
+/*[clinic input]
+_winapi.GetExitCodeProcess -> DWORD
-static PyObject *
-winapi_GetExitCodeProcess(PyObject* self, PyObject* args)
+ process: HANDLE
+ /
+
+Return the termination status of the specified process.
+[clinic start generated code]*/
+
+static DWORD
+_winapi_GetExitCodeProcess_impl(PyModuleDef *module, HANDLE process)
+/*[clinic end generated code: output=0b10f0848a410f65 input=61b6bfc7dc2ee374]*/
{
DWORD exit_code;
BOOL result;
- HANDLE process;
- if (! PyArg_ParseTuple(args, F_HANDLE ":GetExitCodeProcess", &process))
- return NULL;
-
result = GetExitCodeProcess(process, &exit_code);
- if (! result)
- return PyErr_SetFromWindowsErr(GetLastError());
+ if (! result) {
+ PyErr_SetFromWindowsErr(GetLastError());
+ exit_code = DWORD_MAX;
+ }
- return PyLong_FromUnsignedLong(exit_code);
+ return exit_code;
}
-static PyObject *
-winapi_GetLastError(PyObject *self, PyObject *args)
+/*[clinic input]
+_winapi.GetLastError -> DWORD
+[clinic start generated code]*/
+
+static DWORD
+_winapi_GetLastError_impl(PyModuleDef *module)
+/*[clinic end generated code: output=0ea00d8e67bdd056 input=62d47fb9bce038ba]*/
{
- return Py_BuildValue(F_DWORD, GetLastError());
+ return GetLastError();
}
-PyDoc_STRVAR(GetModuleFileName_doc,
-"GetModuleFileName(module) -> path\n\
-\n\
-Return the fully-qualified path for the file that contains\n\
-the specified module. The module must have been loaded by the\n\
-current process.\n\
-\n\
-The module parameter should be a handle to the loaded module\n\
-whose path is being requested. If this parameter is 0, \n\
-GetModuleFileName retrieves the path of the executable file\n\
-of the current process.");
+/*[clinic input]
+_winapi.GetModuleFileName
+
+ module_handle: HMODULE
+ /
+
+Return the fully-qualified path for the file that contains module.
+
+The module must have been loaded by the current process.
+
+The module parameter should be a handle to the loaded module
+whose path is being requested. If this parameter is 0,
+GetModuleFileName retrieves the path of the executable file
+of the current process.
+[clinic start generated code]*/
static PyObject *
-winapi_GetModuleFileName(PyObject* self, PyObject* args)
+_winapi_GetModuleFileName_impl(PyModuleDef *module, HMODULE module_handle)
+/*[clinic end generated code: output=90063dc63bdbfa18 input=6d66ff7deca5d11f]*/
{
BOOL result;
- HMODULE module;
WCHAR filename[MAX_PATH];
- if (! PyArg_ParseTuple(args, F_HANDLE ":GetModuleFileName",
- &module))
- return NULL;
-
- result = GetModuleFileNameW(module, filename, MAX_PATH);
+ result = GetModuleFileNameW(module_handle, filename, MAX_PATH);
filename[MAX_PATH-1] = '\0';
if (! result)
@@ -829,83 +1036,96 @@ winapi_GetModuleFileName(PyObject* self, PyObject* args)
return PyUnicode_FromWideChar(filename, wcslen(filename));
}
-PyDoc_STRVAR(GetStdHandle_doc,
-"GetStdHandle(handle) -> integer\n\
-\n\
-Return a handle to the specified standard device\n\
-(STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE).\n\
-The integer associated with the handle object is returned.");
+/*[clinic input]
+_winapi.GetStdHandle -> HANDLE
-static PyObject *
-winapi_GetStdHandle(PyObject* self, PyObject* args)
+ std_handle: DWORD
+ One of STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE.
+ /
+
+Return a handle to the specified standard device.
+
+The integer associated with the handle object is returned.
+[clinic start generated code]*/
+
+static HANDLE
+_winapi_GetStdHandle_impl(PyModuleDef *module, DWORD std_handle)
+/*[clinic end generated code: output=5f5ca28b28c6fad2 input=07016b06a2fc8826]*/
{
HANDLE handle;
- DWORD std_handle;
-
- if (! PyArg_ParseTuple(args, F_DWORD ":GetStdHandle", &std_handle))
- return NULL;
Py_BEGIN_ALLOW_THREADS
handle = GetStdHandle(std_handle);
Py_END_ALLOW_THREADS
if (handle == INVALID_HANDLE_VALUE)
- return PyErr_SetFromWindowsErr(GetLastError());
+ PyErr_SetFromWindowsErr(GetLastError());
- if (! handle) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- /* note: returns integer, not handle object */
- return HANDLE_TO_PYNUM(handle);
+ return handle;
}
-PyDoc_STRVAR(GetVersion_doc,
-"GetVersion() -> version\n\
-\n\
-Return the version number of the current operating system.");
+/*[clinic input]
+_winapi.GetVersion -> long
-static PyObject *
-winapi_GetVersion(PyObject* self, PyObject* args)
-{
- if (! PyArg_ParseTuple(args, ":GetVersion"))
- return NULL;
+Return the version number of the current operating system.
+[clinic start generated code]*/
+
+static long
+_winapi_GetVersion_impl(PyModuleDef *module)
+/*[clinic end generated code: output=95a2f8ad3b948ca8 input=e21dff8d0baeded2]*/
+/* Disable deprecation warnings about GetVersionEx as the result is
+ being passed straight through to the caller, who is responsible for
+ using it correctly. */
+#pragma warning(push)
+#pragma warning(disable:4996)
- return PyLong_FromUnsignedLong(GetVersion());
+{
+ return GetVersion();
}
-static PyObject *
-winapi_OpenProcess(PyObject *self, PyObject *args)
+#pragma warning(pop)
+
+/*[clinic input]
+_winapi.OpenProcess -> HANDLE
+
+ desired_access: DWORD
+ inherit_handle: BOOL
+ process_id: DWORD
+ /
+[clinic start generated code]*/
+
+static HANDLE
+_winapi_OpenProcess_impl(PyModuleDef *module, DWORD desired_access,
+ BOOL inherit_handle, DWORD process_id)
+/*[clinic end generated code: output=6bc52eda82a3d226 input=ec98c4cf4ea2ec36]*/
{
- DWORD dwDesiredAccess;
- BOOL bInheritHandle;
- DWORD dwProcessId;
HANDLE handle;
- if (!PyArg_ParseTuple(args, F_DWORD F_BOOL F_DWORD,
- &dwDesiredAccess, &bInheritHandle, &dwProcessId))
- return NULL;
-
- handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
- if (handle == NULL)
- return PyErr_SetFromWindowsErr(0);
+ handle = OpenProcess(desired_access, inherit_handle, process_id);
+ if (handle == NULL) {
+ PyErr_SetFromWindowsErr(0);
+ handle = INVALID_HANDLE_VALUE;
+ }
- return Py_BuildValue(F_HANDLE, handle);
+ return handle;
}
+/*[clinic input]
+_winapi.PeekNamedPipe
+
+ handle: HANDLE
+ size: int = 0
+ /
+[clinic start generated code]*/
+
static PyObject *
-winapi_PeekNamedPipe(PyObject *self, PyObject *args)
+_winapi_PeekNamedPipe_impl(PyModuleDef *module, HANDLE handle, int size)
+/*[clinic end generated code: output=e6c908e2fb63c798 input=c7aa53bfbce69d70]*/
{
- HANDLE handle;
- int size = 0;
PyObject *buf = NULL;
DWORD nread, navail, nleft;
BOOL ret;
- if (!PyArg_ParseTuple(args, F_HANDLE "|i:PeekNamedPipe" , &handle, &size))
- return NULL;
-
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative size");
return NULL;
@@ -938,23 +1158,24 @@ winapi_PeekNamedPipe(PyObject *self, PyObject *args)
}
}
+/*[clinic input]
+_winapi.ReadFile
+
+ handle: HANDLE
+ size: int
+ overlapped as use_overlapped: int(c_default='0') = False
+[clinic start generated code]*/
+
static PyObject *
-winapi_ReadFile(PyObject *self, PyObject *args, PyObject *kwds)
+_winapi_ReadFile_impl(PyModuleDef *module, HANDLE handle, int size,
+ int use_overlapped)
+/*[clinic end generated code: output=d7695db4db97b135 input=8dd810194e86ac7d]*/
{
- HANDLE handle;
- int size;
DWORD nread;
PyObject *buf;
BOOL ret;
- int use_overlapped = 0;
DWORD err;
OverlappedObject *overlapped = NULL;
- static char *kwlist[] = {"handle", "size", "overlapped", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds,
- F_HANDLE "i|i:ReadFile", kwlist,
- &handle, &size, &use_overlapped))
- return NULL;
buf = PyBytes_FromStringAndSize(NULL, size);
if (!buf)
@@ -997,18 +1218,27 @@ winapi_ReadFile(PyObject *self, PyObject *args, PyObject *kwds)
return Py_BuildValue("NI", buf, err);
}
+/*[clinic input]
+_winapi.SetNamedPipeHandleState
+
+ named_pipe: HANDLE
+ mode: object
+ max_collection_count: object
+ collect_data_timeout: object
+ /
+[clinic start generated code]*/
+
static PyObject *
-winapi_SetNamedPipeHandleState(PyObject *self, PyObject *args)
+_winapi_SetNamedPipeHandleState_impl(PyModuleDef *module, HANDLE named_pipe,
+ PyObject *mode,
+ PyObject *max_collection_count,
+ PyObject *collect_data_timeout)
+/*[clinic end generated code: output=25aa3c28dee223ce input=9142d72163d0faa6]*/
{
- HANDLE hNamedPipe;
- PyObject *oArgs[3];
+ PyObject *oArgs[3] = {mode, max_collection_count, collect_data_timeout};
DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL};
int i;
- if (!PyArg_ParseTuple(args, F_HANDLE "OOO",
- &hNamedPipe, &oArgs[0], &oArgs[1], &oArgs[2]))
- return NULL;
-
PyErr_Clear();
for (i = 0 ; i < 3 ; i++) {
@@ -1020,49 +1250,54 @@ winapi_SetNamedPipeHandleState(PyObject *self, PyObject *args)
}
}
- if (!SetNamedPipeHandleState(hNamedPipe, pArgs[0], pArgs[1], pArgs[2]))
+ if (!SetNamedPipeHandleState(named_pipe, pArgs[0], pArgs[1], pArgs[2]))
return PyErr_SetFromWindowsErr(0);
Py_RETURN_NONE;
}
-PyDoc_STRVAR(TerminateProcess_doc,
-"TerminateProcess(handle, exit_code) -> None\n\
-\n\
-Terminate the specified process and all of its threads.");
+
+/*[clinic input]
+_winapi.TerminateProcess
+
+ handle: HANDLE
+ exit_code: UINT
+ /
+
+Terminate the specified process and all of its threads.
+[clinic start generated code]*/
static PyObject *
-winapi_TerminateProcess(PyObject* self, PyObject* args)
+_winapi_TerminateProcess_impl(PyModuleDef *module, HANDLE handle,
+ UINT exit_code)
+/*[clinic end generated code: output=937c1bb6219aca8b input=d6bc0aa1ee3bb4df]*/
{
BOOL result;
- HANDLE process;
- UINT exit_code;
- if (! PyArg_ParseTuple(args, F_HANDLE F_UINT ":TerminateProcess",
- &process, &exit_code))
- return NULL;
-
- result = TerminateProcess(process, exit_code);
+ result = TerminateProcess(handle, exit_code);
if (! result)
return PyErr_SetFromWindowsErr(GetLastError());
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
+/*[clinic input]
+_winapi.WaitNamedPipe
+
+ name: LPCTSTR
+ timeout: DWORD
+ /
+[clinic start generated code]*/
+
static PyObject *
-winapi_WaitNamedPipe(PyObject *self, PyObject *args)
+_winapi_WaitNamedPipe_impl(PyModuleDef *module, LPCTSTR name, DWORD timeout)
+/*[clinic end generated code: output=5bca5e02f448c9d7 input=36fc781291b1862c]*/
{
- LPCTSTR lpNamedPipeName;
- DWORD nTimeOut;
BOOL success;
- if (!PyArg_ParseTuple(args, "s" F_DWORD, &lpNamedPipeName, &nTimeOut))
- return NULL;
-
Py_BEGIN_ALLOW_THREADS
- success = WaitNamedPipe(lpNamedPipeName, nTimeOut);
+ success = WaitNamedPipe(name, timeout);
Py_END_ALLOW_THREADS
if (!success)
@@ -1071,21 +1306,25 @@ winapi_WaitNamedPipe(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+/*[clinic input]
+_winapi.WaitForMultipleObjects
+
+ handle_seq: object
+ wait_flag: BOOL
+ milliseconds: DWORD(c_default='INFINITE') = _winapi.INFINITE
+ /
+[clinic start generated code]*/
+
static PyObject *
-winapi_WaitForMultipleObjects(PyObject* self, PyObject* args)
+_winapi_WaitForMultipleObjects_impl(PyModuleDef *module,
+ PyObject *handle_seq, BOOL wait_flag,
+ DWORD milliseconds)
+/*[clinic end generated code: output=acb440728d06d130 input=36f76ca057cd28a0]*/
{
DWORD result;
- PyObject *handle_seq;
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
HANDLE sigint_event = NULL;
Py_ssize_t nhandles, i;
- BOOL wait_flag;
- DWORD milliseconds = INFINITE;
-
- if (!PyArg_ParseTuple(args, "O" F_BOOL "|" F_DWORD
- ":WaitForMultipleObjects",
- &handle_seq, &wait_flag, &milliseconds))
- return NULL;
if (!PySequence_Check(handle_seq)) {
PyErr_Format(PyExc_TypeError,
@@ -1139,53 +1378,57 @@ winapi_WaitForMultipleObjects(PyObject* self, PyObject* args)
return PyLong_FromLong((int) result);
}
-PyDoc_STRVAR(WaitForSingleObject_doc,
-"WaitForSingleObject(handle, timeout) -> result\n\
-\n\
-Wait until the specified object is in the signaled state or\n\
-the time-out interval elapses. The timeout value is specified\n\
-in milliseconds.");
+/*[clinic input]
+_winapi.WaitForSingleObject -> long
-static PyObject *
-winapi_WaitForSingleObject(PyObject* self, PyObject* args)
+ handle: HANDLE
+ milliseconds: DWORD
+ /
+
+Wait for a single object.
+
+Wait until the specified object is in the signaled state or
+the time-out interval elapses. The timeout value is specified
+in milliseconds.
+[clinic start generated code]*/
+
+static long
+_winapi_WaitForSingleObject_impl(PyModuleDef *module, HANDLE handle,
+ DWORD milliseconds)
+/*[clinic end generated code: output=34ae40c269749c48 input=443d1ab076edc7b1]*/
{
DWORD result;
- HANDLE handle;
- DWORD milliseconds;
- if (! PyArg_ParseTuple(args, F_HANDLE F_DWORD ":WaitForSingleObject",
- &handle,
- &milliseconds))
- return NULL;
-
Py_BEGIN_ALLOW_THREADS
result = WaitForSingleObject(handle, milliseconds);
Py_END_ALLOW_THREADS
- if (result == WAIT_FAILED)
- return PyErr_SetFromWindowsErr(GetLastError());
+ if (result == WAIT_FAILED) {
+ PyErr_SetFromWindowsErr(GetLastError());
+ return -1;
+ }
- return PyLong_FromUnsignedLong(result);
+ return result;
}
+/*[clinic input]
+_winapi.WriteFile
+
+ handle: HANDLE
+ buffer: object
+ overlapped as use_overlapped: int(c_default='0') = False
+[clinic start generated code]*/
+
static PyObject *
-winapi_WriteFile(PyObject *self, PyObject *args, PyObject *kwds)
+_winapi_WriteFile_impl(PyModuleDef *module, HANDLE handle, PyObject *buffer,
+ int use_overlapped)
+/*[clinic end generated code: output=65e70ea41f4d2a1d input=51846a5af52053fd]*/
{
- HANDLE handle;
Py_buffer _buf, *buf;
- PyObject *bufobj;
DWORD len, written;
BOOL ret;
- int use_overlapped = 0;
DWORD err;
OverlappedObject *overlapped = NULL;
- static char *kwlist[] = {"handle", "buffer", "overlapped", NULL};
-
- /* First get handle and use_overlapped to know which Py_buffer to use */
- if (!PyArg_ParseTupleAndKeywords(args, kwds,
- F_HANDLE "O|i:WriteFile", kwlist,
- &handle, &bufobj, &use_overlapped))
- return NULL;
if (use_overlapped) {
overlapped = new_overlapped(handle);
@@ -1196,7 +1439,7 @@ winapi_WriteFile(PyObject *self, PyObject *args, PyObject *kwds)
else
buf = &_buf;
- if (!PyArg_Parse(bufobj, "y*", buf)) {
+ if (!PyArg_Parse(buffer, "y*", buf)) {
Py_XDECREF(overlapped);
return NULL;
}
@@ -1229,52 +1472,30 @@ winapi_WriteFile(PyObject *self, PyObject *args, PyObject *kwds)
static PyMethodDef winapi_functions[] = {
- {"CloseHandle", winapi_CloseHandle, METH_VARARGS,
- CloseHandle_doc},
- {"ConnectNamedPipe", (PyCFunction)winapi_ConnectNamedPipe,
- METH_VARARGS | METH_KEYWORDS, ""},
- {"CreateFile", winapi_CreateFile, METH_VARARGS,
- ""},
- {"CreateNamedPipe", winapi_CreateNamedPipe, METH_VARARGS,
- ""},
- {"CreatePipe", winapi_CreatePipe, METH_VARARGS,
- CreatePipe_doc},
- {"CreateProcess", winapi_CreateProcess, METH_VARARGS,
- CreateProcess_doc},
- {"DuplicateHandle", winapi_DuplicateHandle, METH_VARARGS,
- DuplicateHandle_doc},
- {"ExitProcess", winapi_ExitProcess, METH_VARARGS,
- ""},
- {"GetCurrentProcess", winapi_GetCurrentProcess, METH_VARARGS,
- GetCurrentProcess_doc},
- {"GetExitCodeProcess", winapi_GetExitCodeProcess, METH_VARARGS,
- GetExitCodeProcess_doc},
- {"GetLastError", winapi_GetLastError, METH_NOARGS,
- GetCurrentProcess_doc},
- {"GetModuleFileName", winapi_GetModuleFileName, METH_VARARGS,
- GetModuleFileName_doc},
- {"GetStdHandle", winapi_GetStdHandle, METH_VARARGS,
- GetStdHandle_doc},
- {"GetVersion", winapi_GetVersion, METH_VARARGS,
- GetVersion_doc},
- {"OpenProcess", winapi_OpenProcess, METH_VARARGS,
- ""},
- {"PeekNamedPipe", winapi_PeekNamedPipe, METH_VARARGS,
- ""},
- {"ReadFile", (PyCFunction)winapi_ReadFile, METH_VARARGS | METH_KEYWORDS,
- ""},
- {"SetNamedPipeHandleState", winapi_SetNamedPipeHandleState, METH_VARARGS,
- ""},
- {"TerminateProcess", winapi_TerminateProcess, METH_VARARGS,
- TerminateProcess_doc},
- {"WaitNamedPipe", winapi_WaitNamedPipe, METH_VARARGS,
- ""},
- {"WaitForMultipleObjects", winapi_WaitForMultipleObjects, METH_VARARGS,
- ""},
- {"WaitForSingleObject", winapi_WaitForSingleObject, METH_VARARGS,
- WaitForSingleObject_doc},
- {"WriteFile", (PyCFunction)winapi_WriteFile, METH_VARARGS | METH_KEYWORDS,
- ""},
+ _WINAPI_CLOSEHANDLE_METHODDEF
+ _WINAPI_CONNECTNAMEDPIPE_METHODDEF
+ _WINAPI_CREATEFILE_METHODDEF
+ _WINAPI_CREATENAMEDPIPE_METHODDEF
+ _WINAPI_CREATEPIPE_METHODDEF
+ _WINAPI_CREATEPROCESS_METHODDEF
+ _WINAPI_CREATEJUNCTION_METHODDEF
+ _WINAPI_DUPLICATEHANDLE_METHODDEF
+ _WINAPI_EXITPROCESS_METHODDEF
+ _WINAPI_GETCURRENTPROCESS_METHODDEF
+ _WINAPI_GETEXITCODEPROCESS_METHODDEF
+ _WINAPI_GETLASTERROR_METHODDEF
+ _WINAPI_GETMODULEFILENAME_METHODDEF
+ _WINAPI_GETSTDHANDLE_METHODDEF
+ _WINAPI_GETVERSION_METHODDEF
+ _WINAPI_OPENPROCESS_METHODDEF
+ _WINAPI_PEEKNAMEDPIPE_METHODDEF
+ _WINAPI_READFILE_METHODDEF
+ _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF
+ _WINAPI_TERMINATEPROCESS_METHODDEF
+ _WINAPI_WAITNAMEDPIPE_METHODDEF
+ _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF
+ _WINAPI_WAITFORSINGLEOBJECT_METHODDEF
+ _WINAPI_WRITEFILE_METHODDEF
{NULL, NULL}
};