ntdll: Implement BindIoCompletionCallback.
This commit is contained in:
parent
26bc15a811
commit
343f2c1b30
@ -1912,8 +1912,13 @@ BOOL WINAPI PostQueuedCompletionStatus( HANDLE CompletionPort, DWORD dwNumberOfB
|
|||||||
*/
|
*/
|
||||||
BOOL WINAPI BindIoCompletionCallback( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags)
|
BOOL WINAPI BindIoCompletionCallback( HANDLE FileHandle, LPOVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags)
|
||||||
{
|
{
|
||||||
FIXME("%p, %p, %d, stub!\n", FileHandle, Function, Flags);
|
NTSTATUS status;
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
||||||
|
TRACE("(%p, %p, %d)\n", FileHandle, Function, Flags);
|
||||||
|
|
||||||
|
status = RtlSetIoCompletionCallback( FileHandle, (PRTL_OVERLAPPED_COMPLETION_ROUTINE)Function, Flags );
|
||||||
|
if (status == STATUS_SUCCESS) return TRUE;
|
||||||
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,10 +326,6 @@ static void test_iocp_callback(void)
|
|||||||
|
|
||||||
retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
|
retb = p_BindIoCompletionCallback(hFile, iocp_callback, 0);
|
||||||
ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
|
ok(retb == FALSE, "BindIoCompletionCallback succeeded on a file that wasn't created with FILE_FLAG_OVERLAPPED\n");
|
||||||
if(retb == FALSE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
|
|
||||||
todo_wine ok (0, "BindIoCompletionCallback returned ERROR_CALL_NOT_IMPLEMENTED\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
|
ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error is %d\n", GetLastError());
|
||||||
|
|
||||||
ret = CloseHandle(hFile);
|
ret = CloseHandle(hFile);
|
||||||
|
@ -822,7 +822,7 @@
|
|||||||
@ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long)
|
@ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long)
|
||||||
# @ stub RtlSetHeapInformation
|
# @ stub RtlSetHeapInformation
|
||||||
@ stub RtlSetInformationAcl
|
@ stub RtlSetInformationAcl
|
||||||
# @ stub RtlSetIoCompletionCallback
|
@ stdcall RtlSetIoCompletionCallback(long ptr long)
|
||||||
@ stdcall RtlSetLastWin32Error(long)
|
@ stdcall RtlSetLastWin32Error(long)
|
||||||
@ stdcall RtlSetLastWin32ErrorAndNtStatusFromNtStatus(long)
|
@ stdcall RtlSetLastWin32ErrorAndNtStatusFromNtStatus(long)
|
||||||
# @ stub RtlSetMemoryStreamSize
|
# @ stub RtlSetMemoryStreamSize
|
||||||
|
@ -54,6 +54,16 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
|||||||
};
|
};
|
||||||
static RTL_CRITICAL_SECTION threadpool_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
|
static RTL_CRITICAL_SECTION threadpool_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
static HANDLE compl_port = NULL;
|
||||||
|
static RTL_CRITICAL_SECTION threadpool_compl_cs;
|
||||||
|
static RTL_CRITICAL_SECTION_DEBUG critsect_compl_debug =
|
||||||
|
{
|
||||||
|
0, 0, &threadpool_compl_cs,
|
||||||
|
{ &critsect_compl_debug.ProcessLocksList, &critsect_compl_debug.ProcessLocksList },
|
||||||
|
0, 0, { (DWORD_PTR)(__FILE__ ": threadpool_compl_cs") }
|
||||||
|
};
|
||||||
|
static RTL_CRITICAL_SECTION threadpool_compl_cs = { &critsect_compl_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
struct work_item
|
struct work_item
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
@ -218,3 +228,86 @@ NTSTATUS WINAPI RtlQueueWorkItem(PRTL_WORK_ITEM_ROUTINE Function, PVOID Context,
|
|||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* iocp_poller - get completion events and run callbacks
|
||||||
|
*/
|
||||||
|
static DWORD CALLBACK iocp_poller(LPVOID Arg)
|
||||||
|
{
|
||||||
|
while( TRUE )
|
||||||
|
{
|
||||||
|
PRTL_OVERLAPPED_COMPLETION_ROUTINE callback;
|
||||||
|
LPVOID overlapped;
|
||||||
|
IO_STATUS_BLOCK iosb;
|
||||||
|
NTSTATUS res = NtRemoveIoCompletion( compl_port, (PULONG_PTR)&callback, (PULONG_PTR)&overlapped, &iosb, NULL );
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
ERR("NtRemoveIoCompletion failed: 0x%x\n", res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DWORD transferred = 0;
|
||||||
|
DWORD err = 0;
|
||||||
|
|
||||||
|
if (iosb.u.Status == STATUS_SUCCESS)
|
||||||
|
transferred = iosb.Information;
|
||||||
|
else
|
||||||
|
err = RtlNtStatusToDosError(iosb.u.Status);
|
||||||
|
|
||||||
|
callback( err, transferred, overlapped );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RtlSetIoCompletionCallback (NTDLL.@)
|
||||||
|
*
|
||||||
|
* Binds a handle to a thread pool's completion port, and possibly
|
||||||
|
* starts a non-I/O thread to monitor this port and call functions back.
|
||||||
|
*
|
||||||
|
* PARAMS
|
||||||
|
* FileHandle [I] Handle to bind to a completion port.
|
||||||
|
* Function [I] Callback function to call on I/O completions.
|
||||||
|
* Flags [I] Not used.
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* Success: STATUS_SUCCESS.
|
||||||
|
* Failure: Any NTSTATUS code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
NTSTATUS WINAPI RtlSetIoCompletionCallback(HANDLE FileHandle, PRTL_OVERLAPPED_COMPLETION_ROUTINE Function, ULONG Flags)
|
||||||
|
{
|
||||||
|
IO_STATUS_BLOCK iosb;
|
||||||
|
FILE_COMPLETION_INFORMATION info;
|
||||||
|
|
||||||
|
if (Flags) FIXME("Unknown value Flags=0x%x\n", Flags);
|
||||||
|
|
||||||
|
if (!compl_port)
|
||||||
|
{
|
||||||
|
NTSTATUS res = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
RtlEnterCriticalSection(&threadpool_compl_cs);
|
||||||
|
if (!compl_port)
|
||||||
|
{
|
||||||
|
HANDLE cport;
|
||||||
|
|
||||||
|
res = NtCreateIoCompletion( &cport, IO_COMPLETION_ALL_ACCESS, NULL, 0 );
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
/* FIXME native can start additional threads in case of e.g. hung callback function. */
|
||||||
|
res = RtlQueueWorkItem( iocp_poller, NULL, WT_EXECUTEDEFAULT );
|
||||||
|
if (!res)
|
||||||
|
compl_port = cport;
|
||||||
|
else
|
||||||
|
NtClose( cport );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RtlLeaveCriticalSection(&threadpool_compl_cs);
|
||||||
|
if (res) return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.CompletionPort = compl_port;
|
||||||
|
info.CompletionKey = (ULONG_PTR)Function;
|
||||||
|
|
||||||
|
return NtSetInformationFile( FileHandle, &iosb, &info, sizeof(info), FileCompletionInformation );
|
||||||
|
}
|
||||||
|
@ -1568,6 +1568,8 @@ typedef struct _KEY_MULTIPLE_VALUE_INFORMATION
|
|||||||
ULONG Type;
|
ULONG Type;
|
||||||
} KEY_MULTIPLE_VALUE_INFORMATION, *PKEY_MULTIPLE_VALUE_INFORMATION;
|
} KEY_MULTIPLE_VALUE_INFORMATION, *PKEY_MULTIPLE_VALUE_INFORMATION;
|
||||||
|
|
||||||
|
typedef VOID (CALLBACK *PRTL_OVERLAPPED_COMPLETION_ROUTINE)(DWORD,DWORD,LPVOID);
|
||||||
|
|
||||||
typedef VOID (*PTIMER_APC_ROUTINE) ( PVOID, ULONG, LONG );
|
typedef VOID (*PTIMER_APC_ROUTINE) ( PVOID, ULONG, LONG );
|
||||||
|
|
||||||
typedef enum _EVENT_TYPE {
|
typedef enum _EVENT_TYPE {
|
||||||
@ -2273,6 +2275,7 @@ NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOL
|
|||||||
NTSYSAPI NTSTATUS WINAPI RtlSetEnvironmentVariable(PWSTR*,PUNICODE_STRING,PUNICODE_STRING);
|
NTSYSAPI NTSTATUS WINAPI RtlSetEnvironmentVariable(PWSTR*,PUNICODE_STRING,PUNICODE_STRING);
|
||||||
NTSYSAPI NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID,BOOLEAN);
|
NTSYSAPI NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID,BOOLEAN);
|
||||||
NTSYSAPI NTSTATUS WINAPI RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID,BOOLEAN);
|
NTSYSAPI NTSTATUS WINAPI RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID,BOOLEAN);
|
||||||
|
NTSYSAPI NTSTATUS WINAPI RtlSetIoCompletionCallback(HANDLE,PRTL_OVERLAPPED_COMPLETION_ROUTINE,ULONG);
|
||||||
NTSYSAPI void WINAPI RtlSetLastWin32Error(DWORD);
|
NTSYSAPI void WINAPI RtlSetLastWin32Error(DWORD);
|
||||||
NTSYSAPI void WINAPI RtlSetLastWin32ErrorAndNtStatusFromNtStatus(NTSTATUS);
|
NTSYSAPI void WINAPI RtlSetLastWin32ErrorAndNtStatusFromNtStatus(NTSTATUS);
|
||||||
NTSYSAPI NTSTATUS WINAPI RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL,BOOLEAN);
|
NTSYSAPI NTSTATUS WINAPI RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL,BOOLEAN);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user