NTSTATUS
MakeDeviceControl(PDEVICE_OBJECT DeviceObject,
ULONG IoctlCode,
PVOID InputBuffer,
ULONG InputBufferSize,
PVOID OutputBuffer,
ULONG OutputBufferSize)
{
PIRP Irp;
NTSTATUS Status;
KEVENT Event;
IO_STATUS_BLOCK Iosb;
//
// First, start by initializing the event
//
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
//
// Build the request, using the I/O Manager routine...
//
Irp = IoBuildDeviceIoControlRequest(IoctlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
OutputBuffer,
OutputBufferSize,
FALSE,
&Event,
&Iosb);
//
// Send the request to the lower layer driver.
//
KdPrint(("current irql: %d\n", KeGetCurrentIrql()));
Status = IoCallDriver(DeviceObject, Irp);
//
// Wait, if necessary
//
if (Status == STATUS_PENDING) {
//
// We must wait here in non-interruptable mode. Why? Because our
// event is on the stack. If we were to return out of here (because
// of an APC, for example) we might return from this function BEFORE
// the event is set. When the event is set later, at a minimum we'll
// trash the stack. Worse yet, the stack might be paged out and the
// system will die.
//
(void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
/*
if (KeGetCurrentIrql() < DISPATCH_LEVEL)
{
(void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
}
else
{
LARGE_INTEGER dueTime;
dueTime.QuadPart = 0;
(void) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, &dueTime);
}*/
}
return (Status);
}
转载于:https://blog.51cto.com/co63oc/971614