03958d6b18d8dcd74bfb87dd3ba32f70e3b4e0ac
[reactos.git] / reactos / ntoskrnl / io / ioctrl.c
1 /* $Id: ioctrl.c,v 1.12 2001/03/21 23:27:18 chorns Exp $
2 *
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)
9 * UPDATE HISTORY:
10 * Created 22/05/98
11 * Filled in ZwDeviceIoControlFile 22/02/99
12 * Fixed IO method handling 08/03/99
13 * Added APC support 05/11/99
14 */
15
16 /* INCLUDES *****************************************************************/
17
18 #include <ddk/ntddk.h>
19 #include <internal/io.h>
20 #define NDEBUG
21 #include <internal/debug.h>
22
23 /* FUNCTIONS *****************************************************************/
24
25 NTSTATUS STDCALL NtDeviceIoControlFile (IN HANDLE DeviceHandle,
26 IN HANDLE Event,
27 IN PIO_APC_ROUTINE UserApcRoutine,
28 IN PVOID UserApcContext,
29 OUT PIO_STATUS_BLOCK IoStatusBlock,
30 IN ULONG IoControlCode,
31 IN PVOID InputBuffer,
32 IN ULONG InputBufferSize,
33 OUT PVOID OutputBuffer,
34 IN ULONG OutputBufferSize)
35 {
36 NTSTATUS Status;
37 PFILE_OBJECT FileObject;
38 PDEVICE_OBJECT DeviceObject;
39 PIRP Irp;
40 PIO_STACK_LOCATION StackPtr;
41 KEVENT KEvent;
42
43 DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
44 "UserApcContext %x IoStatusBlock %x IoControlCode %x "
45 "InputBuffer %x InputBufferSize %x OutputBuffer %x "
46 "OutputBufferSize %x)\n",
47 DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock,
48 IoControlCode,InputBuffer,InputBufferSize,OutputBuffer,
49 OutputBufferSize);
50
51 Status = ObReferenceObjectByHandle(DeviceHandle,
52 FILE_READ_DATA | FILE_WRITE_DATA,
53 IoFileObjectType,
54 KernelMode,
55 (PVOID *) &FileObject,
56 NULL);
57
58 if (!NT_SUCCESS(Status))
59 {
60 return(Status);
61 }
62
63 DeviceObject = FileObject->DeviceObject;
64
65 KeInitializeEvent(&KEvent,NotificationEvent,TRUE);
66
67 Irp = IoBuildDeviceIoControlRequest(IoControlCode,
68 DeviceObject,
69 InputBuffer,
70 InputBufferSize,
71 OutputBuffer,
72 OutputBufferSize,
73 FALSE,
74 &KEvent,
75 IoStatusBlock);
76
77 Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
78 Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
79
80 StackPtr = IoGetNextIrpStackLocation(Irp);
81 StackPtr->FileObject = FileObject;
82 StackPtr->DeviceObject = DeviceObject;
83 StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferSize;
84 StackPtr->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferSize;
85
86 Status = IoCallDriver(DeviceObject,Irp);
87 if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
88 {
89 KeWaitForSingleObject(&KEvent,Executive,KernelMode,FALSE,NULL);
90 return(IoStatusBlock->Status);
91 }
92 return(Status);
93 }
94
95 /* EOF */