📄 pnp.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 + -