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

📄 pci2040.cpp

📁 pci2040VxD驱动非常详细的源程序
💻 CPP
字号:
// PCI2040.cpp - main module for VxD PCI2040

#define DEVICE_MAIN
#include "pci2040.h"
Declare_Virtual_Device(PCI2040)
#undef DEVICE_MAIN

WORD ioport;
DWORD membase[2];///0 hpi csr base, 1 control space
BOOL  bVirIrq;
MyHwInt* pMyIRQ;
PVOID	    	CallBackApc = 0;
THREADHANDLE 	TheThread = 0;	
long int x;

#define PAGENUM(p)  (((ULONG)(p))>>12)//除以4k得多少页
#define PAGEOFF(p)  (((ULONG)(p))&0xFFF)//偏移地址为低4k位
#define PAGEBASE(p)	 (((ULONG)(p))&~0xFFF)//基址为高位
#define _NPAGES_(p,k)  ((PAGENUM((char*)p+(k-1))-PAGENUM(p))+1)

///三个全局函数地址映射用
PVOID MapDevice(PVOID PhysAddress, DWORD SizeInBytes)
{
#ifdef USE_MAP_PHYS_TO_LINEAR
	return MapPhysToLinear(PhysAddress, SizeInBytes, 0);
#else
	PVOID Linear;
	ULONG nPages = _NPAGES_(PhysAddress, SizeInBytes);
	Linear = PageReserve(
		PR_SYSTEM,
		nPages,
		PR_FIXED
		);
	PageCommitPhys(
		PAGENUM(Linear),
		nPages,
		PAGENUM(PhysAddress),
		PC_INCR | PC_WRITEABLE | PC_USER
		);		
	LinPageLock(PAGENUM(Linear), nPages, 0);
	return (PVOID) ((ULONG)Linear+PAGEOFF(PhysAddress));
#endif
}

VOID UnmapDevice(PVOID LinearAddress, DWORD SizeInBytes)
{
#ifdef USE_MAP_PHYS_TO_LINEAR
	// cannot unmap
#else
	LinPageUnLock(
		PAGENUM(LinearAddress),
		_NPAGES_(LinearAddress, SizeInBytes),
		0
		);
	PageDecommit(
		PAGENUM(LinearAddress),
		_NPAGES_(LinearAddress, SizeInBytes),
		0
		);
	PageFree((MEMHANDLE)LinearAddress,0);
#endif
}

CONFIGRET OnConfigure(
	CONFIGFUNC cf, 		// function id
	SUBCONFIGFUNC scf,	// subfunction id
	DEVNODE devnode, 	// device node being configured
	DWORD refdata, 		// context information (function specific)
	ULONG flags			// function specific flags
)
{
	CMCONFIG config;
	LOG_CONF logconf;
	RES_DES hres;
	switch (cf)					// branch on function code
	{		
	case CONFIG_START:
		CONFIGMG_Get_Alloc_Log_Conf(&config, devnode, CM_GET_ALLOC_LOG_CONF_ALLOC);
		irq=config.bIRQRegisters[0];
//		irq=12;
		membase[0]=config.dMemBase[0];
		membase[1]=config.dMemBase[1];
		ioport=config.wIOPortBase[0];
		
		return CR_SUCCESS;

	case CONFIG_REMOVE /* 4 */:

	case CONFIG_STOP   /* 2 */:
		irq = 0xff;
		return CR_SUCCESS;

	default:
		return CR_DEFAULT;
	}			  
}				  

BOOL Pci2040Device::OnSysDynamicDeviceInit()
{

	return TRUE;
}

BOOL Pci2040Device::OnSysDynamicDeviceExit()
{
	return TRUE;
}

CONFIGRET Pci2040Device::OnPnpNewDevnode(DEVNODE devNode, DWORD loadType)
{
	switch(loadType)
	{
	case DLVXD_LOAD_DEVLOADER:
		return CONFIGMG_Register_Device_Driver(devNode,OnConfigure,
		0,CM_REGISTER_DEVICE_DRIVER_DISABLEABLE | CM_REGISTER_DEVICE_DRIVER_REMOVABLE);
	default:
		return CR_DEFAULT;
	}
	return CR_DEFAULT;
}

DWORD Pci2040Device::OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams)
{
	PMAPDEVREQUEST pReq;
	switch (pDIOCParams->dioc_IOCtlCode)
	{
	case DIOC_OPEN:
		dout<<"open"<<endl;
		x=0;
		if(irq!=0xff)
		{
			pMyIRQ=new MyHwInt();
			if(!pMyIRQ||!pMyIRQ->hook())
				bVirIrq=FALSE;
			else
			{
				bVirIrq=TRUE;
				pMyIRQ->physicalUnmask();
			}
		}
		break;

	case DIOC_CLOSEHANDLE:
		dout<<"close"<<endl;
		pMyIRQ->physicalMask();
		if(bVirIrq) delete pMyIRQ;
		break;

	case MDR_SERVICE_UNMAP:
		dout<<"unmap"<<endl;
		pReq = *(PMAPDEVREQUEST*)pDIOCParams->dioc_InBuf;	
		UnmapDevice(
			pReq->mdr_LinearAddress,
			pReq->mdr_SizeInBytes
			);
		pReq->mdr_Status = MDR_STATUS_SUCCESS;
		break;	
		
	case MDR_SERVICE_MAP:
		dout<<"map"<<endl;
		pReq = *(PMAPDEVREQUEST*)pDIOCParams->dioc_InBuf;	
		pReq->mdr_LinearAddress = MapDevice(
			pReq->mdr_PhysicalAddress,		
			pReq->mdr_SizeInBytes				
			);									
		if	(pReq->mdr_LinearAddress == NULL) 
			pReq->mdr_Status=MDR_STATUS_ERROR;
		else
			pReq->mdr_Status=MDR_STATUS_SUCCESS;
		break;

	case GETMEMBASE0:
		dout<<"getmembase0"<<endl;
		*(DWORD*)pDIOCParams->dioc_OutBuf=membase[0];
		break;

	case GETMEMBASE1:
		dout<<"getmembase1"<<endl;
		*(DWORD*)pDIOCParams->dioc_OutBuf=membase[1];
		break;

	case GETIOBASE:
		dout<<"GETIOBASE"<<endl;
		*(DWORD*)pDIOCParams->dioc_OutBuf=ioport;
		break;

	case GETIRQ:
		dout<<"GETIRQ"<<endl;
		*(int*)pDIOCParams->dioc_OutBuf=irq;
		break;

	case ADDRPASS:
		dout<<"addrpass"<<endl;
		CallBackApc = pDIOCParams->dioc_InBuf;
		TheThread = Get_Cur_Thread_Handle();
		break;
	default:
		return -1;
	}
	return 0;
}

BOOL MyHwInt::OnSharedHardwareInt(VMHANDLE)
{
	pMyIRQ->physicalMask();
	x++;
	if(x>70&&x<75)
	{
		VWIN32_QueueUserApc(CallBackApc, (DWORD)&x, TheThread);
	}
	for(int temp=0;temp<10000;temp++);
	sendPhysicalEOI();
	pMyIRQ->physicalUnmask();
	if(x>200)
	{
		pMyIRQ->physicalMask();
	}
	return FALSE;

}

⌨️ 快捷键说明

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