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