ntdll: Cleaned up the ioctl functions.

Renamed function parameters to something usable.
Fixed potential event leaks.
This commit is contained in:
Alexandre Julliard 2006-01-18 17:18:22 +01:00
parent 002e143981
commit 4202824e9e
1 changed files with 126 additions and 117 deletions

View File

@ -847,58 +847,54 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
* Perform an I/O control operation on an open file handle. * Perform an I/O control operation on an open file handle.
* *
* PARAMS * PARAMS
* DeviceHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile() * handle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
* Event [I] Event to signal upon completion (or NULL) * event [I] Event to signal upon completion (or NULL)
* ApcRoutine [I] Callback to call upon completion (or NULL) * apc [I] Callback to call upon completion (or NULL)
* ApcContext [I] Context for ApcRoutine (or NULL) * apc_context [I] Context for ApcRoutine (or NULL)
* IoStatusBlock [O] Receives information about the operation on return * io [O] Receives information about the operation on return
* IoControlCode [I] Control code for the operation to perform * code [I] Control code for the operation to perform
* InputBuffer [I] Source for any input data required (or NULL) * in_buffer [I] Source for any input data required (or NULL)
* InputBufferSize [I] Size of InputBuffer * in_size [I] Size of InputBuffer
* OutputBuffer [O] Source for any output data returned (or NULL) * out_buffer [O] Source for any output data returned (or NULL)
* OutputBufferSize [I] Size of OutputBuffer * out_size [I] Size of OutputBuffer
* *
* RETURNS * RETURNS
* Success: 0. IoStatusBlock is updated. * Success: 0. IoStatusBlock is updated.
* Failure: An NTSTATUS error code describing the error. * Failure: An NTSTATUS error code describing the error.
*/ */
NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE DeviceHandle, HANDLE hEvent, NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE handle, HANDLE event,
PIO_APC_ROUTINE UserApcRoutine, PIO_APC_ROUTINE apc, PVOID apc_context,
PVOID UserApcContext, PIO_STATUS_BLOCK io, ULONG code,
PIO_STATUS_BLOCK IoStatusBlock, PVOID in_buffer, ULONG in_size,
ULONG IoControlCode, PVOID out_buffer, ULONG out_size)
PVOID InputBuffer,
ULONG InputBufferSize,
PVOID OutputBuffer,
ULONG OutputBufferSize)
{ {
NTSTATUS ret; ULONG device = (code >> 16);
TRACE("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx)\n", TRACE("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx)\n",
DeviceHandle, hEvent, UserApcRoutine, UserApcContext, handle, event, apc, apc_context, io, code,
IoStatusBlock, IoControlCode, in_buffer, in_size, out_buffer, out_size);
InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize);
if ((IoControlCode >> 16) == FILE_DEVICE_SERIAL_PORT) switch(device)
ret = COMM_DeviceIoControl(DeviceHandle, hEvent,
UserApcRoutine, UserApcContext,
IoStatusBlock, IoControlCode,
InputBuffer, InputBufferSize,
OutputBuffer, OutputBufferSize);
else ret = CDROM_DeviceIoControl(DeviceHandle, hEvent,
UserApcRoutine, UserApcContext,
IoStatusBlock, IoControlCode,
InputBuffer, InputBufferSize,
OutputBuffer, OutputBufferSize);
if (ret == STATUS_NO_SUCH_DEVICE)
{ {
/* it wasn't a supported device (CDROM, COMM) */ case FILE_DEVICE_DISK:
FIXME("Unimplemented dwIoControlCode=%08lx\n", IoControlCode); case FILE_DEVICE_CD_ROM:
IoStatusBlock->u.Status = STATUS_NOT_IMPLEMENTED; case FILE_DEVICE_DVD:
IoStatusBlock->Information = 0; case FILE_DEVICE_CONTROLLER:
if (hEvent) NtSetEvent(hEvent, NULL); case FILE_DEVICE_MASS_STORAGE:
io->u.Status = CDROM_DeviceIoControl(handle, event, apc, apc_context, io, code,
in_buffer, in_size, out_buffer, out_size);
break;
case FILE_DEVICE_SERIAL_PORT:
io->u.Status = COMM_DeviceIoControl(handle, event, apc, apc_context, io, code,
in_buffer, in_size, out_buffer, out_size);
break;
default:
FIXME("Unsupported ioctl %lx (device=%lx access=%lx func=%lx method=%lx)\n",
code, device, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3);
io->u.Status = STATUS_NOT_SUPPORTED;
break;
} }
return IoStatusBlock->u.Status; return io->u.Status;
} }
/*********************************************************************** /***********************************************************************
@ -921,110 +917,123 @@ static void CALLBACK pipe_completion_wait(HANDLE event, PIO_STATUS_BLOCK iosb, U
* Perform a file system control operation on an open file handle. * Perform a file system control operation on an open file handle.
* *
* PARAMS * PARAMS
* DeviceHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile() * handle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
* Event [I] Event to signal upon completion (or NULL) * event [I] Event to signal upon completion (or NULL)
* ApcRoutine [I] Callback to call upon completion (or NULL) * apc [I] Callback to call upon completion (or NULL)
* ApcContext [I] Context for ApcRoutine (or NULL) * apc_context [I] Context for ApcRoutine (or NULL)
* IoStatusBlock [O] Receives information about the operation on return * io [O] Receives information about the operation on return
* FsControlCode [I] Control code for the operation to perform * code [I] Control code for the operation to perform
* InputBuffer [I] Source for any input data required (or NULL) * in_buffer [I] Source for any input data required (or NULL)
* InputBufferSize [I] Size of InputBuffer * in_size [I] Size of InputBuffer
* OutputBuffer [O] Source for any output data returned (or NULL) * out_buffer [O] Source for any output data returned (or NULL)
* OutputBufferSize [I] Size of OutputBuffer * out_size [I] Size of OutputBuffer
* *
* RETURNS * RETURNS
* Success: 0. IoStatusBlock is updated. * Success: 0. IoStatusBlock is updated.
* Failure: An NTSTATUS error code describing the error. * Failure: An NTSTATUS error code describing the error.
*/ */
NTSTATUS WINAPI NtFsControlFile(HANDLE DeviceHandle, HANDLE Event OPTIONAL, PIO_APC_ROUTINE ApcRoutine, NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc,
PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG FsControlCode, PVOID apc_context, PIO_STATUS_BLOCK io, ULONG code,
PVOID InputBuffer, ULONG InputBufferSize, PVOID OutputBuffer, ULONG OutputBufferSize) PVOID in_buffer, ULONG in_size, PVOID out_buffer, ULONG out_size)
{ {
NTSTATUS ret = STATUS_NOT_SUPPORTED;
HANDLE internal_event;
TRACE("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx)\n", TRACE("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx)\n",
DeviceHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,FsControlCode, handle, event, apc, apc_context, io, code,
InputBuffer,InputBufferSize,OutputBuffer,OutputBufferSize); in_buffer, in_size, out_buffer, out_size);
if(!IoStatusBlock) return STATUS_INVALID_PARAMETER; if (!io) return STATUS_INVALID_PARAMETER;
switch(FsControlCode) switch(code)
{ {
case FSCTL_DISMOUNT_VOLUME: case FSCTL_DISMOUNT_VOLUME:
ret = DIR_unmount_device( DeviceHandle ); io->u.Status = DIR_unmount_device( handle );
break; break;
case FSCTL_PIPE_LISTEN : case FSCTL_PIPE_LISTEN:
case FSCTL_PIPE_WAIT :
{ {
OBJECT_ATTRIBUTES obj; HANDLE internal_event = 0;
if(!Event) if(!event)
{ {
InitializeObjectAttributes(&obj, NULL, 0, 0, NULL); io->u.Status = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE);
ret = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, &obj, FALSE, FALSE); if (io->u.Status != STATUS_SUCCESS) return io->u.Status;
if(ret != STATUS_SUCCESS) return ret;
} }
switch(FsControlCode) SERVER_START_REQ(connect_named_pipe)
{ {
case FSCTL_PIPE_LISTEN : req->handle = handle;
SERVER_START_REQ(connect_named_pipe) req->event = event ? event : internal_event;
{ req->func = pipe_completion_wait;
req->handle = DeviceHandle; io->u.Status = wine_server_call(req);
req->event = Event ? Event : internal_event; }
req->func = pipe_completion_wait; SERVER_END_REQ;
ret = wine_server_call(req);
}
SERVER_END_REQ;
break;
case FSCTL_PIPE_WAIT :
{
FILE_PIPE_WAIT_FOR_BUFFER *buff = InputBuffer;
SERVER_START_REQ(wait_named_pipe) if(io->u.Status == STATUS_SUCCESS)
{
req->handle = DeviceHandle;
req->timeout = buff->TimeoutSpecified ? buff->Timeout.QuadPart / -10000L
: NMPWAIT_USE_DEFAULT_WAIT;
req->event = Event ? Event : internal_event;
req->func = pipe_completion_wait;
wine_server_add_data( req, buff->Name, buff->NameLength );
ret = wine_server_call( req );
}
SERVER_END_REQ;
break;
}
}
if(ret == STATUS_SUCCESS)
{ {
if(Event) if(event) io->u.Status = STATUS_PENDING;
ret = STATUS_PENDING;
else else
{ {
do do
ret = NtWaitForSingleObject(internal_event, TRUE, NULL); io->u.Status = NtWaitForSingleObject(internal_event, TRUE, NULL);
while(ret == STATUS_USER_APC); while(io->u.Status == STATUS_USER_APC);
NtClose(internal_event);
} }
} }
break; if (internal_event) NtClose(internal_event);
} }
case FSCTL_PIPE_DISCONNECT : break;
SERVER_START_REQ(disconnect_named_pipe)
case FSCTL_PIPE_WAIT:
{
HANDLE internal_event = 0;
FILE_PIPE_WAIT_FOR_BUFFER *buff = in_buffer;
if(!event)
{ {
req->handle = DeviceHandle; io->u.Status = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE);
ret = wine_server_call(req); if (io->u.Status != STATUS_SUCCESS) return io->u.Status;
if (!ret && reply->fd != -1) close(reply->fd); }
SERVER_START_REQ(wait_named_pipe)
{
req->handle = handle;
req->timeout = buff->TimeoutSpecified ? buff->Timeout.QuadPart / -10000L
: NMPWAIT_USE_DEFAULT_WAIT;
req->event = event ? event : internal_event;
req->func = pipe_completion_wait;
wine_server_add_data( req, buff->Name, buff->NameLength );
io->u.Status = wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
break;
default : if(io->u.Status == STATUS_SUCCESS)
FIXME("Unsupported FsControlCode %lx\n", FsControlCode); {
break; if(event)
io->u.Status = STATUS_PENDING;
else
{
do
io->u.Status = NtWaitForSingleObject(internal_event, TRUE, NULL);
while(io->u.Status == STATUS_USER_APC);
}
}
if (internal_event) NtClose(internal_event);
}
break;
case FSCTL_PIPE_DISCONNECT:
SERVER_START_REQ(disconnect_named_pipe)
{
req->handle = handle;
io->u.Status = wine_server_call(req);
if (!io->u.Status && reply->fd != -1) close(reply->fd);
}
SERVER_END_REQ;
break;
default:
FIXME("Unsupported fsctl %lx (device=%lx access=%lx func=%lx method=%lx)\n",
code, code >> 16, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3);
io->u.Status = STATUS_NOT_SUPPORTED;
break;
} }
IoStatusBlock->u.Status = ret; return io->u.Status;
return ret;
} }
/****************************************************************************** /******************************************************************************