📄 main.c
字号:
--*/
{ // RequestCreate
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
DbgPrint("Entering IRP_MJ_CREAT\n");
status = STATUS_SUCCESS;
deviceExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension;
// 每一个设备同一时间只允许一个应用打开
if( deviceExtension->bIsOpen ){
status = STATUS_ACCESS_DENIED;
}else{
deviceExtension->bIsOpen = TRUE;
}
return CompleteRequest(Irp, status, 0);
}
NTSTATUS RequestClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
/*++
Routine Description:
Close the device
Arguments:
DeviceObject - Pointer to deviceobject
Irp - Pointer to an IRP_MJ_CREATE
Return Value:
NT Status is returned;
--*/
{ // RequestClose
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
DbgPrint("Entering IRP_MJ_CLOSE\n");
status = STATUS_SUCCESS;
deviceExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension;
if( deviceExtension->bIsOpen ){
deviceExtension->bIsOpen = FALSE;
}else{
status = STATUS_ACCESS_DENIED;
}
return CompleteRequest(Irp, status, 0);
}
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG info)
/*++
Routine Description:
Routine to complete the requests
Arguments:
Irp - Pointer to an IRP_MJ_CREATE
status - NT status
info - Irp->IoStatus.Information
Return Value:
NT Status is returned;
--*/
{ // CompleteRequest
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} // CompleteRequest
/*++
Routine Description:
The default dispatch routine. If this driver does not recognize the
IRP, then it should send it down, unmodified.
If the device holds iris, this IRP must be queued in the device extension
No completion routine is required.
For demonstrative purposes only, we will pass all the (non-PnP) Irps down
on the stack (as we are a filter driver). A real driver might choose to
service some of these Irps.
As we have NO idea which function we are happily passing on, we can make
NO assumptions about whether or not it will be called at raised IRQL.
For this reason, this function must be in put into non-paged pool
(aka the default location).
Arguments:
DeviceObject - pointer to a device object.
Irp - pointer to an I/O Request Packet.
Return Value:
NT status code
--*/
/*
Note:
Because we call IoSkipCurrentIrpStackLocation rather than IoCopyCurrentIrpStackLocation, we need NOT
set Irp->IoStatus.Status and NOT call IoCompleteRequest. The only work is to call IoCallDriver.
*/
NTSTATUS DefaultPnpHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PDEVICE_EXTENSION deviceExtension;
IoSkipCurrentIrpStackLocation( Irp );
deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
return IoCallDriver( deviceExtension->NextLowerDriver, Irp);
}
NTSTATUS ForwardAndWait(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
/*++
Routine Description:
The routine forwards the IRP to the underlying driver and waits for the lower layer to complete the IRP
Arguments:
DeviceObject - Pointer to deviceobject
Irp - Pointer to a PnP Irp.
Return Value:
NT Status is returned.
--*/
{
KEVENT event;
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
deviceExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
OnRequestComplete, (PVOID) &event, TRUE, TRUE, TRUE);
status = IoCallDriver( deviceExtension->NextLowerDriver, Irp);
if (status == STATUS_PENDING)
{ // wait for completion
KeWaitForSingleObject(
&event,
Executive, // Waiting for reasion of a driver
KernelMode, // Waiting in kernel mode
FALSE, // No alert
NULL); // No timeout
status = Irp->IoStatus.Status;
} // wait for completion
return status;
} // ForwardAndWait
NTSTATUS OnRequestComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PKEVENT event)
/*++
Routine Description:
A completion routine for use when calling the lower device objects to
which ourdeviceobject is attached.
Arguments:
DeviceObject - Pointer to deviceobject
Irp - Pointer to a PnP Irp.
event - Pointer to event
Return Value:
NT Status is returned.
--*/
{
KeSetEvent( event, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
#if DBG
PCHAR
PnPMinorFunctionString (
UCHAR MinorFunction
)
{
switch (MinorFunction)
{
case IRP_MN_START_DEVICE:
return "IRP_MN_START_DEVICE";
case IRP_MN_QUERY_REMOVE_DEVICE:
return "IRP_MN_QUERY_REMOVE_DEVICE";
case IRP_MN_REMOVE_DEVICE:
return "IRP_MN_REMOVE_DEVICE";
case IRP_MN_CANCEL_REMOVE_DEVICE:
return "IRP_MN_CANCEL_REMOVE_DEVICE";
case IRP_MN_STOP_DEVICE:
return "IRP_MN_STOP_DEVICE";
case IRP_MN_QUERY_STOP_DEVICE:
return "IRP_MN_QUERY_STOP_DEVICE";
case IRP_MN_CANCEL_STOP_DEVICE:
return "IRP_MN_CANCEL_STOP_DEVICE";
case IRP_MN_QUERY_DEVICE_RELATIONS:
return "IRP_MN_QUERY_DEVICE_RELATIONS";
case IRP_MN_QUERY_INTERFACE:
return "IRP_MN_QUERY_INTERFACE";
case IRP_MN_QUERY_CAPABILITIES:
return "IRP_MN_QUERY_CAPABILITIES";
case IRP_MN_QUERY_RESOURCES:
return "IRP_MN_QUERY_RESOURCES";
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
case IRP_MN_QUERY_DEVICE_TEXT:
return "IRP_MN_QUERY_DEVICE_TEXT";
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
case IRP_MN_READ_CONFIG:
return "IRP_MN_READ_CONFIG";
case IRP_MN_WRITE_CONFIG:
return "IRP_MN_WRITE_CONFIG";
case IRP_MN_EJECT:
return "IRP_MN_EJECT";
case IRP_MN_SET_LOCK:
return "IRP_MN_SET_LOCK";
case IRP_MN_QUERY_ID:
return "IRP_MN_QUERY_ID";
case IRP_MN_QUERY_PNP_DEVICE_STATE:
return "IRP_MN_QUERY_PNP_DEVICE_STATE";
case IRP_MN_QUERY_BUS_INFORMATION:
return "IRP_MN_QUERY_BUS_INFORMATION";
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
return "IRP_MN_DEVICE_USAGE_NOTIFICATION";
case IRP_MN_SURPRISE_REMOVAL:
return "IRP_MN_SURPRISE_REMOVAL";
default:
return "IRP_MN_?????";
}
}
#endif
NTSTATUS RequestCleanup(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
The routine handles the IRP_MJ_CLEANUP which is sent beforce the IRP_MJ_CLOSE.
Arguments:
DeviceObject - Pointer to deviceobject
Irp - Pointer to a PnP Irp.
Return Value:
NT Status is returned.
--*/
{
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
PLIST_ENTRY link;
PIRP pendingIrp;
DbgPrint("Entering IRP_MJ_Cleanup\n");
deviceExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension;
status = STATUS_SUCCESS;
DebugPrint(("to cleanup pending WaitOnMask IRP\n"));
if( deviceExtension->bIsWaitOnMask ){
CompleteRequest( deviceExtension->WaitOnMaskIrp, STATUS_CANCELLED, 0 );
deviceExtension->WaitOnMaskIrp = NULL;
deviceExtension->bIsWaitOnMask = FALSE;
}
DebugPrint(("to cleanup pending Read IRP\n"));
RequestPurgeIrpQueue( DeviceObject, &deviceExtension->ReadIrpQueue );
DebugPrint(("to cleanup pending Write IRP\n"));
RequestPurgeIrpQueue( DeviceObject, &deviceExtension->WriteIrpQueue );
return CompleteRequest( Irp, status, 0 );
}
#if 0
VOID
OnTimer(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context
)
{
PDEVICE_EXTENSION deviceExtension;
PLIST_ENTRY link;
PIRP IrpToComplete;
deviceExtension = ( PDEVICE_EXTENSION )Context;
if( deviceExtension->timer > 0 ){
deviceExtension->timer--;
}else{
link = NULL;
link = ExInterlockedRemoveHeadList( &deviceExtension->ReadIrpQueue, &deviceExtension->CancelSpinLock );
while( link != NULL ){
IrpToComplete = CONTAINING_RECORD( link, IRP, Tail.Overlay.ListEntry );
ASSERT( IrpToComplete );
DebugPrint(("Fing out pending ReadIrp (0x%x )\n", IrpToComplete ));
CompleteReadIrpOnTimer(deviceExtension, IrpToComplete );
link = ExInterlockedRemoveHeadList( &deviceExtension->ReadIrpQueue, &deviceExtension->CancelSpinLock );
}
deviceExtension->timer = 3;
}
}
VOID
CompleteReadIrpOnTimer(
IN PDEVICE_EXTENSION deviceExtension,
IN PIRP Irp
)
{
PIO_STACK_LOCATION IrpStack;
ULONG ControlCode;
ULONG InputLength,OutputLength;
PUCHAR pOutBuf;
ULONG info;
ULONG i;
CHAR buf[ 256 ];
LARGE_INTEGER time;
DebugPrint(("Enter ReadIrpOnTimer routine ( 0x%x )\n", Irp));
IrpStack = IoGetCurrentIrpStackLocation(Irp);
DebugPrint(("GetCurrentIrpStackLocation OK\n"));
ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
OutputLength= IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
DbgPrint("InputBufferLength: %d OutputBufferLength: %d\n", InputLength, OutputLength );
pOutBuf = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
KeQuerySystemTime(&time);
sprintf( buf, "CurrentTime: %10u-%10u\r\n", time.HighPart, time.LowPart );
memcpy(pOutBuf, buf, ( (strlen( buf ) > OutputLength ) ? OutputLength : strlen( buf ) ) );
info = (strlen( buf ) > OutputLength ) ? OutputLength : strlen( buf ) ;
CompleteRequest( Irp, STATUS_SUCCESS, info );
DebugPrint(("Exit ReadIrpOnTimer routine\n"));
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -