3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/ioctrl.c
6 * PURPOSE: Device IO control
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 * Eric Kohl (ekohl@rz-online.de)
12 /* INCLUDES *****************************************************************/
16 #include <internal/debug.h>
18 /* FUNCTIONS *****************************************************************/
24 NtDeviceIoControlFile (IN HANDLE DeviceHandle
,
25 IN HANDLE Event OPTIONAL
,
26 IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL
,
27 IN PVOID UserApcContext OPTIONAL
,
28 OUT PIO_STATUS_BLOCK IoStatusBlock
,
29 IN ULONG IoControlCode
,
31 IN ULONG InputBufferLength OPTIONAL
,
32 OUT PVOID OutputBuffer
,
33 IN ULONG OutputBufferLength OPTIONAL
)
36 PFILE_OBJECT FileObject
;
37 PDEVICE_OBJECT DeviceObject
;
39 PIO_STACK_LOCATION StackPtr
;
41 KPROCESSOR_MODE PreviousMode
;
43 DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
44 "UserApcContext %x IoStatusBlock %x IoControlCode %x "
45 "InputBuffer %x InputBufferLength %x OutputBuffer %x "
46 "OutputBufferLength %x)\n",
47 DeviceHandle
,Event
,UserApcRoutine
,UserApcContext
,IoStatusBlock
,
48 IoControlCode
,InputBuffer
,InputBufferLength
,OutputBuffer
,
51 if (IoStatusBlock
== NULL
)
52 return STATUS_ACCESS_VIOLATION
;
54 PreviousMode
= ExGetPreviousMode();
56 /* Check granted access against the access rights from IoContolCode */
57 Status
= ObReferenceObjectByHandle (DeviceHandle
,
58 (IoControlCode
>> 14) & 0x3,
61 (PVOID
*) &FileObject
,
63 if (!NT_SUCCESS(Status
))
70 Status
= ObReferenceObjectByHandle (Event
,
76 if (!NT_SUCCESS(Status
))
78 ObDereferenceObject (FileObject
);
84 EventObject
= &FileObject
->Event
;
85 KeResetEvent (EventObject
);
88 DeviceObject
= FileObject
->DeviceObject
;
90 Irp
= IoBuildDeviceIoControlRequest (IoControlCode
,
100 /* Trigger FileObject/Event dereferencing */
101 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
103 Irp
->RequestorMode
= PreviousMode
;
104 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= UserApcRoutine
;
105 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= UserApcContext
;
107 StackPtr
= IoGetNextIrpStackLocation(Irp
);
108 StackPtr
->FileObject
= FileObject
;
109 StackPtr
->DeviceObject
= DeviceObject
;
110 StackPtr
->Parameters
.DeviceIoControl
.InputBufferLength
= InputBufferLength
;
111 StackPtr
->Parameters
.DeviceIoControl
.OutputBufferLength
= OutputBufferLength
;
113 Status
= IoCallDriver(DeviceObject
,Irp
);
114 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
116 Status
= KeWaitForSingleObject (EventObject
,
119 FileObject
->Flags
& FO_ALERTABLE_IO
,
121 if (Status
!= STATUS_WAIT_0
)
127 Status
= IoStatusBlock
->Status
;