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

📄 pnp.cpp

📁 武安河书第一版(vxd)Windows 驱动例子
💻 CPP
字号:
#define INITGUID
#define FILE_DEVICE_CO_PROC 0xEA65
#include "co_proc.h"
#include "AMCC5933.H"
#include "c:\ntddk\inc\ddk\ntddk.h"

NTSTATUS PnpStartDeviceHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS PnpQueryRemoveDeviceHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS PnpSurpriseRemovalHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS PnpRemoveDeviceHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS PnpStopDeviceHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS PnpCancelRemoveDeviceHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS PnpDefaultHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS ForwardIrpAndWait(IN PDEVICE_OBJECT fdo,IN PIRP Irp);
NTSTATUS ForwardedIrpCompletionRoutine(IN PDEVICE_OBJECT fdo,IN PIRP Irp,IN PKEVENT ev);
VOID     PnpCancelIrpQueue(IN PDEVICE_OBJECT fdo);
VOID	 Co_procReset(IN PDEVICE_OBJECT fdo);

NTSTATUS Co_procAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT pdo){
	NTSTATUS status;
	PDEVICE_OBJECT fdo;
	status=IoCreateDevice(DriverObject,sizeof(CO_PROC_DEVICE_EXTENSION),NULL,FILE_DEVICE_CO_PROC,0,FALSE,&fdo);
	if(!NT_SUCCESS(status)){
		return status;
	}
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	dx->fdo=fdo;
	dx->pdo=pdo;
	dx->OpenHandle=0;
	dx->PnpState=Removed;
	dx->PrePnpState=Removed;
	dx->ConnectedToInterrupt=false;
	KeInitializeEvent(&dx->NowCanStop,NotificationEvent,FALSE);
	IoInitializeRemoveLock(&dx->CountOfUse,0,0,512);
	IoInitializeDpcRequest(fdo,Co_procDpcForIsr);
	status=IoRegisterDeviceInterface(pdo,&CO_PROC,NULL,&dx->ifSymLinkName);
	if(!NT_SUCCESS(status)){
		IoDeleteDevice(fdo);
		return status;
	}
	dx->NextStackDevice=IoAttachDeviceToDeviceStack(fdo,pdo);
	fdo->Flags|=DO_BUFFERED_IO;
	fdo->Flags&=~DO_DEVICE_INITIALIZING;
	return STATUS_SUCCESS;
}

NTSTATUS Co_procPnp(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	NTSTATUS status=IoAcquireRemoveLock(&dx->CountOfUse,Irp);
	if(!NT_SUCCESS(status)) return CompleteIrp(Irp,status,0);
	PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
	ULONG MinorFunction=IrpStack->MinorFunction;
	switch(MinorFunction){
		case IRP_MN_START_DEVICE:
		     status=PnpStartDeviceHandler(fdo,Irp);
		     break;
		case IRP_MN_QUERY_REMOVE_DEVICE:
		     status=PnpQueryRemoveDeviceHandler(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->PnpState=StopPending;
		     status=PnpDefaultHandler(fdo,Irp);
		     break;
		case IRP_MN_STOP_DEVICE:
		     status=PnpStopDeviceHandler(fdo,Irp);
		     break;
		case IRP_MN_CANCEL_REMOVE_DEVICE:
		     status=PnpCancelRemoveDeviceHandler(fdo,Irp);
		     break;
		case IRP_MN_CANCEL_STOP_DEVICE:
		     dx->PnpState=Started;
        default:
		     status=PnpDefaultHandler(fdo,Irp);
	}
	if(MinorFunction!=IRP_MN_REMOVE_DEVICE) IoReleaseRemoveLock(&dx->CountOfUse,Irp);
	return status;
}

NTSTATUS PnpStartDeviceHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
	
	Irp->IoStatus.Status=STATUS_SUCCESS;
	
	NTSTATUS status=ForwardIrpAndWait(fdo,Irp);
	if(!NT_SUCCESS(status))	return CompleteIrp(Irp,status,Irp->IoStatus.Information);
	status=Co_procStartDevice(dx,IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated);
	if(NT_SUCCESS(status)){
		IoSetDeviceInterfaceState(&dx->ifSymLinkName,TRUE);
	        dx->PrePnpState=Started;	
	        dx->PnpState=Started;
	        status=IoConnectInterrupt(&dx->InterruptObject,(PKSERVICE_ROUTINE)Co_procInterruptHandler,(PVOID)dx,NULL,dx->Vector,dx->Irql,dx->Irql,dx->Mode,TRUE,dx->Affinity,FALSE);
	        if(!NT_SUCCESS(status)){
	        	dx->ConnectedToInterrupt=false;
			return status;
		}
	}
	Co_procReset(fdo);
	IoCompleteRequest(Irp,IO_NO_INCREMENT);
	return status;
}

NTSTATUS PnpQueryRemoveDeviceHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	if(dx->OpenHandle>0){
		return CompleteIrp(Irp,STATUS_UNSUCCESSFUL,0);
	}
	dx->PnpState=RemovePending;
	return PnpDefaultHandler(fdo,Irp);
}

NTSTATUS PnpSurpriseRemovalHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	PnpCancelIrpQueue(fdo);
   	dx->PnpState=SurpriseRemoved;
	return PnpDefaultHandler(fdo,Irp);
}

NTSTATUS PnpRemoveDeviceHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	IoReleaseRemoveLockAndWait(&dx->CountOfUse,Irp);
	if(dx->ConnectedToInterrupt){
		IoDisconnectInterrupt(dx->InterruptObject);
		dx->ConnectedToInterrupt=false;
	}
	NTSTATUS status=PnpDefaultHandler(fdo,Irp);
	(*dx->AdapterObject->DmaOperations->FreeCommonBuffer)(
			dx->AdapterObject,
			128,
			dx->pa,
			dx->va,
			false);
	IoSetDeviceInterfaceState(&dx->ifSymLinkName,FALSE);
	RtlFreeUnicodeString(&dx->ifSymLinkName);
	if(dx->NextStackDevice)	IoDetachDevice(dx->NextStackDevice);
	IoDeleteDevice(fdo);
	return status;
}

NTSTATUS PnpCancelRemoveDeviceHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	dx->PnpState=dx->PrePnpState;
	return STATUS_SUCCESS;
}

NTSTATUS PnpStopDeviceHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;

	if(dx->PnpState==Stopped) return STATUS_SUCCESS;

	dx->WantToStop=true;
	KeWaitForSingleObject(&dx->NowCanStop,Executive,KernelMode,FALSE,NULL);
	if(dx->ConnectedToInterrupt){
		IoDisconnectInterrupt(dx->InterruptObject);
		dx->ConnectedToInterrupt=false;
	}
	dx->PnpState=Stopped;
	dx->PrePnpState=Stopped;

	return PnpDefaultHandler(fdo,Irp);
}

NTSTATUS PnpDefaultHandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(dx->NextStackDevice,Irp);
}


NTSTATUS ForwardIrpAndWait(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	KEVENT event;
	KeInitializeEvent(&event,NotificationEvent,FALSE);
	IoCopyCurrentIrpStackLocationToNext(Irp);
	IoSetCompletionRoutine(Irp,(PIO_COMPLETION_ROUTINE)ForwardedIrpCompletionRoutine,(PVOID)&event,TRUE,TRUE,TRUE);
	NTSTATUS status=IoCallDriver(dx->NextStackDevice,Irp);
	if(status==STATUS_PENDING){
		KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL);
	}
	return Irp->IoStatus.Status;
}




NTSTATUS ForwardedIrpCompletionRoutine(IN PDEVICE_OBJECT fdo,IN PIRP Irp,IN PKEVENT ev){
	KeSetEvent(ev,0,FALSE);
	return STATUS_MORE_PROCESSING_REQUIRED;
}

VOID PnpCancelIrpQueue(IN PDEVICE_OBJECT fdo){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
    KIRQL OldIrql;
	IoAcquireCancelSpinLock(&OldIrql);
	PKDEVICE_QUEUE_ENTRY QueueEntry;
	while((QueueEntry=KeRemoveDeviceQueue(&fdo->DeviceQueue))!=NULL){
		PIRP CancelIrp=CONTAINING_RECORD(QueueEntry,IRP,Tail.Overlay.DeviceQueueEntry);
		CancelIrp->Cancel=TRUE;
		CancelIrp->CancelIrql=OldIrql;
		CancelIrp->CancelRoutine=NULL;
		IoReleaseCancelSpinLock(OldIrql);
		IoReleaseRemoveLock(&dx->CountOfUse,CancelIrp);
		CompleteIrp(CancelIrp,STATUS_CANCELLED,0);
		IoAcquireCancelSpinLock(&OldIrql);
	}
	IoReleaseCancelSpinLock(OldIrql);
    return;
}

NTSTATUS Co_procDispatchCleanup(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
	IoAcquireRemoveLock(&dx->CountOfUse,Irp);
	PFILE_OBJECT fo=IrpStack->FileObject;
	LIST_ENTRY WantToCancelList;
	InitializeListHead(&WantToCancelList);
	KIRQL OldIrql;
	IoAcquireCancelSpinLock(&OldIrql);
	KeAcquireSpinLockAtDpcLevel(&fdo->DeviceQueue.Lock);
	PLIST_ENTRY First=&fdo->DeviceQueue.DeviceListHead;
	PLIST_ENTRY Next;
	for(Next=First->Flink;Next!=First;){
		PIRP QueuedIrp=CONTAINING_RECORD(Next,IRP,Tail.Overlay.ListEntry);
		PIO_STACK_LOCATION QueuedIrpStack=IoGetCurrentIrpStackLocation(QueuedIrp);
		PLIST_ENTRY Current=Next;
		Next=Next->Flink;
		if(QueuedIrpStack->FileObject!=fo) continue;
		IoSetCancelRoutine(QueuedIrp,NULL);
		RemoveEntryList(Current);
		InsertTailList(&WantToCancelList,Current);
	}
	KeReleaseSpinLockFromDpcLevel(&fdo->DeviceQueue.Lock);
	IoReleaseCancelSpinLock(OldIrql);
	while(!IsListEmpty(&WantToCancelList)){
		Next=RemoveHeadList(&WantToCancelList);
		PIRP CancelingIrp=CONTAINING_RECORD(Next,IRP,Tail.Overlay.ListEntry);
		IoReleaseRemoveLock(&dx->CountOfUse,CancelingIrp);
		CompleteIrp(CancelingIrp,STATUS_CANCELLED,0);
	}
	IoReleaseRemoveLock(&dx->CountOfUse,Irp);
	return CompleteIrp(Irp,STATUS_SUCCESS,0);
}

VOID Co_procReset(IN PDEVICE_OBJECT fdo){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	WRITE_PORT_ULONG((PULONG)(dx->BA0+INTCSR),0x003f0000);

	INTERFACE_TYPE BusType;
	ULONG ulBusTypeLen;

	IoGetDeviceProperty(dx->pdo,DevicePropertyLegacyBusType,sizeof(BusType),&BusType,&ulBusTypeLen);

	DEVICE_DESCRIPTION DeviceDescription;
	RtlZeroMemory(&DeviceDescription,sizeof(DeviceDescription));
	DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
	DeviceDescription.Master = true;
	DeviceDescription.InterfaceType = BusType;
	DeviceDescription.MaximumLength = 128;
	DeviceDescription.Dma32BitAddresses = true;

	dx->AdapterObject = IoGetDmaAdapter(dx->pdo,&DeviceDescription,&dx->NMapRegister);
	
	dx->va=(*dx->AdapterObject->DmaOperations->AllocateCommonBuffer)(dx->AdapterObject,128,&dx->pa,false);

	WRITE_PORT_ULONG((PULONG)(dx->BA0+MWAR),(ULONG)(dx->pa.LowPart));
	WRITE_PORT_ULONG((PULONG)(dx->BA0+MWTC),128);
	WRITE_PORT_ULONG((PULONG)(dx->BA0+MCSR),0x0c000000);
	WRITE_PORT_ULONG((PULONG)(dx->BA0+INTCSR),0x20005000);
}

NTSTATUS Co_procPower(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	if(dx->PnpState<Started) return CompleteIrp(Irp,STATUS_DEVICE_NOT_CONNECTED,0);
	NTSTATUS status=IoAcquireRemoveLock(&dx->CountOfUse,Irp);
	if(!NT_SUCCESS(status)) return CompleteIrp(Irp,STATUS_DELETE_PENDING,0);
	status=STATUS_SUCCESS;
	PoStartNextPowerIrp(Irp);
	IoSkipCurrentIrpStackLocation(Irp);
	status=PoCallDriver(dx->NextStackDevice,Irp);
	IoReleaseRemoveLock(&dx->CountOfUse,Irp);
	return status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -