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

📄 wahpnp.cpp

📁 武安河书第一版(vxd)Windows 驱动例子
💻 CPP
字号:
// WAHPNP.cpp - main module for VxD WAHPNP

#define DEVICE_MAIN
#include "WAHPNP.h"
Declare_Virtual_Device(WAHPNP)
#undef DEVICE_MAIN
#include <vsd.h>

WORD ioport,io;
#define MCSR	0x3c;
#define INTCSR	0x38;
#define OMB1	0;
#define IMB1	0x10;
#define MBEF	0x34;
#define MWAR	0x24;
#define MWTC	0x28;

MyHwInt* pMyIRQ;
PVOID	    	CallBackApc = 0;
THREADHANDLE 	TheThread = 0;	
DWORD abox;
BeepTimeOut* pBeeper;

PVOID ClientBuffer;				// address of client buffer to receive data
DWORD nBytes;					// number of bytes to read
DWORD nPages;					// number of pages spanned by buffer
ULONG PhysAddr;					// physical address to send to DMA controller
PVOID DMABufferLinear;			// linear address of the DMA buffer
BOOL  bUsingInt = FALSE;		// TRUE if int avalible
BOOL  bUsingBuffer = FALSE;		// TRUE if using buffer provided by VDMAD
MEMHANDLE hMem;
VOID Bufalloc();
VOID Buffree();

BOOL MyHwInt::OnSharedHardwareInt(VMHANDLE hVM)
{
	DWORD sint,sbox;
	io=ioport+INTCSR;
	sint=_inpd(io);
	if ((sint&0x800000)!=0x800000) return FALSE;
	if ((sint&0x20000)==0x20000) {
		io=ioport+INTCSR;
        _outpd(io,sint&0xff02ffff);
		io=ioport+MBEF;
		sbox=_inpd(io);
		if ((sbox&0x10000)==0x10000) {
			io=ioport+IMB1;
			abox=_inpd(io);
			if (abox&0xaa==0xaa) {
				#ifdef DEBUG
				dout << "DMA: Start!" << endl;
				#endif
				io=ioport+MCSR;
				_outpd(io,0x700);
			}
		}
	}
	else if ((sint&0x40000)==0x40000) {
		io=ioport+INTCSR;
        _outpd(io,sint&0xff04ffff);
		VWIN32_QueueUserApc(CallBackApc, (DWORD)DMABufferLinear, TheThread);
	}
	else if ((sint&0x300000)!=0) {
		io=ioport+INTCSR;
		_outpd(io,sint&0xff03ffff);
		#ifdef DEBUG
			dout << "DMA: Abort!" << endl;
		#endif
	}
	sendPhysicalEOI();
	return TRUE;	
}
BOOL WahpnpDevice::OnSysDynamicDeviceInit()
{
//	pBeeper = new BeepTimeOut(500); 
	return TRUE;
}

BOOL WahpnpDevice::OnSysDynamicDeviceExit()
{
	return TRUE;
}
DWORD WahpnpDevice::OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams)
{
	DWORD	status;

	switch (pDIOCParams->dioc_IOCtlCode)
		{
	case DIOC_OPEN:
		Bufalloc();
		io=ioport+INTCSR;
		_outpd(io,0x3f0000);          // 清除所有中断源
		if (bUsingBuffer) {
			#ifdef DEBUG
				dout << "DMA: set memory!" << endl;
			#endif
			io=ioport+MWAR;
			_outpd(io,PhysAddr);
			io=ioport+MWTC;
			_outpd(io,128);
			io=ioport+MCSR;
			_outpd(io,0xc000000);      //ADD-ON到PCI的FIFO复位,邮箱复位
			io=ioport+INTCSR;
			_outpd(io,0x20005000);		
		}
		status = 0;
		break;
	case DIOC_CLOSEHANDLE:
		io=ioport+INTCSR;
		_outpd(io,0);
		if (bUsingBuffer) Buffree();
		if (bUsingInt) pMyIRQ->physicalMask();
		status = 0;
		break;
	case TEST:
		CallBackApc = pDIOCParams->dioc_InBuf;
		TheThread = Get_Cur_Thread_Handle();
		status = 0;
		if (!bUsingBuffer) status += 1;
		if (bUsingInt) pMyIRQ->physicalUnmask();
		else status += 2;
		io=ioport+OMB1;
		_outp(io,0x55);
		break;

	case READ:
		ClientBuffer = pDIOCParams->dioc_InBuf;
//		nBytes = pDIOCParams->dioc_cbInBuf;
		nBytes =128;
		memcpy(ClientBuffer, DMABufferLinear, nBytes);
		break;
	default:
		status = -1;
	}
	return status;
}


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];
		ioport=config.wIOPortBase[0];
		// Here we would initialize the device, doing things
		// like VPICD_Virtualize_IRQ, etc.

		if (irq != 0xff) {
			pMyIRQ = new MyHwInt();
			if (!pMyIRQ || !pMyIRQ->hook())	bUsingInt=FALSE;
			else bUsingInt=TRUE;
		};
		return CR_SUCCESS;

	case CONFIG_REMOVE /* 4 */:
	case CONFIG_STOP   /* 2 */:
		
		// Here we would disable the device and do things
		// like unvirtualizing our IRQ
		
		if (pMyIRQ) delete pMyIRQ;
		irq = 0xff;
		return CR_SUCCESS;

	default:
		return CR_DEFAULT;
	}			  
}				  
CONFIGRET WahpnpDevice::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;
	}
}
VOID Bufalloc(void)
{
	DWORD status;
	nPages=2;

	status=PageAllocate(
		nPages,
		PG_SYS,
		0,
		0, // align on 4K boundary
		0,
		0x100000,//4G
		&PhysAddr,
		PAGECONTIG | PAGEFIXED | PAGEUSEALIGN,
		&hMem,
		&DMABufferLinear);

	if (status == FALSE)
	{
		#ifdef DEBUG
			dout << "DMA: cannot get locked memory!" << endl;
		#endif
		bUsingBuffer=FALSE;
		dprintf("DMA: cannot get locked memory\n");
	}
	else
	{
		#ifdef DEBUG
			dout << "DMA: allocated a buffer with PageAllocate!" << endl;
		#endif
		bUsingBuffer=TRUE;
	}
}
VOID Buffree(void)
{
	PageFree(hMem, 0);
	#ifdef DEBUG
		dout << "DMA: free a buffer" << endl;
	#endif
}

⌨️ 快捷键说明

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