3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/ioctrl.c
6 * PURPOSE: Device IO control
7 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * Eric Kohl (ekohl@abo.rhein-zeitung.de)
11 * Filled in ZwDeviceIoControlFile 22/02/99
12 * Fixed IO method handling 08/03/99
13 * Added APC support 05/11/99
16 /* INCLUDES *****************************************************************/
18 #include <ddk/ntddk.h>
19 #include <internal/io.h>
21 #include <internal/debug.h>
23 /* FUNCTIONS *****************************************************************/
25 NTSTATUS STDCALL NtDeviceIoControlFile (IN HANDLE DeviceHandle,
27 IN PIO_APC_ROUTINE UserApcRoutine,
28 IN PVOID UserApcContext,
29 OUT PIO_STATUS_BLOCK IoStatusBlock,
30 IN ULONG IoControlCode,
32 IN ULONG InputBufferSize,
33 OUT PVOID OutputBuffer,
34 IN ULONG OutputBufferSize)
37 PFILE_OBJECT FileObject;
38 PDEVICE_OBJECT DeviceObject;
40 PIO_STACK_LOCATION StackPtr;
44 DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
45 "UserApcContext %x IoStatusBlock %x IoControlCode %x "
46 "InputBuffer %x InputBufferSize %x OutputBuffer %x "
47 "OutputBufferSize %x)\n",
48 DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock,
49 IoControlCode,InputBuffer,InputBufferSize,OutputBuffer,
52 Status = ObReferenceObjectByHandle(DeviceHandle,
53 FILE_READ_DATA | FILE_WRITE_DATA,
56 (PVOID *) &FileObject,
59 if (!NT_SUCCESS(Status))
65 Status = ObReferenceObjectByHandle (Event,
71 if (!NT_SUCCESS(Status))
73 ObDereferenceObject(FileObject);
79 KeResetEvent (&FileObject->Event);
80 ptrEvent = &FileObject->Event;
83 DeviceObject = FileObject->DeviceObject;
85 Irp = IoBuildDeviceIoControlRequest(IoControlCode,
93 Event ? IoStatusBlock : &IoSB);
95 Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
96 Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
98 StackPtr = IoGetNextIrpStackLocation(Irp);
99 StackPtr->FileObject = FileObject;
100 StackPtr->DeviceObject = DeviceObject;
101 StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferSize;
102 StackPtr->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferSize;
104 Status = IoCallDriver(DeviceObject,Irp);
105 if (Event == NULL && Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
107 KeWaitForSingleObject(ptrEvent,Executive,KernelMode,FALSE,NULL);
108 Status = IoSB.Status;
112 *IoStatusBlock = IoSB;