IpHookGlobal.cpp
上传用户:nnxzhh
上传日期:2007-01-11
资源大小:742k
文件大小:8k
开发平台:

WINDOWS

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright 1999 - 2000 Mark Roddy
  4. // All Rights Reserved
  5. //
  6. // Hollis Technology Solutions
  7. // 94 Dow Road
  8. // Hollis, NH 03049
  9. // info@hollistech.com
  10. //
  11. // Synopsis: 
  12. // 
  13. //
  14. // Version Information:
  15. //
  16. // $Header: /iphook/sys/driver/IpHookGlobal.cpp 4     1/27/00 10:35p Markr $ 
  17. //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #include "IpHookKrnl.h"
  20. HTS_DEBUG_THIS_FILE
  21. void IP_HOOK_GLOBAL_DATA::queueRequest(PIRP Irp)
  22. {
  23. PVOID context;
  24. lock(context);
  25. IoSetCancelRoutine(Irp, GlobalCancel);
  26. InsertTailList(&queue, &Irp->Tail.Overlay.ListEntry);
  27. unlock(context);
  28. }
  29. PIRP IP_HOOK_GLOBAL_DATA::popQueue(BOOLEAN locked)
  30. {
  31. PIRP Irp = NULL;
  32. PVOID context;
  33. if (!locked) {
  34. lock(context);
  35. }
  36. if (!IsListEmpty(&queue)) {
  37. PLIST_ENTRY el = RemoveHeadList(&queue);
  38. Irp = CONTAINING_RECORD(el, IRP, Tail.Overlay.ListEntry);
  39. PDRIVER_CANCEL state = IoSetCancelRoutine(Irp, NULL);
  40. if (state == NULL) {
  41. //
  42. // we have hit the race condition where our
  43. // cancel routine is runnning just before it acquires
  44. // the lock and dequeues the irp
  45. //
  46. InsertHeadList(&cancelQueue, &Irp->Tail.Overlay.ListEntry);
  47. Irp = NULL;
  48. }
  49.     }
  50. if (!locked) {
  51. unlock(context);
  52. }
  53. return Irp;
  54. }
  55. PIPHOOK_DATA IP_HOOK_GLOBAL_DATA::getBuffer()
  56. {
  57. PIPHOOK_DATA data = NULL;
  58. HtsDebugPrint(HTS_DEBUG_LOW, "getBuffer()n");
  59. PVOID context;
  60. lock(context);
  61. bool keepTrying = true;
  62. do {
  63. if (currentBuffer == NULL) {
  64. HtsAssert(currentIrp == NULL);
  65. currentIrp = popQueue(TRUE);
  66. if (currentIrp) {
  67. currentBuffer = 
  68. (PIPHOOK_BUFFER) MmGetSystemAddressForMdl(currentIrp->MdlAddress);
  69. }
  70. if (currentBuffer) {
  71. currentBuffer->valid = 0;
  72. }  else {
  73. keepTrying =false;
  74. }
  75. }
  76. if (currentBuffer) {
  77. HtsDebugPrint(HTS_DEBUG_LOW, "currentBuffer %x valid %x entries %xn",
  78. currentBuffer,
  79. currentBuffer->valid, currentBuffer->entries);
  80. if (currentBuffer->valid < currentBuffer->entries) {
  81. data = &currentBuffer->buffer[currentBuffer->valid];
  82. currentBuffer->valid++;
  83. } else {
  84. flushBuffer(TRUE);
  85. HtsAssert(currentBuffer == NULL);
  86. //
  87. // Im tempted to recurse here
  88. //
  89. HtsDebugPrint(HTS_DEBUG_LOW, "getBuffer continuen");
  90. }
  91. }
  92. } while ((!currentBuffer) && keepTrying);
  93. unlock(context);
  94. HtsDebugPrint(HTS_DEBUG_LOW, "returning data %xn", data);
  95. return data;
  96. }
  97. IP_HOOK_GLOBAL_DATA::IP_HOOK_GLOBAL_DATA() 
  98. {
  99. owningContext = NULL;
  100. IpfDeviceObject = NULL;
  101. IpfFileObject = NULL;
  102. IpHookSequence = 0;
  103. InitializeListHead(&queue);
  104. InitializeListHead(&cancelQueue);
  105. currentIrp = NULL;
  106. currentBuffer = NULL;
  107. KeInitializeEvent(&stopEvent, NotificationEvent, FALSE);
  108. }
  109. NTSTATUS IP_HOOK_GLOBAL_DATA::initDevice()
  110. {
  111. UNICODE_STRING nameString;
  112. RtlInitUnicodeString(&nameString, DD_IPFLTRDRVR_DEVICE_NAME);
  113. NTSTATUS Status = IoGetDeviceObjectPointer(&nameString,
  114.   STANDARD_RIGHTS_ALL,
  115.   &IpfFileObject,
  116.   &IpfDeviceObject);
  117. if (!NT_SUCCESS(Status)) {
  118. HtsDebugPrint(HTS_DEBUG_HIGH, "Can't open IpFilter (%S) Status %xn",
  119.   DD_IPFLTRDRVR_DEVICE_NAME, Status);
  120. } else {
  121. HtsAssert( IpfFileObject );
  122. HtsAssert( IpfDeviceObject );
  123. }
  124. return Status;
  125. }
  126. IP_HOOK_GLOBAL_DATA::~IP_HOOK_GLOBAL_DATA()
  127. {
  128. HtsDebugPrint(HTS_DEBUG_LOW, 
  129. "~IP_HOOK_GLOBAL_DATA IpfFileObject %xn", IpfFileObject);
  130. if (workerThreadObject != NULL) {
  131. KeSetEvent(&stopEvent, 0, TRUE);
  132. (void) KeWaitForSingleObject(workerThreadObject, Executive, KernelMode, FALSE, NULL);
  133. ObDereferenceObject(workerThreadObject);
  134.         
  135. }
  136. if (IpfFileObject) {
  137. HtsAssert(IpfDeviceObject);
  138. ObDereferenceObject(IpfFileObject);
  139. IpfFileObject = NULL;
  140. IpfDeviceObject = NULL;
  141. } else {
  142. HtsAssert(ipGlobal.IpfDeviceObject == NULL);
  143. }
  144. }
  145. void IP_HOOK_GLOBAL_DATA::flushBufferIfData()
  146. {
  147. PVOID context;
  148. lock(context);
  149. if (currentIrp) {
  150. HtsAssert(currentBuffer);
  151. if (currentBuffer->valid) {
  152. flushBuffer(TRUE);
  153. }
  154. }
  155. unlock(context);
  156. }
  157. void IP_HOOK_GLOBAL_DATA::flushBuffer(BOOLEAN locked)
  158. {
  159. //
  160. // complete the current buffer/irp
  161. //
  162. PIRP Irp = NULL;
  163. ULONG Information = 0;
  164. PVOID context;
  165. HtsDebugPrint(HTS_DEBUG_LOW, "flushBuffer(%x)n", locked);
  166. if (!locked) {
  167. lock(context);
  168. }
  169. if (currentIrp) {
  170. HtsAssert(currentBuffer);
  171. Irp = currentIrp;
  172. currentIrp = NULL;
  173. ULONG valid = currentBuffer->valid;
  174. Information = sizeof(IPHOOK_BUFFER) - sizeof(IPHOOK_DATA)
  175. + (valid * sizeof(IPHOOK_DATA));
  176. currentBuffer = NULL;
  177. HtsDebugPrint(HTS_DEBUG_LOW, "Flushing Irp %x valid %x size %xn", Irp, valid, Information);
  178. }
  179. if (!locked) {
  180. unlock(context);
  181. }
  182. if (Irp) {
  183. HtsIrpReturn(Irp, STATUS_SUCCESS, Information);
  184. }
  185. }
  186. void IP_HOOK_GLOBAL_DATA::releaseAllBuffers(BOOLEAN locked)
  187. {
  188. flushBuffer(locked);
  189. PIRP Irp = popQueue(locked);
  190. HtsDebugPrint(HTS_DEBUG_LOW, "releaseAllBuffers(%d)n", locked);
  191. while (Irp) {
  192. HtsDebugPrint(HTS_DEBUG_LOW, "releasing Irp %xn", Irp);
  193. HtsIrpReturn(Irp, STATUS_CANCELLED, 0);
  194. Irp = popQueue(locked);
  195. }
  196. }
  197. void workerThreadStart(PVOID context)
  198. {
  199. //
  200. // this routine runs forever until it is signalled to die.
  201. // It waits on an event - the stopevent, the wait is timed.
  202. // If the timer expires then the function flushes the current buffer - 
  203. // delivering the contents to user space. Otherwise the routine terminates
  204. // its host thread by returning out of this function.
  205. //
  206. PRKEVENT stopEvent = (PRKEVENT) context;
  207. LARGE_INTEGER  Timeout;
  208. do {
  209. Timeout.QuadPart = -10000000L;
  210. NTSTATUS Status = KeWaitForSingleObject(stopEvent,
  211.   Executive,
  212.   KernelMode,
  213.   FALSE,
  214.   &Timeout);
  215. switch (Status) {
  216. case STATUS_TIMEOUT:
  217. //
  218. // flush the buffer
  219. //
  220. HtsDebugPrint(HTS_DEBUG_LOW, "workerThreadStart STATUS_TIMEOUTn");
  221. ipGlobal.flushBufferIfData();
  222. break;
  223. default:
  224. HtsDebugPrint(HTS_DEBUG_HIGH,
  225. "workerThreadStart wait returned %xn", Status);
  226. case STATUS_SUCCESS:
  227. //
  228. // for any value other than STATUS_TIMEOUT we bail!
  229. //
  230. HtsDebugPrint(HTS_DEBUG_LOW,
  231. "workerThreadStart exitn");
  232. return;
  233. }
  234. } while(1);
  235. }
  236. NTSTATUS IP_HOOK_GLOBAL_DATA::createThread()
  237. {
  238. NTSTATUS Status = PsCreateSystemThread(&workerThread,
  239.   THREAD_ALL_ACCESS,
  240.   NULL,
  241.   NULL,
  242.   NULL,
  243.   workerThreadStart,
  244.   (PVOID)&stopEvent);
  245. if (!NT_SUCCESS(Status)) {
  246. HtsDebugPrint(HTS_DEBUG_HIGH, "PsCreateSystemThread failedn");
  247. workerThread = NULL;
  248. }
  249. Status = ObReferenceObjectByHandle(workerThread, THREAD_ALL_ACCESS, NULL, KernelMode,
  250.   &workerThreadObject, NULL );
  251. if (!NT_SUCCESS(Status)) {
  252. HtsDebugPrint(HTS_DEBUG_HIGH, "ObReferenceObjectByHandle failedn");
  253. KeSetEvent(&stopEvent, 0, FALSE);
  254. workerThread = NULL;
  255. workerThreadObject = NULL;
  256. }
  257. return Status;
  258. }
  259. ///////////////////////////////////////////////////////////////////////////////
  260. // 
  261. // Change History Log
  262. //
  263. // $Log: /iphook/sys/driver/IpHookGlobal.cpp $
  264. // 
  265. // 4     1/27/00 10:35p Markr
  266. // Prepare to release!
  267. //
  268. ///////////////////////////////////////////////////////////////////////////////