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

📄 f.c

📁 DS编写基于ISA插槽的,数据采集卡驱动程序,包含基本的中断,I/O读写
💻 C
📖 第 1 页 / 共 2 页
字号:
			status = STATUS_SUCCESS;
		}

		return I.Complete(status);
	}

	case IOCTL_PORTIO_CLOSEPORT:
	{
		PORTCLOSEPARAMS* pClose = (PORTCLOSEPARAMS*)ioBuffer;

		if ( ioInSize < sizeof(PORTCLOSEPARAMS) )
		{
			return I.Complete(STATUS_BUFFER_TOO_SMALL);
		}
			
		GenericPort* port = (GenericPort*)pClose->close_Handle;

		if ( !PortInList(port) )
			status = STATUS_INVALID_PARAMETER;
		else
		{

// Remove the port from the device's list and delete it

			m_PortList.Remove(port);
			delete port;
			status = STATUS_SUCCESS;
		}
		return I.Complete(status);
	}
// Map the device to the calling process, return the process virtual address
    case IOCTL_GET_INIT1:
	{
		ULONG  IrqNum= *(ULONG*)ioBuffer;
		 if ( ioInSize  < sizeof(ULONG))
		 {
				return I.Complete(STATUS_BUFFER_TOO_SMALL);
		}
		m_Interrupt.Initialize(
		Isa,
		0,
		IrqNum,
		IrqNum,
		Latched,
		FALSE,
		FALSE
	);

	

      if (m_File == 0)
	{
		m_File = I.FileObject();
		status = m_Interrupt.Connect(LinkTo(Isr), this);
	}
	else
		status = STATUS_UNSUCCESSFUL;
//	m_pEvent = NULL;
    m_Dpc.Setup(LinkTo(Dpc), this);

	
	I.Information() = 0;
	return I.Complete(status);

	}
	case IOCTL_GET_INIT2:
	{
		ULONG  IrqNum= *(ULONG*)ioBuffer;
		 if ( ioInSize  < sizeof(ULONG))
		 {
				return I.Complete(STATUS_BUFFER_TOO_SMALL);
		}
		m_Interrupt1.Initialize(
		Isa,
		0,
		IrqNum,
		IrqNum,
		Latched,
		FALSE,
		FALSE
	);



	 if (m_File1 == 0)
	{
		m_File1 = I.FileObject();
		status = m_Interrupt1.Connect(LinkTo(Isr1), this);
	}
	else
		status = STATUS_UNSUCCESSFUL;
    m_Dpc1.Setup(LinkTo(Dpc1), this);

	I.Information() = 0;
	return I.Complete(status);

	}
	case IOCTL_MAPMEM_MAP_DEVICE:
	{
		pOpen1= (DEVMAPMEMPARAMS*)ioBuffer;
	        
	    if ( ioInSize  < sizeof(DEVMAPMEMPARAMS)) 
		{
				return I.Complete(STATUS_BUFFER_TOO_SMALL);
		}
		if ( ioOutSize < sizeof(PVOID) )
			return I.Complete(STATUS_BUFFER_TOO_SMALL);
		m_Exclusive.Wait();

		

			pMap = new(NonPagedPool) KMemoryToProcessMap(
				Isa,
				0,
				pOpen1->DeviceAddress,
				pOpen1->WindowSize,
				HANDLE(-1)
				);
			
		if (pMap)			
		{
			status = pMap->ConstructorStatus();
			if ( NT_SUCCESS(status) )
			{
				*(PVOID*)I.IoctlBuffer() = pMap->ProcessAddress();
				I.Information() = sizeof(PVOID);
				I.FileObject()->FsContext = pMap;
			}
		}
		else
			status = STATUS_INSUFFICIENT_RESOURCES;

		m_Exclusive.Set();
		return I.Complete(status);
        }
		
	case IOCTL_MAPMEM_UNMAP_DEVICE:
        {
// Unmap the device for the calling process

		m_Exclusive.Wait();

 		delete (KMemoryToProcessMap*)I.FileObject()->FsContext;
		I.FileObject()->FsContext = 0;

		m_Exclusive.Set();

		return I.Complete(STATUS_SUCCESS);
         } 
	default:
		return I.Complete(STATUS_INVALID_PARAMETER);
	}
}

/////////////////////////////////////////////////////////////////////////////////
// Find a port in the port list
//
BOOLEAN MapMemDevice::PortInList(GenericPort* pPort)
{
	GenericPort* p = m_PortList.Head();

	while (p)
	{
		if (p == pPort)
			return TRUE;

		else
			p = m_PortList.Next(p);

	}

	return FALSE;
}
//////////////////////////////////////////////////////////////////
// Isr
//
// This is the interrupt service routine. Since we always return
// FALSE (to indicate that we did not service the interrupt), there
// is no interaction with the hardware required. The system will
// call the actual floppy interrupt handler. This routine justs
// counts the interrupt (m_InterruptCount), grabs a timestamp,
// and requests queues the DPC object.
//
BOOLEAN MapMemDevice::Isr(void)
{
	
	m_Dpc.Request();
	return FALSE;
}

//////////////////////////////////////////////////////////////////
// Dpc
// 
// This the callback associated with the device's DPC object. The
// ISR queues the dpc object, resulting in a call to this routine.
// It invokes the synch crit section member function TestAndClearNotifyApp,
// which determines if it is necessary to notify the app of the 
// interrupt. The idea is that we only notify the app when there
// is no outstanding interrupt to which the app has not responded.
//
VOID MapMemDevice::Dpc(PVOID Arg1, PVOID Arg2)
{

		m_pEvent->Set();

}


//////////////////////////////////////////////////////////////////
// ReadTimeFifo
// 
// This is a synch critical section member function, called when
// the app requests data from the fifo. (Note: this could be done
// with a KInterruptSafeFifo object.)
//
BOOLEAN MapMemDevice::ReadTimeFifo(PVOID pIrp)
{
/*	KIrp I = (PIRP)pIrp;
	ULONG MaxReadItems = I.IoctlOutputBufferSize() / sizeof(TIMESTAMP);
	ULONG nItemsRead;

	nItemsRead = m_TimeStampFifo.Read((TIMESTAMP*)I.IoctlBuffer(), MaxReadItems);
	// guaranteed to empty the buffer, because app's read buffer is sizeof the fifo

	I.Information() = nItemsRead * sizeof(TIMESTAMP);

	m_bNotifyApp = TRUE;
*/
	return TRUE;
}

BOOLEAN MapMemDevice::TestAndClearNotifyApp(PVOID p)
{
/*	*(BOOLEAN*)p = m_bNotifyApp;
	m_bNotifyApp = FALSE;

	T << "TestAndClearNotifyApp previous state was=" << ULONG(m_bNotifyApp) << "\n";
*/
	return TRUE;
}

//////////////////////////////////////////////////////////////////
// Isr
//
// This is the interrupt service routine. Since we always return
// FALSE (to indicate that we did not service the interrupt), there
// is no interaction with the hardware required. The system will
// call the actual floppy interrupt handler. This routine justs
// counts the interrupt (m_InterruptCount), grabs a timestamp,
// and requests queues the DPC object.
//
BOOLEAN MapMemDevice::Isr1(void)
{
//	T << "In the ISR\n";
	
//	TIMESTAMP ts;

//	ts.ts_interrupt_count = ++m_InterruptCount1;
//	KeQueryTickCount(&ts.ts_time);

//	m_TimeStampFifo1.Write(&ts, 1);
	
	m_Dpc1.Request();
	return FALSE;
}

//////////////////////////////////////////////////////////////////
// Dpc
// 
// This the callback associated with the device's DPC object. The
// ISR queues the dpc object, resulting in a call to this routine.
// It invokes the synch crit section member function TestAndClearNotifyApp,
// which determines if it is necessary to notify the app of the 
// interrupt. The idea is that we only notify the app when there
// is no outstanding interrupt to which the app has not responded.
//
VOID MapMemDevice::Dpc1(PVOID Arg1, PVOID Arg2)
{
	BOOLEAN Notify;
	BOOLEAN SynchStatus;

	m_pEvent1->Set();
/*	if (m_pEvent1) 
	{
		SynchStatus = SynchronizeInterrupt(
			&m_Interrupt1, 
			LinkTo(TestAndClearNotifyApp1), 
			&Notify
			);

		if (SynchStatus)
		{
			T << "DPC, App notify=" << ULONG(Notify) << "\n";
			if (Notify) 
				m_pEvent1->Set();
		}
		else
			T << "Dpc error synchronizing\n";
	}
*/
}


//////////////////////////////////////////////////////////////////
// ReadTimeFifo
// 
// This is a synch critical section member function, called when
// the app requests data from the fifo. (Note: this could be done
// with a KInterruptSafeFifo object.)
//
BOOLEAN MapMemDevice::ReadTimeFifo1(PVOID pIrp)
{
/*	KIrp I = (PIRP)pIrp;
	ULONG MaxReadItems = I.IoctlOutputBufferSize() / sizeof(TIMESTAMP);
	ULONG nItemsRead;

	nItemsRead = m_TimeStampFifo1.Read((TIMESTAMP*)I.IoctlBuffer(), MaxReadItems);
	// guaranteed to empty the buffer, because app's read buffer is sizeof the fifo

	I.Information() = nItemsRead * sizeof(TIMESTAMP);

	m_bNotifyApp1 = TRUE;
*/
	return TRUE;
}

BOOLEAN MapMemDevice::TestAndClearNotifyApp1(PVOID p)
{
/*	*(BOOLEAN*)p = m_bNotifyApp1;
	m_bNotifyApp1 = FALSE;

	T << "TestAndClearNotifyApp previous state was=" << ULONG(m_bNotifyApp1) << "\n";
*/
	return TRUE;
}

⌨️ 快捷键说明

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