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 *****************************************************************/
28 NTSTATUS STDCALL NtDeviceIoControlFile (IN HANDLE DeviceHandle,
30 IN PIO_APC_ROUTINE UserApcRoutine,
31 IN PVOID UserApcContext,
32 OUT PIO_STATUS_BLOCK IoStatusBlock,
33 IN ULONG IoControlCode,
35 IN ULONG InputBufferSize,
36 OUT PVOID OutputBuffer,
37 IN ULONG OutputBufferSize)
40 PFILE_OBJECT FileObject;
41 PDEVICE_OBJECT DeviceObject;
43 PIO_STACK_LOCATION StackPtr;
47 DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
48 "UserApcContext %x IoStatusBlock %x IoControlCode %x "
49 "InputBuffer %x InputBufferSize %x OutputBuffer %x "
50 "OutputBufferSize %x)\n",
51 DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock,
52 IoControlCode,InputBuffer,InputBufferSize,OutputBuffer,
55 Status = ObReferenceObjectByHandle(DeviceHandle,
56 FILE_READ_DATA | FILE_WRITE_DATA,
59 (PVOID *) &FileObject,
62 if (!NT_SUCCESS(Status))
68 Status = ObReferenceObjectByHandle (Event,
74 if (!NT_SUCCESS(Status))
76 ObDereferenceObject(FileObject);
82 KeResetEvent (&FileObject->Event);
83 ptrEvent = &FileObject->Event;
86 DeviceObject = FileObject->DeviceObject;
88 Irp = IoBuildDeviceIoControlRequest(IoControlCode,
96 Event ? IoStatusBlock : &IoSB);
98 //trigger FileObject/Event dereferencing
99 Irp->Tail.Overlay.OriginalFileObject = FileObject;
101 Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
102 Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
104 StackPtr = IoGetNextIrpStackLocation(Irp);
105 StackPtr->FileObject = FileObject;
106 StackPtr->DeviceObject = DeviceObject;
107 StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferSize;
108 StackPtr->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferSize;
110 Status = IoCallDriver(DeviceObject,Irp);
111 if (Event == NULL && Status == STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
113 KeWaitForSingleObject(ptrEvent,Executive,KernelMode,FALSE,NULL);
114 Status = IoSB.Status;
118 *IoStatusBlock = IoSB;