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

📄 f.c

📁 DS编写基于ISA插槽的,数据采集卡驱动程序,包含基本的中断,I/O读写
💻 C
📖 第 1 页 / 共 2 页
字号:
// mmdevice.cpp -  example driver, device class
//=============================================================================
//
// Compuware Corporation
// NuMega Lab
// 9 Townsend West
// Nashua, NH 03060  USA
//
// Copyright (c) 1998 Compuware Corporation. All Rights Reserved.
// Unpublished - rights reserved under the Copyright laws of the
// United States.
//
//=============================================================================

#include <vdw.h>
#include "mmioctl.h"
#include "mmdevice.h"

// This is a simple demonstration of mapping a bus physical address
// to process virtual space. In this example, the bus is assumed to
// be ISA, and there is assumed to be just one ISA bus. The address
// on the ISA bus is defaulted in mapmem.h, although DriverEntry will
// read both the bus address and memory window size from the registry.
// The address and size are recorded in the device object.

// Each time member Create is called, it means a new process is opening
// the device, and a new file object is created. This driver uses the
// FsContext field of the file object to store a pointer to the mapping
// object for the process that corresponds to the file object. 

// The mapping is not done until the process call DeviceIoControl to 
// request it. The driver returns a pointer in the process' virtual
// space to the device memory window.

// When member CleanUp is called, the process has closed all its handles
// to the driver, so the mapping can be deleted if it has not already
// been unmapped.

///////////////////////////////////////////////////////////////////////////
// Constructor
//
KDebugOnlyTrace T("mapmem");
//extern KDebugOnlyTrace T;
#pragma code_seg("INIT")

MapMemDevice::MapMemDevice() :
	KDevice(L"MapMem0", FILE_DEVICE_UNKNOWN, L"MAPMEM0", 0, DO_BUFFERED_IO),
	m_Exclusive(SynchronizationEvent, TRUE)
{
	m_File = 0;
	m_pEvent = NULL;
	m_bNotifyApp = TRUE;
	m_InterruptCount = 0;

	m_File1 = 0;
	m_pEvent1 = NULL;
	m_bNotifyApp1 = TRUE;
	m_InterruptCount1 = 0;
}


#pragma code_seg()
/////////////////////////////////////////////////////////////////////////////////
// Destructor
//
MapMemDevice::~MapMemDevice()
{
	GenericPort* p;

	do
	{
		p = m_PortList.RemoveHead();
		if (p) delete p;
	} while (p);
	
	T << "Deleting device\n";

	if (m_pEvent)
		delete m_pEvent;

	if ((PKINTERRUPT)m_Interrupt)
		m_Interrupt.Disconnect();

	if (m_pEvent1)
		delete m_pEvent1;

	if ((PKINTERRUPT)m_Interrupt1)
		m_Interrupt1.Disconnect();
}

///////////////////////////////////////////////////////////////////////////
// Create - a process is opening the driver for the first time
//
NTSTATUS MapMemDevice::Create(KIrp I)
{
	NTSTATUS status;
	

	
   	m_pEvent = NULL;


	m_pEvent1 = NULL;

//	T << "Create status = " << ULONG(status) << "\n";
	I.FileObject()->FsContext = 0;
	I.Information() = 0;
	return I.Complete(STATUS_SUCCESS);

}

///////////////////////////////////////////////////////////////////////////
// Create - a process is opening the driver for the first time
//
NTSTATUS MapMemDevice::Close(KIrp I)
{
	NTSTATUS status;

	I.Information() = 0;

	if (m_File == I.FileObject())
	{
		T << "Disconnecting interrupt\n";

		m_Interrupt.Disconnect();

		m_File = 0;
		if (m_pEvent) delete m_pEvent;
		m_pEvent = NULL;

		status = STATUS_SUCCESS;
	}
	else
		status = STATUS_UNSUCCESSFUL;

	I.Information() = 0;

	if (m_File1 == I.FileObject())
	{
		T << "Disconnecting interrupt\n";

		m_Interrupt1.Disconnect();

		m_File1 = 0;
		if (m_pEvent1) delete m_pEvent1;
		m_pEvent1 = NULL;

		status = STATUS_SUCCESS;
	}
	else
		status = STATUS_UNSUCCESSFUL;

	return I.Complete(status);
}     

///////////////////////////////////////////////////////////////////////////
	
// CleanUp - all handles of the calling process for this driver are closed
//
NTSTATUS MapMemDevice::CleanUp(KIrp I)
{
	// Test and clear the file object context

        
	m_Exclusive.Wait();

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

	m_Exclusive.Set();

	// if it was mapped, delete the mapping

	if (pMap != NULL)
		delete pMap;

	return I.Complete(STATUS_SUCCESS);
}

///////////////////////////////////////////////////////////////////////////
// DeviceControl
//
NTSTATUS MapMemDevice::DeviceControl(KIrp I)
{
	NTSTATUS status;
	T << I;
	PVOID ioBuffer  = I.IoctlBuffer();
	ULONG ioInSize  = I.IoctlInputBufferSize();
	ULONG ioOutSize = I.IoctlOutputBufferSize();

	KMemoryToProcessMap* pMap;
	DEVMAPMEMPARAMS* pOpen1;
	ULONG  LineAddr;

	I.Information() = 0;

  
	switch (I.IoctlCode())
	{
	case IOCTL_SET_NOTIFICATION_EVENT:
	{
		HANDLE hEvent = *(HANDLE*)I.IoctlBuffer();

		if (m_pEvent)
			delete m_pEvent;

		m_pEvent = new (NonPagedPool) KEvent(hEvent, OBJECT_TYPE_ALL_ACCESS);
		return I.Complete(STATUS_SUCCESS);
	}
	case IOCTL_GET_TIMESTAMP_DATA:
	{	
		if (SynchronizeInterrupt(&m_Interrupt, LinkTo(ReadTimeFifo), PIRP(I)) )
			return I.Complete(STATUS_SUCCESS);

		else
			return I.Complete(STATUS_UNSUCCESSFUL);

	}	
	case IOCTL_SET_NOTIFICATION_EVENT1:
	{
		HANDLE hEvent = *(HANDLE*)I.IoctlBuffer();

		if (m_pEvent1)
			delete m_pEvent1;

		m_pEvent1 = new (NonPagedPool) KEvent(hEvent, OBJECT_TYPE_ALL_ACCESS);
		return I.Complete(STATUS_SUCCESS);
	}
	case IOCTL_GET_TIMESTAMP_DATA1:
	{	
		if (SynchronizeInterrupt(&m_Interrupt1, LinkTo(ReadTimeFifo1), PIRP(I)) )
			return I.Complete(STATUS_SUCCESS);

		else
			return I.Complete(STATUS_UNSUCCESSFUL);

	}	
    case IOCTL_PORTIO_OPENPORT:
	{
		PORTOPENPARAMS* pOpen = (PORTOPENPARAMS*)ioBuffer;
		GenericPort** pHandle = (GenericPort**)ioBuffer;

// Validate parameters

		if ( (ioInSize  < sizeof(PORTOPENPARAMS)) ||
			 (ioOutSize < sizeof(GenericPort**) ) )
		{
			return I.Complete(STATUS_BUFFER_TOO_SMALL);
		}

// Create a new port object

		GenericPort* port = 
			new (NonPagedPool) GenericPort(
				pOpen->open_Address,
				pOpen->open_PortSize,
				pOpen->open_PortCount
				);

// Return result

		if (port && NT_SUCCESS(port->ConstructorStatus()))
		{
			m_PortList.InsertHead(port);
			*pHandle = port;
			I.Information() = sizeof(pHandle);
			status = STATUS_SUCCESS;
		}
		else
		{
			*pHandle = NULL;
			status = port ? STATUS_INVALID_PARAMETER : STATUS_INSUFFICIENT_RESOURCES;
		}		

		return I.Complete(status);
	}

	case IOCTL_PORTIO_READPORT:
	{
		PORTREADPARAMS* pRead = (PORTREADPARAMS*)ioBuffer;

// Validate parameters

		if ( ioInSize < sizeof(PORTREADPARAMS) )
		{
			return I.Complete(STATUS_BUFFER_TOO_SMALL);
		}

// Make sure the port is in the list
					
		GenericPort* port = (GenericPort*)pRead->rd_Handle;

		if (( !PortInList(port) ) || 
			( pRead->rd_Index >= port->Count()) ||
		    ( ioOutSize < sizeof(ULONG) ) )

			status = STATUS_INVALID_PARAMETER;

		else
		{

// Do the read

			*(ULONG*)ioBuffer = port->Read(pRead->rd_Index);
			I.Information() = sizeof(ULONG);
			status = STATUS_SUCCESS;
		}

		return I.Complete(status);
	}

	case IOCTL_PORTIO_WRITEPORT:
	{
		PORTWRITEPARAMS* pWrite = (PORTWRITEPARAMS*)ioBuffer;

// Validate parameters

		if ( ioInSize < sizeof(PORTWRITEPARAMS) )
		{
			return I.Complete(STATUS_BUFFER_TOO_SMALL);
		}
			
		GenericPort* port = (GenericPort*)pWrite->wr_Handle;

// Make sure the port is in the list

		if ( !PortInList(port) || (pWrite->wr_Index >= port->Count()) )
			status = STATUS_INVALID_PARAMETER;
		else
		{

// Do the write

			port->Write(pWrite->wr_Index, pWrite->wr_Data);

⌨️ 快捷键说明

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