📄 pnp.cpp
字号:
#define INITGUID
#include "WdmUsb.h"
#pragma code_seg("PAGE")
//--------------------Defines----------------------------------------------------
NTSTATUS PnpStartDeviceHandler(IN PDEVICE_OBJECT fdo,PIRP Irp);
//NTSTATUS PnpQueryCapabilitiesHandler(IN PDEVICE_OBJECT fdo,PIRP Irp);
NTSTATUS PnpQueryRemoveHandler(IN PDEVICE_OBJECT fdo,PIRP Irp);
NTSTATUS PnpSurpriseRemovalHandler(IN PDEVICE_OBJECT fdo,PIRP Irp);
NTSTATUS PnpRemoveDeviceHandler(IN PDEVICE_OBJECT fdo,PIRP Irp);
NTSTATUS PnpStopDeviceHandler(IN PDEVICE_OBJECT fdo,PIRP Irp);
void PnpStopDevice(IN PWDMUSB_DEVICE_EXTENSION dx);
NTSTATUS PnpDefaultHandler(IN PDEVICE_OBJECT fdo,PIRP Irp);
NTSTATUS ForwardedIrpCompleteRoutine(IN PDEVICE_OBJECT fdo,PIRP Irp,IN PKEVENT ev);
//-----------------------Routines--------------------------------------------------
NTSTATUS WdmUsbAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT pdo)
{
KdPrint(("AddDevice"));
NTSTATUS status;
PDEVICE_OBJECT fdo;
status=IoCreateDevice(DriverObject,
sizeof(WDMUSB_DEVICE_EXTENSION),
NULL,
FILE_DEVICE_UNKNOWN,
FILE_AUTOGENERATED_DEVICE_NAME,
FALSE,
&fdo);
if(!NT_SUCCESS(status))
return status;
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
dx->fdo=fdo;
dx->pdo=pdo;
dx->UsageCount=1;
KeInitializeEvent(&dx->StoppingEvent,NotificationEvent,FALSE);
dx->OpenHandleCount=0;
dx->GotResources=false;
dx->Paused=false;
dx->IODisabled=true;
dx->Stopping=false;
dx->PowerState=PowerDeviceD3;
dx->PowerIdleCounter=NULL;
KdPrint(("FDO is %x",fdo));
POWER_STATE NewState;
NewState.DeviceState=dx->PowerState;
PoSetPowerState(fdo,DevicePowerState,NewState);
status=IoRegisterDeviceInterface(pdo,&WDMUSB_GUID,NULL,&dx->ifSymLinkName);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(fdo);
return status;
}
KdPrint(("Symbolic Link Name is %s",&dx->ifSymLinkName.Buffer));
dx->NextStackDevice=IoAttachDeviceToDeviceStack(fdo,pdo);
dx->Interface=NULL;
dx->Configurationhandle=NULL;
dx->DeviceDescriptor=NULL;
for(int i=0;i<WDMUSB_MAX_PIPES;i++)
dx->PipeList[i].PipeInfo=NULL;
fdo->Flags|=DO_DIRECT_IO|DO_POWER_PAGABLE;
fdo->Flags&=~DO_DEVICE_INITIALIZING;
// dx->PowerIdleCounter=PoRegisterDeviceForIdleDetection(pdo,30,60,PowerDeviceD3);
KdPrint(("no PoRegisterDeviceForIdleDetection"));
return STATUS_SUCCESS;
}
NTSTATUS WdmUsbPnp(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
KdPrint(("Pnp %x",Irp));
if(!LockDevice(dx))
return CompleteIrp(Irp,STATUS_DELETE_PENDING,0);
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
ULONG MinorFunction=IrpStack->MinorFunction;
NTSTATUS status=STATUS_SUCCESS;
switch(MinorFunction)
{
case IRP_MN_START_DEVICE:
status=PnpStartDeviceHandler(fdo,Irp);
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
status=PnpQueryRemoveHandler(fdo,Irp);
break;
case IRP_MN_SURPRISE_REMOVAL:
status=PnpSurpriseRemovalHandler(fdo,Irp);
break;
case IRP_MN_REMOVE_DEVICE:
status=PnpRemoveDeviceHandler(fdo,Irp);
break;
case IRP_MN_QUERY_STOP_DEVICE:
dx->Paused=true;
dx->IODisabled=true;
status=PnpDefaultHandler(fdo,Irp);
break;
case IRP_MN_STOP_DEVICE:
status=PnpStopDeviceHandler(fdo,Irp);
break;
// case IRP_MN_QUERY_CAPABILITIES:
// status=PnpQueryCapabilitiesHandler(fdo,Irp);
break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
case IRP_MN_CANCEL_STOP_DEVICE:
dx->Paused=false;
dx->IODisabled=false;
break;
default:
status=PnpDefaultHandler(fdo,Irp);
}
UnlockDevice(dx);
#if DBG
if(status!=STATUS_SUCCESS)
DbgPrint("Pnp completed %x",status);
#endif
return status;
}
//-----------------------------Define Routines-------------------------------------
NTSTATUS PnpStartDeviceHandler(IN PDEVICE_OBJECT fdo,PIRP Irp)
{
KdPrint(("PnpStartDeviceHandler"));
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status=ForwardIrpAndWait(fdo,Irp);
if(!NT_SUCCESS(status))
return CompleteIrp(Irp,status,Irp->IoStatus.Information);
KdPrint(("PnpStartDeviceHandler:post-processing"));
status=StartDevice(dx,
IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated);
if(NT_SUCCESS(status))
{
dx->Paused=false;
dx->IODisabled=false;
IoSetDeviceInterfaceState(&dx->ifSymLinkName,TRUE);
}
return CompleteIrp(Irp,status,0);
}
//NTSTATUS PnpQueryCapabilitiesHandler(IN PDEVICE_OBJECT fdo,PIRP Irp)
//{
//}
NTSTATUS PnpQueryRemoveHandler(IN PDEVICE_OBJECT fdo,PIRP Irp)
{
KdPrint(("PnpQueryRemoveHandler"));
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
if(dx->OpenHandleCount>0)
{
KdPrint(("PnpQueryRemoveHandler:%d handles still open",dx->OpenHandleCount));
return CompleteIrp(Irp,STATUS_UNSUCCESSFUL,0);
}
dx->Paused=true;
dx->IODisabled=true;
return PnpDefaultHandler(fdo,Irp);
}
NTSTATUS PnpSurpriseRemovalHandler(IN PDEVICE_OBJECT fdo,PIRP Irp)
{
KdPrint(("PnpSurpriseRemovalHandler"));
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
PnpStopDevice(dx);
return PnpDefaultHandler(fdo,Irp);
}
NTSTATUS PnpRemoveDeviceHandler(IN PDEVICE_OBJECT fdo,PIRP Irp)
{
KdPrint(("PnpRemoveDeviceHandler"));
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
PnpStopDevice(dx);
NTSTATUS status=PnpDefaultHandler(fdo,Irp);
IoSetDeviceInterfaceState(&dx->ifSymLinkName,FALSE);
RtlFreeUnicodeString(&dx->ifSymLinkName);
if(dx->DeviceDescriptor)
ExFreePool(dx->DeviceDescriptor);
if(dx->Interface)
ExFreePool(dx->Interface);
if(dx->NextStackDevice)
IoDetachDevice(dx->NextStackDevice);
IoDeleteDevice(fdo);
return status;
}
NTSTATUS PnpStopDeviceHandler(IN PDEVICE_OBJECT fdo,PIRP Irp)
{
KdPrint(("PnpStopDeviceHandler"));
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
PnpStopDevice(dx);
return PnpDefaultHandler(fdo,Irp);
}
void PnpStopDevice(IN PWDMUSB_DEVICE_EXTENSION dx)
{
dx->IODisabled=true;
if(!dx->GotResources)
return;
dx->Stopping=true;
KeResetEvent(&dx->StoppingEvent);
UnlockDevice(dx);
UnlockDevice(dx);
KeWaitForSingleObject(&dx->StoppingEvent,Executive,KernelMode,FALSE,NULL);
KdPrint(("PnpStopDevice:All pending I/O completed"));
dx->Stopping=false;
StopDevice(dx);
LockDevice(dx);
LockDevice(dx);
}
NTSTATUS PnpDefaultHandler(IN PDEVICE_OBJECT fdo,PIRP Irp)
{
KdPrint(("PnpDefaultHandler"));
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(dx->NextStackDevice,Irp);
}
//-------------------------Define Routines End-----------------------------------
NTSTATUS ForwardIrpAndWait(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
KdPrint(("ForwardIrpAndWait"));
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
KEVENT event;
KeInitializeEvent(&event,NotificationEvent,FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE)ForwardedIrpCompleteRoutine,
(PVOID)&event,
TRUE,
TRUE,
TRUE);
NTSTATUS status=IoCallDriver(dx->NextStackDevice,Irp);
if(status==STATUS_PENDING)
{
KdPrint(("ForwardedIrpAndWait:waiting for completion"));
KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL);
status=Irp->IoStatus.Status;
}
#if DBG
if(status!=STATUS_SUCCESS)
DbgPrint("ForwardIrpAndWait: completed %x",status);
#endif
return status;
}
bool LockDevice(IN PWDMUSB_DEVICE_EXTENSION dx)
{
InterlockedIncrement(&dx->UsageCount);
if(dx->Stopping)
{
if(InterlockedDecrement(&dx->UsageCount)==0)
KeSetEvent(&dx->StoppingEvent,0,FALSE);
return false;
}
return true;
}
void UnlockDevice(IN PWDMUSB_DEVICE_EXTENSION dx)
{
LONG UsageCount=InterlockedDecrement(&dx->UsageCount);
if(UsageCount==0)
{
KdPrint(("UnlockDevice:setting StoppingEvent flag"));
KeSetEvent(&dx->StoppingEvent,0,FALSE);
}
}
#pragma code_seg()
//----------------------------CompleteRoutine------------------------------------------
NTSTATUS ForwardedIrpCompleteRoutine(IN PDEVICE_OBJECT fdo,PIRP Irp,IN PKEVENT ev)
{
KeSetEvent(ev,0,FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -