?? iphookglobal.cpp
字號:
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 1999 - 2000 Mark Roddy
// All Rights Reserved
//
// Hollis Technology Solutions
// 94 Dow Road
// Hollis, NH 03049
// info@hollistech.com
//
// Synopsis:
//
//
// Version Information:
//
// $Header: /iphook/sys/driver/IpHookGlobal.cpp 4 1/27/00 10:35p Markr $
//
///////////////////////////////////////////////////////////////////////////////
#include "IpHookKrnl.h"
HTS_DEBUG_THIS_FILE
void IP_HOOK_GLOBAL_DATA::queueRequest(PIRP Irp)
{
PVOID context;
lock(context);
IoSetCancelRoutine(Irp, GlobalCancel);
InsertTailList(&queue, &Irp->Tail.Overlay.ListEntry);
unlock(context);
}
PIRP IP_HOOK_GLOBAL_DATA::popQueue(BOOLEAN locked)
{
PIRP Irp = NULL;
PVOID context;
if (!locked) {
lock(context);
}
if (!IsListEmpty(&queue)) {
PLIST_ENTRY el = RemoveHeadList(&queue);
Irp = CONTAINING_RECORD(el, IRP, Tail.Overlay.ListEntry);
PDRIVER_CANCEL state = IoSetCancelRoutine(Irp, NULL);
if (state == NULL) {
//
// we have hit the race condition where our
// cancel routine is runnning just before it acquires
// the lock and dequeues the irp
//
InsertHeadList(&cancelQueue, &Irp->Tail.Overlay.ListEntry);
Irp = NULL;
}
}
if (!locked) {
unlock(context);
}
return Irp;
}
PIPHOOK_DATA IP_HOOK_GLOBAL_DATA::getBuffer()
{
PIPHOOK_DATA data = NULL;
HtsDebugPrint(HTS_DEBUG_LOW, "getBuffer()\n");
PVOID context;
lock(context);
bool keepTrying = true;
do {
if (currentBuffer == NULL) {
HtsAssert(currentIrp == NULL);
currentIrp = popQueue(TRUE);
if (currentIrp) {
currentBuffer =
(PIPHOOK_BUFFER) MmGetSystemAddressForMdl(currentIrp->MdlAddress);
}
if (currentBuffer) {
currentBuffer->valid = 0;
} else {
keepTrying =false;
}
}
if (currentBuffer) {
HtsDebugPrint(HTS_DEBUG_LOW, "currentBuffer %x valid %x entries %x\n",
currentBuffer,
currentBuffer->valid, currentBuffer->entries);
if (currentBuffer->valid < currentBuffer->entries) {
data = ¤tBuffer->buffer[currentBuffer->valid];
currentBuffer->valid++;
} else {
flushBuffer(TRUE);
HtsAssert(currentBuffer == NULL);
//
// Im tempted to recurse here
//
HtsDebugPrint(HTS_DEBUG_LOW, "getBuffer continue\n");
}
}
} while ((!currentBuffer) && keepTrying);
unlock(context);
HtsDebugPrint(HTS_DEBUG_LOW, "returning data %x\n", data);
return data;
}
IP_HOOK_GLOBAL_DATA::IP_HOOK_GLOBAL_DATA()
{
owningContext = NULL;
IpfDeviceObject = NULL;
IpfFileObject = NULL;
IpHookSequence = 0;
InitializeListHead(&queue);
InitializeListHead(&cancelQueue);
currentIrp = NULL;
currentBuffer = NULL;
KeInitializeEvent(&stopEvent, NotificationEvent, FALSE);
}
NTSTATUS IP_HOOK_GLOBAL_DATA::initDevice()
{
UNICODE_STRING nameString;
RtlInitUnicodeString(&nameString, DD_IPFLTRDRVR_DEVICE_NAME);
NTSTATUS Status = IoGetDeviceObjectPointer(&nameString,
STANDARD_RIGHTS_ALL,
&IpfFileObject,
&IpfDeviceObject);
if (!NT_SUCCESS(Status)) {
HtsDebugPrint(HTS_DEBUG_HIGH, "Can't open IpFilter (%S) Status %x\n",
DD_IPFLTRDRVR_DEVICE_NAME, Status);
} else {
HtsAssert( IpfFileObject );
HtsAssert( IpfDeviceObject );
}
return Status;
}
IP_HOOK_GLOBAL_DATA::~IP_HOOK_GLOBAL_DATA()
{
HtsDebugPrint(HTS_DEBUG_LOW,
"~IP_HOOK_GLOBAL_DATA IpfFileObject %x\n", IpfFileObject);
if (workerThreadObject != NULL) {
KeSetEvent(&stopEvent, 0, TRUE);
(void) KeWaitForSingleObject(workerThreadObject, Executive, KernelMode, FALSE, NULL);
ObDereferenceObject(workerThreadObject);
}
if (IpfFileObject) {
HtsAssert(IpfDeviceObject);
ObDereferenceObject(IpfFileObject);
IpfFileObject = NULL;
IpfDeviceObject = NULL;
} else {
HtsAssert(ipGlobal.IpfDeviceObject == NULL);
}
}
void IP_HOOK_GLOBAL_DATA::flushBufferIfData()
{
PVOID context;
lock(context);
if (currentIrp) {
HtsAssert(currentBuffer);
if (currentBuffer->valid) {
flushBuffer(TRUE);
}
}
unlock(context);
}
void IP_HOOK_GLOBAL_DATA::flushBuffer(BOOLEAN locked)
{
//
// complete the current buffer/irp
//
PIRP Irp = NULL;
ULONG Information = 0;
PVOID context;
HtsDebugPrint(HTS_DEBUG_LOW, "flushBuffer(%x)\n", locked);
if (!locked) {
lock(context);
}
if (currentIrp) {
HtsAssert(currentBuffer);
Irp = currentIrp;
currentIrp = NULL;
ULONG valid = currentBuffer->valid;
Information = sizeof(IPHOOK_BUFFER) - sizeof(IPHOOK_DATA)
+ (valid * sizeof(IPHOOK_DATA));
currentBuffer = NULL;
HtsDebugPrint(HTS_DEBUG_LOW, "Flushing Irp %x valid %x size %x\n", Irp, valid, Information);
}
if (!locked) {
unlock(context);
}
if (Irp) {
HtsIrpReturn(Irp, STATUS_SUCCESS, Information);
}
}
void IP_HOOK_GLOBAL_DATA::releaseAllBuffers(BOOLEAN locked)
{
flushBuffer(locked);
PIRP Irp = popQueue(locked);
HtsDebugPrint(HTS_DEBUG_LOW, "releaseAllBuffers(%d)\n", locked);
while (Irp) {
HtsDebugPrint(HTS_DEBUG_LOW, "releasing Irp %x\n", Irp);
HtsIrpReturn(Irp, STATUS_CANCELLED, 0);
Irp = popQueue(locked);
}
}
void workerThreadStart(PVOID context)
{
//
// this routine runs forever until it is signalled to die.
// It waits on an event - the stopevent, the wait is timed.
// If the timer expires then the function flushes the current buffer -
// delivering the contents to user space. Otherwise the routine terminates
// its host thread by returning out of this function.
//
PRKEVENT stopEvent = (PRKEVENT) context;
LARGE_INTEGER Timeout;
do {
Timeout.QuadPart = -10000000L;
NTSTATUS Status = KeWaitForSingleObject(stopEvent,
Executive,
KernelMode,
FALSE,
&Timeout);
switch (Status) {
case STATUS_TIMEOUT:
//
// flush the buffer
//
HtsDebugPrint(HTS_DEBUG_LOW, "workerThreadStart STATUS_TIMEOUT\n");
ipGlobal.flushBufferIfData();
break;
default:
HtsDebugPrint(HTS_DEBUG_HIGH,
"workerThreadStart wait returned %x\n", Status);
case STATUS_SUCCESS:
//
// for any value other than STATUS_TIMEOUT we bail!
//
HtsDebugPrint(HTS_DEBUG_LOW,
"workerThreadStart exit\n");
return;
}
} while(1);
}
NTSTATUS IP_HOOK_GLOBAL_DATA::createThread()
{
NTSTATUS Status = PsCreateSystemThread(&workerThread,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
workerThreadStart,
(PVOID)&stopEvent);
if (!NT_SUCCESS(Status)) {
HtsDebugPrint(HTS_DEBUG_HIGH, "PsCreateSystemThread failed\n");
workerThread = NULL;
}
Status = ObReferenceObjectByHandle(workerThread, THREAD_ALL_ACCESS, NULL, KernelMode,
&workerThreadObject, NULL );
if (!NT_SUCCESS(Status)) {
HtsDebugPrint(HTS_DEBUG_HIGH, "ObReferenceObjectByHandle failed\n");
KeSetEvent(&stopEvent, 0, FALSE);
workerThread = NULL;
workerThreadObject = NULL;
}
return Status;
}
///////////////////////////////////////////////////////////////////////////////
//
// Change History Log
//
// $Log: /iphook/sys/driver/IpHookGlobal.cpp $
//
// 4 1/27/00 10:35p Markr
// Prepare to release!
//
///////////////////////////////////////////////////////////////////////////////
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -