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

📄 hardrela.cpp

📁 武安河书第一版(vxd)Windows 驱动例子
💻 CPP
字号:
#include "co_proc.h"
#include "Ioctl.h"
#include "AMCC5933.H"

NTSTATUS GetResources(IN PCO_PROC_DEVICE_EXTENSION dx,IN PCM_RESOURCE_LIST AllocatedResourcesTranslated);
BOOLEAN  Co_procInterruptHandler(IN PKINTERRUPT Interrupt,IN PCO_PROC_DEVICE_EXTENSION dx);
VOID Co_procDpcForIsr(IN PKDPC Dpc,IN PDEVICE_OBJECT fdo,IN PIRP Irp,IN PCO_PROC_DEVICE_EXTENSION dx);


NTSTATUS Co_procStartDevice(IN PCO_PROC_DEVICE_EXTENSION dx,IN PCM_RESOURCE_LIST AllocatedResourcesTranslated){
	if(dx->PnpState==Started){
		return STATUS_SUCCESS;
	}

	NTSTATUS status=GetResources(dx,AllocatedResourcesTranslated);
	if(!NT_SUCCESS(status)){
		return status;
	}
	return STATUS_SUCCESS;
}

NTSTATUS GetResources(IN PCO_PROC_DEVICE_EXTENSION dx,IN PCM_RESOURCE_LIST AllocatedResourcesTranslated){
	if(AllocatedResourcesTranslated==NULL||AllocatedResourcesTranslated->Count==0){
		return STATUS_UNSUCCESSFUL;
	}
	PCM_PARTIAL_RESOURCE_LIST list=&AllocatedResourcesTranslated->List[0].PartialResourceList;
	PCM_PARTIAL_RESOURCE_DESCRIPTOR pPRD=list->PartialDescriptors;
	ULONG NumResources=list->Count;
	for(ULONG i=0;i<NumResources;i++,pPRD++){
		switch(pPRD->Type){
		case CmResourceTypePort:
			dx->PortLength=pPRD->u.Port.Length;
			if(dx->PortLength==64){
					dx->BA0=(PUCHAR)pPRD->u.Port.Start.LowPart;
			}
			break;

		case CmResourceTypeInterrupt:
			dx->Irql=(KIRQL)pPRD->u.Interrupt.Level;
			dx->Vector=pPRD->u.Interrupt.Vector;
			dx->Affinity=pPRD->u.Interrupt.Affinity;
			dx->Mode=(pPRD->Flags==CM_RESOURCE_INTERRUPT_LATCHED)?Latched:LevelSensitive;
			break;
		}
	}
	return STATUS_SUCCESS;
}
	
VOID Co_procStartIo(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);

	KIRQL OldIrql;
	IoAcquireCancelSpinLock(&OldIrql);
	IoSetCancelRoutine(Irp,NULL);
	IoReleaseCancelSpinLock(OldIrql);
    typedef struct _BAR_DATA{
		ULONG length;
		ULONG  Offset;
		ULONG Data;
	}BAR_DATA,*PBAR_DATA;
	ULONG ReadData;
	PBAR_DATA Buffer=(PBAR_DATA)Irp->AssociatedIrp.SystemBuffer;

	NTSTATUS status=STATUS_SUCCESS;
	dx->DMAlength=Buffer->length;
//	if(Offset>dx->PortLength)
//	{
//		status=STATUS_UNSUCCESSFUL;
//		CompleteIrp(Irp,status,0);
//               IoStartNextPacket(fdo,FALSE);
//                IoReleaseRemoveLock(&dx->CountOfUse,NULL);
//                return;
//        }
	
	
	switch(IrpStack->Parameters.DeviceIoControl.IoControlCode)
	{
		case IOCTL_CO_PROC_WRITE:
			WRITE_PORT_ULONG((PULONG)(dx->BA0+Buffer->Offset),(long)Buffer->Data);
			break;
		case IOCTL_CO_PROC_READ:
	        ReadData=READ_PORT_ULONG((PULONG)(dx->BA0+Buffer->Offset));
		   	Buffer->Data=ReadData;
			RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,Buffer,sizeof(BAR_DATA));
			break;
		default:
		    status=STATUS_NOT_SUPPORTED;
		    break;
        }
}

VOID Co_procCancelIrp(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
	PCO_PROC_DEVICE_EXTENSION dx=(PCO_PROC_DEVICE_EXTENSION)fdo->DeviceExtension;
	if(Irp==fdo->CurrentIrp){
		IoReleaseCancelSpinLock(Irp->CancelIrql);
	}else{
		BOOLEAN dequeued=KeRemoveEntryDeviceQueue(&fdo->DeviceQueue,&Irp->Tail.Overlay.DeviceQueueEntry);
		IoReleaseCancelSpinLock(Irp->CancelIrql);
		if(dequeued){
			IoReleaseRemoveLock(&dx->CountOfUse,Irp);
			CompleteIrp(Irp,STATUS_CANCELLED,0);
		}
	}
}

BOOLEAN  Co_procInterruptHandler(IN PKINTERRUPT Interrupt,IN PCO_PROC_DEVICE_EXTENSION dx){
	PDEVICE_OBJECT fdo=dx->fdo;
	PIRP Irp=fdo->CurrentIrp;

	dx->sint=READ_PORT_ULONG((PULONG)(dx->BA0+INTCSR));
	if (!((dx->sint)&0x800000)) return FALSE;
	if ((dx->sint)&0x20000){
        WRITE_PORT_ULONG((PULONG)(dx->BA0+INTCSR),(dx->sint)&0xff02ffff);
		WRITE_PORT_ULONG((PULONG)(dx->BA0+MCSR),0x700);
	}
	else if ((dx->sint)&0x40000){
        WRITE_PORT_ULONG((PULONG)(dx->BA0+INTCSR),(dx->sint)&0xff04ffff);
		IoRequestDpc(fdo,Irp,dx);
	}
	else if (!((dx->sint)&0x300000)){
		WRITE_PORT_ULONG((PULONG)(dx->BA0+INTCSR),(dx->sint)&0xff03ffff);
	}
	return TRUE;
}

VOID Co_procDpcForIsr(IN PKDPC Dpc,IN PDEVICE_OBJECT fdo,IN PIRP Irp,IN PCO_PROC_DEVICE_EXTENSION dx)
{
    NTSTATUS status=Irp->Cancel?STATUS_CANCELLED:Irp->IoStatus.Status;
	KIRQL OldIrql;
	IoAcquireCancelSpinLock(&OldIrql);
	IoSetCancelRoutine(Irp,NULL);
	IoReleaseCancelSpinLock(OldIrql);
	IoReleaseRemoveLock(&dx->CountOfUse,Irp);
	if(dx->WantToStop){
		CompleteIrp(Irp,status,Irp->IoStatus.Information);
		return;
	}
	IoStartNextPacket(fdo,TRUE);
	CompleteIrp(Irp,status,Irp->IoStatus.Information);
	        IoReleaseRemoveLock(&dx->CountOfUse,NULL);
}

⌨️ 快捷键说明

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