📄 f.c
字号:
// 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 + -