IpHookGlobal.cpp
资源名称:ipfilter.zip [点击查看]
上传用户:nnxzhh
上传日期:2007-01-11
资源大小:742k
文件大小:8k
源码类别:
防火墙与安全工具
开发平台:
WINDOWS
- ///////////////////////////////////////////////////////////////////////////////
- //
- // (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 %xn",
- 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 continuen");
- }
- }
- } while ((!currentBuffer) && keepTrying);
- unlock(context);
- HtsDebugPrint(HTS_DEBUG_LOW, "returning data %xn", 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 %xn",
- 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 %xn", 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 %xn", 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 %xn", 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_TIMEOUTn");
- ipGlobal.flushBufferIfData();
- break;
- default:
- HtsDebugPrint(HTS_DEBUG_HIGH,
- "workerThreadStart wait returned %xn", Status);
- case STATUS_SUCCESS:
- //
- // for any value other than STATUS_TIMEOUT we bail!
- //
- HtsDebugPrint(HTS_DEBUG_LOW,
- "workerThreadStart exitn");
- 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 failedn");
- workerThread = NULL;
- }
- Status = ObReferenceObjectByHandle(workerThread, THREAD_ALL_ACCESS, NULL, KernelMode,
- &workerThreadObject, NULL );
- if (!NT_SUCCESS(Status)) {
- HtsDebugPrint(HTS_DEBUG_HIGH, "ObReferenceObjectByHandle failedn");
- 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!
- //
- ///////////////////////////////////////////////////////////////////////////////