⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pnp.cpp

📁 一个通用的usb驱动程序列程
💻 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 + -