{"id":570,"date":"2012-07-07T18:47:25","date_gmt":"2012-07-07T10:47:25","guid":{"rendered":"http:\/\/newbiecoder.0ginr.com\/blog\/?p=570"},"modified":"2012-08-21T19:27:45","modified_gmt":"2012-08-21T11:27:45","slug":"tdi-%e8%bf%87%e6%bb%a4%e9%a9%b1%e5%8a%a8%e7%9b%91%e8%a7%86%e8%bf%9b%e7%a8%8b%e7%9a%84%e7%bd%91%e7%bb%9c%e6%b5%81%e9%87%8f","status":"publish","type":"post","link":"https:\/\/newbiecoder.0ginr.com\/blog\/?p=570","title":{"rendered":"TDI \u8fc7\u6ee4\u9a71\u52a8\u76d1\u89c6\u8fdb\u7a0b\u7684\u7f51\u7edc\u6d41\u91cf"},"content":{"rendered":"<p>\u8981\u63a7\u5236\u6d41\u91cf\u5927\u6982\u662f\u5728 IoCompletion \u91cc\u9762\u8fd4\u56de STATUS_MORE_PROCESSING_REQUIRED \u7136\u540e\u6295\u9012\u4e00\u4e2a WorkItem \u5230\u67d0\u4e2a\u5de5\u4f5c\u7ebf\u7a0b\u91cc\u9762\u53bb\uff0c\u7136\u540e\u5728\u90a3\u5de5\u4f5c\u7ebf\u7a0b\u91cc\u9762\u591a Sleep \u4e00\u4f1a\u513f\u518d IoCompleteRequest\uff1f<\/p>\n<pre>[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:  280, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:  280, Sent:        413 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:         57 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:    4, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:         57 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:    4, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:  280, Sent:        413 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:         57 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:    4, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:  280, Sent:        596 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:        239 bytes \/ s Received:      70948 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:    4, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:        239 bytes \/ s Received:    8927920 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:    4, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   12346060 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:    8163876 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:    9287056 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:    3076616 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:    7026796 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:    9108028 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:    3158352 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:    5285124 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   10047148 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   11329012 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   13408224 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   13795512 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   16626816 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:    4, Sent:        201 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   13855816 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   20182288 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   14285852 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   14093656 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   17039600 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   18342860 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   16822336 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   14925796 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   17185912 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   17422724 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   14773376 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   13452628 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:   20832756 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:  280, Sent:         17 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:    2674734 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1132, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:    2674734 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id: 1588, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:    4, Sent:          0 bytes \/ s Received:          0 bytes \/ s.\r\n[FlowWatcher] DumpNetworkUsage: Process Id:    4, Sent:          0 bytes \/ s Received:          0 bytes \/ s.<\/pre>\n<p><code>#include <ntddk.h><br \/>\n#include <tdikrnl.h>\n<p>\/\/<br \/>\n\/\/ \u9a71\u52a8\u540d\u79f0\u3002<br \/>\n\/\/<\/p>\n<p>#define PROJECT_NAME \"FlowWatcher\"<\/p>\n<p>\/\/<br \/>\n\/\/ \u8f93\u51fa\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u95f4\u9694\uff0c\u5355\u4f4d\u6beb\u79d2\u3002<br \/>\n\/\/<br \/>\n\/\/ \u7531\u4e8e MILLISECOND_TO_SECOND \u5728\u5c06\u6beb\u79d2\u8f6c\u6362\u4e3a\u79d2\u65f6\u53ef\u80fd\u4f1a\u6709\u7cbe\u5ea6\u635f\u5931<br \/>\n\/\/ \u56e0\u6b64\u6b64\u5904\u6700\u597d\u662f\u6574\u6570\u79d2\u3002<br \/>\n\/\/<\/p>\n<p>#define NETWORK_USAGE_DUMP_INTERVAL 1000<\/p>\n<p>\/\/<br \/>\n\/\/ \u6beb\u79d2\u8f6c\u6362\u4e3a\u5185\u6838\u4e0b\u7684\u7b49\u5f85\u65f6\u957f\u3002<br \/>\n\/\/<br \/>\n\/\/ \u5185\u6838\u4e0b\u7684\u7b49\u5f85\u65f6\u957f\u4e3a\u8d1f\u6570\u65f6\u8868\u793a\u8d85\u65f6\u95f4\u9694\u4e3a\u76f8\u5bf9\u65f6\u957f\uff0c\u5355\u4f4d\u662f\u7eb3\u79d2\u3002<br \/>\n\/\/<br \/>\n\/\/ \u6709\u5173\u4e8e\u5185\u6838\u4e0b\u7684\u7b49\u5f85\u65f6\u957f\uff08\u5373 KeWaitForSingleObject \u7684 Timeout \u53c2\u6570\uff09\uff0c\u53c2\u8003<br \/>\n\/\/ http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/hardware\/ff553350(v=vs.85).aspx\u3002<br \/>\n\/\/<\/p>\n<p>#define MILLISECOND_TO_KERNEL_DELAY(Millisecond) (-1LL * (Millisecond) * 1000 * 10)<\/p>\n<p>\/\/<br \/>\n\/\/ \u6beb\u79d2\u8f6c\u6362\u4e3a\u79d2\u3002<br \/>\n\/\/<br \/>\n\/\/ \u6b64\u5904\u662f\u6574\u9664\uff0c\u82e5\u4e0d\u662f\u6574\u6570\u79d2\uff0c\u5219\u4f1a\u6709\u7cbe\u5ea6\u635f\u5931\u3002<br \/>\n\/\/<\/p>\n<p>#define MILLISECOND_TO_SECOND(Millisecond) ((Millisecond) \/ 1000)<\/p>\n<p>\/\/<br \/>\n\/\/ \u83b7\u53d6\u7528\u4e8e\u9644\u52a0\u64cd\u4f5c\u7684\u8bbe\u5907\u7684\u8bbe\u5907\u6269\u5c55\u3002<br \/>\n\/\/<\/p>\n<p>#define ATTACHING_DEVICE_EXTENSION(DeviceObject) ((PATTACHING_DEVICE_EXTENSION)((DeviceObject)->DeviceExtension))<\/p>\n<p>\/\/<br \/>\n\/\/ \u7528\u4e8e\u8bb0\u5f55\u7f51\u7edc\u4f7f\u7528\u4fe1\u606f\u7684\u901a\u7528\u8868\u7684\u8282\u70b9\u7684\u7f13\u51b2\u6c60\u6807\u8bb0\u3002<br \/>\n\/\/<\/p>\n<p>#define NETWORK_USAGE_GENERIC_TABLE_NODE_TAG 'NUGT'<\/p>\n<p>\/\/<br \/>\n\/\/ TDI \u7684 TCP \u8bbe\u5907\u540d\u3002<br \/>\n\/\/<\/p>\n<p>#define TCP_DEVICE_NAME L\"\\\\Device\\\\Tcp\"<\/p>\n<p>\/\/<br \/>\n\/\/ TDI \u7684 UDP \u8bbe\u5907\u540d\u3002<br \/>\n\/\/<\/p>\n<p>#define UDP_DEVICE_NAME L\"\\\\Device\\\\Udp\"<\/p>\n<p>\/\/<br \/>\n\/\/ TDI \u7684 RAW IP \u8bbe\u5907\u540d\u3002<br \/>\n\/\/<\/p>\n<p>#define RAWIP_DEVICE_NAME L\"\\\\Device\\\\RawIp\"<\/p>\n<p>\/\/<br \/>\n\/\/ \u8ba1\u7b97\u9759\u6001\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u4e2a\u6570\u3002<br \/>\n\/\/<\/p>\n<p>#define CountOf(Array) ((sizeof(Array) \/ sizeof((Array)[0])))<\/p>\n<p>\/\/<br \/>\n\/\/ \u5355\u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u7684\u7edf\u8ba1\u4fe1\u606f\u3002<br \/>\n\/\/<\/p>\n<p>typedef struct _NETWORK_USAGE_INFORMATION {<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u81ea\u4ece\u4e0a\u6b21\u8f93\u51fa\u7edf\u8ba1\u4fe1\u606f\u540e\u53d1\u9001\u7684\u5b57\u8282\u6570\u3002<br \/>\n\t\/\/<br \/>\n\t\/\/ \u6bcf\u6b21\u8f93\u51fa\u7edf\u8ba1\u4fe1\u606f\u90fd\u4f1a\u6e05\u7a7a\u53d1\u9001\u5b57\u8282\u6570\u3002<br \/>\n\t\/\/<\/p>\n<p>\tULONGLONG BytesSent;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u81ea\u4ece\u4e0a\u6b21\u8f93\u51fa\u7edf\u8ba1\u4fe1\u606f\u540e\u63a5\u53d7\u7684\u5b57\u8282\u6570\u3002<br \/>\n\t\/\/<br \/>\n\t\/\/ \u6bcf\u6b21\u8f93\u51fa\u7edf\u8ba1\u4fe1\u606f\u90fd\u4f1a\u6e05\u7a7a\u63a5\u53d7\u5b57\u8282\u6570\u3002<br \/>\n\t\/\/<\/p>\n<p>\tULONGLONG BytesReceived;<br \/>\n} NETWORK_USAGE_INFORMATION, *PNETWORK_USAGE_INFORMATION;<\/p>\n<p>\/\/<br \/>\n\/\/ \u50a8\u5b58\u5728\u901a\u7528\u8868\u4e2d\u7684\u8282\u70b9\u3002<br \/>\n\/\/<\/p>\n<p>typedef struct _NETWORK_USAGE_GENERIC_TABLE_NODE {<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u8fdb\u7a0b\u7684 PCB \u6307\u9488\u3002<br \/>\n\t\/\/<br \/>\n\t\/\/ \u5728\u901a\u7528\u8868\u4e2d\u5b58\u653e\u65f6\uff0c\u7528\u4e8e\u6bd4\u8f83\u7ed3\u6784\u4f53\u76f8\u5bf9\u5927\u5c0f\u4f7f\u7528\u7684\u5c31\u662f Process \u6210\u5458\u3002<br \/>\n\t\/\/<\/p>\n<p>\tPEPROCESS Process;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u4fe1\u606f\u3002<br \/>\n\t\/\/<\/p>\n<p>\tNETWORK_USAGE_INFORMATION NetworkUsageInformation;<br \/>\n} NETWORK_USAGE_GENERIC_TABLE_NODE, *PNETWORK_USAGE_GENERIC_TABLE_NODE;<\/p>\n<p>\/\/<br \/>\n\/\/ \u7528\u4e8e\u7edf\u8ba1\u8fdb\u7a0b\u7f51\u7edc\u4f7f\u7528\u4fe1\u606f\u7684\u8868\u3002<br \/>\n\/\/<\/p>\n<p>typedef struct _NETWORK_USAGE_GENERIC_TABLE {<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u7528\u4e8e\u8bb0\u5f55\u4fe1\u606f\u7684\u901a\u7528\u8868\u3002<br \/>\n\t\/\/<\/p>\n<p>\tRTL_GENERIC_TABLE Table;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u7528\u4e8e\u540c\u6b65\u8bbf\u95ee\u7684\u81ea\u65cb\u9501\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKSPIN_LOCK TableLock;<br \/>\n} NETWORK_USAGE_GENERIC_TABLE, *PNETWORK_USAGE_GENERIC_TABLE;<\/p>\n<p>\/\/<br \/>\n\/\/ \u8f93\u51fa\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u5de5\u4f5c\u7ebf\u7a0b\u63a7\u5236\u5757\u3002<br \/>\n\/\/<\/p>\n<p>typedef struct _NETWORK_USAGE_DUMPER_CONTROL_BLOCK {<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u5de5\u4f5c\u7ebf\u7a0b\u7684\u6307\u9488\u3002<br \/>\n\t\/\/<\/p>\n<p>\tPETHREAD Worker;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u4e3a TRUE \u65f6\u8981\u6c42\u5de5\u4f5c\u7ebf\u7a0b\u9000\u51fa\u3002<br \/>\n\t\/\/<\/p>\n<p>\tBOOLEAN Exit;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u8f93\u51fa\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u5de5\u4f5c\u7ebf\u7a0b\u6bcf\u9694 NETWORK_USAGE_DUMP_INTERVAL \u6beb\u79d2<br \/>\n\t\/\/ \u8f93\u51fa\u4e00\u6b21\u3002\u5982\u679c\u76f4\u63a5\u4f7f\u7528 KeDelayExecutionThread\uff0c\u90a3\u4e48\u5728 DriverUnload<br \/>\n\t\/\/ \u4e2d\u7b49\u5f85\u5de5\u4f5c\u7ebf\u7a0b\u9000\u51fa\u6700\u591a\u4f1a\u9700\u8981\u5927\u7ea6 NETWORK_USAGE_DUMP_INTERVAL<br \/>\n\t\/\/ \u6beb\u79d2\u7684\u65f6\u95f4\u3002\u5f53 NETWORK_USAGE_DUMP_INTERVAL \u589e\u5927\u65f6\uff0cDriverUnload<br \/>\n\t\/\/ \u53ef\u80fd\u4f1a\u9700\u8981\u76f8\u5f53\u957f\u7684\u7b49\u5f85\u65f6\u95f4\u3002<br \/>\n\t\/\/<br \/>\n\t\/\/ \u8003\u8651\u5230 DriverUnload \u662f\u7531\u7cfb\u7edf\u7684\u5de5\u4f5c\u7ebf\u7a0b\u8c03\u7528\u7684\uff0c\u56e0\u6b64\u5e94\u5f53\u5c3d\u5feb\u8fd4\u56de\u3002<br \/>\n\t\/\/ \u6240\u4ee5\u6b64\u5904\u4ee4\u5de5\u4f5c\u7ebf\u7a0b\u7b49\u5f85 SleepingEvent\u3002SleepingEvent \u9664\u975e\u5728 Exit<br \/>\n\t\/\/ \u4e3a TRUE \u7684\u65f6\u5019\u624d\u4f1a\u7f6e\u4e3a\u4fe1\u53f7\u6001\u3002\u8fd9\u6837\uff0c\u5728\u9a71\u52a8\u9000\u51fa\u4e4b\u524d\u3002\u7b49\u5f85 SleepingEvent<br \/>\n\t\/\/ \u7684\u7ed3\u679c\u603b\u662f\u4f1a\u8d85\u65f6\uff0c\u8fd9\u6837\u4e5f\u5c31\u5b9e\u73b0\u4e86 KeDelayExecutionThread \u7684\u6548\u679c\uff0c<br \/>\n\t\/\/ \u800c DriverUnload \u4e2d\u5c06 SleepingEvent \u7f6e\u4e3a\u4fe1\u53f7\u6001\uff0c\u8fd9\u6837\u7b49\u5f85\u5c31\u4f1a\u7acb\u5373<br \/>\n\t\/\/ \u7ed3\u675f\uff0c\u4ece\u800c\u8ba9\u5de5\u4f5c\u7ebf\u7a0b\u7acb\u5373\u9000\u51fa\u3002<br \/>\n\t\/\/<br \/>\n\t\/\/ \u5982\u679c\u5c06\u6765 WDK \u63d0\u4f9b\u4e86\u7c7b\u4f3c KeAlertThread \u7684\u4f8b\u7a0b\uff0c\u5219\u53ef\u4ee5\u8003\u8651\u4f7f\u7528<br \/>\n\t\/\/ KeDelayExecutionThread + KeAlertThread \u7684\u7ec4\u5408\u3002<br \/>\n\t\/\/<br \/>\n\t\/\/ \u540c\u6837\uff0c\u901a\u8fc7\u6295\u9012 APC \u4e5f\u53ef\u4ee5\u5524\u9192\u5de5\u4f5c\u7ebf\u7a0b\uff0c\u4f46\u662f\u4e3a\u4e86\u5524\u9192\u7ebf\u7a0b\u800c\u6295\u9012<br \/>\n\t\/\/ APC \u5e76\u975e\u4e00\u4e2a\u597d\u7684\u9009\u62e9\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKEVENT SleepingEvent;<br \/>\n} NETWORK_USAGE_DUMPER_CONTROL_BLOCK, *PNETWORK_USAGE_DUMPER_CONTROL_BLOCK;<\/p>\n<p>\/\/<br \/>\n\/\/ \u9644\u52a0\u5230\u8bbe\u5907\u7684\u64cd\u4f5c\u7684\u72b6\u6001\u3002<br \/>\n\/\/<\/p>\n<p>typedef struct _DEVICE_ATTACH_STATE {<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u7528\u4e8e\u9644\u52a0\u64cd\u4f5c\u6240\u521b\u5efa\u7684\u8bbe\u5907\u3002<br \/>\n\t\/\/<\/p>\n<p>\tPDEVICE_OBJECT AttachingDevice;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u9644\u52a0\u5230\u7684\u8bbe\u5907\u3002<br \/>\n\t\/\/<br \/>\n\t\/\/ \u7531\u4e8e\u6211\u4eec\u662f\u9644\u52a0\u5230\u76ee\u6807\u8bbe\u5907\u4e4b\u4e0a\uff0c\u56e0\u6b64\u6b64\u8bbe\u5907\u4e5f\u662f\u7d27\u6328\u6211\u4eec\u4e0b\u5c42\u7684\u8bbe\u5907\u3002<br \/>\n\t\/\/<\/p>\n<p>\tPDEVICE_OBJECT AttachedDevice;<br \/>\n} DEVICE_ATTACH_STATE, *PDEVICE_ATTACH_STATE;<\/p>\n<p>\/\/<br \/>\n\/\/ \u7528\u4e8e\u9644\u52a0\u64cd\u4f5c\u6240\u521b\u5efa\u7684\u8bbe\u5907\u7684\u8bbe\u5907\u6269\u5c55\u3002<br \/>\n\/\/<\/p>\n<p>typedef struct _ATTACHING_DEVICE_EXTENSION {<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u7528\u4e8e\u63cf\u8ff0\u9644\u52a0\u64cd\u4f5c\u7684\u72b6\u6001\u3002<br \/>\n\t\/\/<\/p>\n<p>\tDEVICE_ATTACH_STATE AttachState;<br \/>\n} ATTACHING_DEVICE_EXTENSION, *PATTACHING_DEVICE_EXTENSION;<\/p>\n<p>\/\/<br \/>\n\/\/ \u7528\u4e8e\u63cf\u8ff0\u9644\u52a0\u64cd\u4f5c\u7684\u6570\u636e\u7ed3\u6784\u3002<br \/>\n\/\/<\/p>\n<p>typedef struct _DEVICE_ATTACHMENT {<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u8981\u9644\u52a0\u5230\u7684\u8bbe\u5907\u7684\u8bbe\u5907\u540d\u3002<br \/>\n\t\/\/<\/p>\n<p>\tUNICODE_STRING TargetDeviceName;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u4e3a\u9644\u52a0\u64cd\u4f5c\u521b\u5efa\u7684\u8bbe\u5907\u5bf9\u8c61\u3002<br \/>\n\t\/\/<\/p>\n<p>\tPDEVICE_OBJECT AttachingDevice;<br \/>\n} DEVICE_ATTACHMENT, *PDEVICE_ATTACHMENT;<\/p>\n<p>\/\/<br \/>\n\/\/ \u8f93\u51fa\u8c03\u8bd5\u4fe1\u606f\u3002<br \/>\n\/\/<\/p>\n<p>#define DbgWrite(Format, ...) DbgPrint(\"[\" PROJECT_NAME \"] \" __FUNCTION__ \": \" Format, __VA_ARGS__)<br \/>\n#define DbgWriteLine(Format, ...) DbgWrite(Format \"\\n\", __VA_ARGS__)<\/p>\n<p>\/\/<br \/>\n\/\/ \u8f93\u51fa\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u5de5\u4f5c\u7ebf\u7a0b\u7684\u63a7\u5236\u5757\u3002<br \/>\n\/\/<\/p>\n<p>NETWORK_USAGE_DUMPER_CONTROL_BLOCK NetworkUsageDumperControlBlock;<\/p>\n<p>\/\/<br \/>\n\/\/ \u7edf\u8ba1\u7f51\u7edc\u4f7f\u7528\u72b6\u51b5\u7684\u8868\u3002<br \/>\n\/\/<\/p>\n<p>NETWORK_USAGE_GENERIC_TABLE NetworkUsageGenericTable;<\/p>\n<p>\/\/<br \/>\n\/\/ \u9700\u8981\u8fdb\u884c\u7684\u9644\u52a0\u9a71\u52a8\u7684\u64cd\u4f5c\u3002<br \/>\n\/\/<\/p>\n<p>DEVICE_ATTACHMENT DeviceAttachments[] = {<br \/>\n\t{RTL_CONSTANT_STRING(TCP_DEVICE_NAME), 0},<br \/>\n\t{RTL_CONSTANT_STRING(UDP_DEVICE_NAME), 0},<br \/>\n\t{RTL_CONSTANT_STRING(RAWIP_DEVICE_NAME), 0}<br \/>\n};<\/p>\n<p>\/\/<br \/>\n\/\/ \u9a71\u52a8\u5bf9\u8c61\u3002<br \/>\n\/\/<\/p>\n<p>PDRIVER_OBJECT FlowWatcherDriverObject;<\/p>\n<p>\/\/<br \/>\n\/\/ \u51fd\u6570\u539f\u578b\u58f0\u660e\u3002<br \/>\n\/\/<\/p>\n<p>RTL_GENERIC_COMPARE_ROUTINE NetworkUsageGenericTableComparaRoutine;<br \/>\nRTL_GENERIC_ALLOCATE_ROUTINE NetworkUsageGenericTableAllocateRoutine;<br \/>\nRTL_GENERIC_FREE_ROUTINE NetworkUsageGenericTableFreeRoutine;<br \/>\nDRIVER_DISPATCH GeneralPassthroughDispath;<br \/>\nDRIVER_INITIALIZE DriverEntry;<br \/>\nDRIVER_UNLOAD DriverUnload;<br \/>\nKSTART_ROUTINE NetworkUsageDumper;<\/p>\n<p>VOID InitializeNetworkUsageGenericTable(<br \/>\n\tVOID<br \/>\n\t);<\/p>\n<p>NTSTATUS AttachDevice(<br \/>\n\t__out PDEVICE_ATTACH_STATE DeviceAttachState,<br \/>\n\t__in PDEVICE_OBJECT AttachingDevice,<br \/>\n\t__in PUNICODE_STRING DeviceName<br \/>\n\t);<\/p>\n<p>NTSTATUS CreateAndAttachDevice(<br \/>\n\t__out PDEVICE_OBJECT *AttachingDevice,<br \/>\n\t__in PUNICODE_STRING DeviceName<br \/>\n\t);<\/p>\n<p>VOID DetachDevice(<br \/>\n\t__in PDEVICE_ATTACH_STATE DeviceAttachState<br \/>\n\t);<\/p>\n<p>VOID DeleteAndDetachDevice(<br \/>\n\t__in PDEVICE_ATTACH_STATE DeviceAttachState<br \/>\n\t);<\/p>\n<p>NTSTATUS AttachDevices(<br \/>\n\tVOID<br \/>\n\t);<\/p>\n<p>VOID DetachDevices(<br \/>\n\tVOID<br \/>\n\t);<\/p>\n<p>NTSTATUS CreateNetworkUsageDumper(<br \/>\n\tVOID<br \/>\n\t);<\/p>\n<p>VOID TerminateNetworkUsageDumper(<br \/>\n\tVOID<br \/>\n\t);<\/p>\n<p>\/\/<br \/>\n\/\/ \u5c06\u51fd\u6570\u5173\u8054\u5230\u5bf9\u5e94\u7684\u4ee3\u7801\u6bb5\u3002<br \/>\n\/\/<\/p>\n<p>#ifdef ALLOC_PRAGMA<\/p>\n<p>#pragma alloc_text(INIT, DriverEntry)<br \/>\n#pragma alloc_text(INIT, InitializeNetworkUsageGenericTable)<br \/>\n#pragma alloc_text(INIT, CreateNetworkUsageDumper)<br \/>\n#pragma alloc_text(INIT, AttachDevice)<br \/>\n#pragma alloc_text(INIT, CreateAndAttachDevice)<br \/>\n#pragma alloc_text(INIT, AttachDevices)<\/p>\n<p>#pragma alloc_text(PAGE, DriverUnload)<br \/>\n#pragma alloc_text(PAGE, TerminateNetworkUsageDumper)<br \/>\n#pragma alloc_text(PAGE, NetworkUsageDumper)<br \/>\n#pragma alloc_text(PAGE, DetachDevice)<br \/>\n#pragma alloc_text(PAGE, DeleteAndDetachDevice)<br \/>\n#pragma alloc_text(PAGE, DetachDevices)<\/p>\n<p>#endif<\/p>\n<p>\/\/<br \/>\n\/\/ \u7528\u4e8e\u6bd4\u8f83\u4e24\u4e2a NETWORK_USAGE_GENERIC_TABLE_NODE \u7684\u6bd4\u8f83\u51fd\u6570\u3002<br \/>\n\/\/<\/p>\n<p>RTL_GENERIC_COMPARE_RESULTS NTAPI NetworkUsageGenericTableComparaRoutine(<br \/>\n\t__in PRTL_GENERIC_TABLE GenericTable,<br \/>\n\t__in PVOID FirstObject,<br \/>\n\t__in PVOID SecondObject<br \/>\n\t)<br \/>\n{<br \/>\n\tPNETWORK_USAGE_GENERIC_TABLE_NODE LeftNode, RightNode;<\/p>\n<p>\tLeftNode = (PNETWORK_USAGE_GENERIC_TABLE_NODE)FirstObject;<br \/>\n\tRightNode = (PNETWORK_USAGE_GENERIC_TABLE_NODE)SecondObject;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u6b64\u5904\u4f7f\u7528 NETWORK_USAGE_GENERIC_TABLE_NODE::Process \u6765\u6bd4\u8f83\u7ed3\u6784\u4f53\u7684\u5927\u5c0f\u3002<br \/>\n\t\/\/<\/p>\n<p>\tif (LeftNode->Process < RightNode->Process) {<br \/>\n\t\treturn GenericLessThan;<br \/>\n\t} else if (LeftNode->Process > RightNode->Process) {<br \/>\n\t\treturn GenericGreaterThan;<br \/>\n\t} else {<br \/>\n\t\treturn GenericEqual;<br \/>\n\t}<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u7528\u4e8e\u5206\u914d NETWORK_USAGE_GENERIC_TABLE_NODE \u7684\u51fd\u6570\u3002<br \/>\n\/\/<\/p>\n<p>PVOID NTAPI NetworkUsageGenericTableAllocateRoutine(<br \/>\n\t__in PRTL_GENERIC_TABLE GenericTable,<br \/>\n\t__in CLONG BufferSize<br \/>\n\t)<br \/>\n{<br \/>\n\treturn ExAllocatePoolWithTag(NonPagedPool, BufferSize, NETWORK_USAGE_GENERIC_TABLE_NODE_TAG);<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u7528\u4e8e\u91ca\u653e NETWORK_USAGE_GENERIC_TABLE_NODE \u7684\u51fd\u6570\u3002<br \/>\n\/\/<\/p>\n<p>VOID NTAPI NetworkUsageGenericTableFreeRoutine(<br \/>\n\t__in PRTL_GENERIC_TABLE GenericTable,<br \/>\n\t__in PVOID Buffer<br \/>\n\t)<br \/>\n{<br \/>\n\tExFreePoolWithTag(Buffer, NETWORK_USAGE_GENERIC_TABLE_NODE_TAG);<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u521d\u59cb\u5316\u7edf\u8ba1\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u901a\u7528\u8868\u3002<br \/>\n\/\/<\/p>\n<p>VOID InitializeNetworkUsageGenericTable(<br \/>\n\tVOID<br \/>\n\t)<br \/>\n{<br \/>\n\t\/\/<br \/>\n\t\/\/ \u521d\u59cb\u5316\u7528\u4e8e\u540c\u6b65\u8bbf\u95ee\u7684\u81ea\u65cb\u9501\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeInitializeSpinLock(&NetworkUsageGenericTable.TableLock);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u521d\u59cb\u5316\u7528\u4e8e\u8bb0\u5f55\u4fe1\u606f\u7684\u901a\u7528\u8868\u3002<br \/>\n\t\/\/<\/p>\n<p>\tRtlInitializeGenericTable(&NetworkUsageGenericTable.Table,<br \/>\n\t\tNetworkUsageGenericTableComparaRoutine,<br \/>\n\t\tNetworkUsageGenericTableAllocateRoutine,<br \/>\n\t\tNetworkUsageGenericTableFreeRoutine,<br \/>\n\t\tNULL);<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u91ca\u653e\u7edf\u8ba1\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u901a\u7528\u8868\uff08\u4e0d\u4e0a\u9501\uff09\u3002<br \/>\n\/\/<\/p>\n<p>VOID DeleteNetworkUsageGenericTableUnsafe(<br \/>\n\tVOID<br \/>\n\t)<br \/>\n{<br \/>\n\tPVOID CurrentEntry;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u9010\u4e2a\u5220\u9664\u5143\u7d20\u3002<br \/>\n\t\/\/<\/p>\n<p>\tfor (CurrentEntry = RtlEnumerateGenericTable(&NetworkUsageGenericTable.Table, TRUE);<br \/>\n\t\tCurrentEntry;<br \/>\n\t\tCurrentEntry = RtlEnumerateGenericTable(&NetworkUsageGenericTable.Table, FALSE)) {<br \/>\n\t\tBOOLEAN DeleteStatus;<\/p>\n<p>\t\t\/\/<br \/>\n\t\t\/\/ \u5220\u9664\u5143\u7d20\u3002<br \/>\n\t\t\/\/<\/p>\n<p>\t\tDeleteStatus = RtlDeleteElementGenericTable(&NetworkUsageGenericTable.Table, CurrentEntry);<\/p>\n<p>\t\tASSERT(DeleteStatus == TRUE);<br \/>\n\t}<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u91ca\u653e\u7edf\u8ba1\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u901a\u7528\u8868\u3002<br \/>\n\/\/<\/p>\n<p>VOID DeleteNetworkUsageGenericTable(<br \/>\n\tVOID<br \/>\n\t)<br \/>\n{<br \/>\n\tKLOCK_QUEUE_HANDLE LockHandle;<br \/>\n\tPVOID CurrentEntry;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u83b7\u53d6\u81ea\u65cb\u9501\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeAcquireInStackQueuedSpinLock(&NetworkUsageGenericTable.TableLock,<br \/>\n\t\t&LockHandle);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u6e05\u7a7a\u901a\u7528\u8868\u3002<br \/>\n\t\/\/<\/p>\n<p>\tDeleteNetworkUsageGenericTableUnsafe();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u91ca\u653e\u81ea\u65cb\u9501\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeReleaseInStackQueuedSpinLock(&LockHandle);<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u83b7\u53d6\u67d0\u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\uff08\u4e0d\u4e0a\u9501\uff09\u3002<br \/>\n\/\/<\/p>\n<p>BOOLEAN QueryProcessNetworkUsageUnsafe(<br \/>\n\t__in PEPROCESS Process,<br \/>\n\t__out PNETWORK_USAGE_INFORMATION NetworkUsageInformation<br \/>\n\t)<br \/>\n{<br \/>\n\tNETWORK_USAGE_GENERIC_TABLE_NODE TableNode;<br \/>\n\tPVOID EntryFound;<\/p>\n<p>\tTableNode.Process = Process;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u67e5\u8be2\u4f7f\u7528\u60c5\u51b5\u3002<br \/>\n\t\/\/<\/p>\n<p>\tEntryFound = RtlLookupElementGenericTable(&NetworkUsageGenericTable.Table,<br \/>\n\t\t(PVOID)&TableNode);<\/p>\n<p>\tif (!EntryFound) {<br \/>\n\t\treturn FALSE;<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u8fd4\u56de\u4fe1\u606f\u3002<br \/>\n\t\/\/<\/p>\n<p>\t*NetworkUsageInformation = ((PNETWORK_USAGE_GENERIC_TABLE_NODE)EntryFound)->NetworkUsageInformation;<\/p>\n<p>\treturn TRUE;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u83b7\u53d6\u67d0\u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u3002<br \/>\n\/\/<\/p>\n<p>BOOLEAN QueryProcessNetworkUsage(<br \/>\n\t__in PEPROCESS Process,<br \/>\n\t__out PNETWORK_USAGE_INFORMATION NetworkUsageInformation<br \/>\n\t)<br \/>\n{<br \/>\n\tKLOCK_QUEUE_HANDLE LockHandle;<br \/>\n\tBOOLEAN Status;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u83b7\u53d6\u81ea\u65cb\u9501\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeAcquireInStackQueuedSpinLock(&NetworkUsageGenericTable.TableLock,<br \/>\n\t\t&LockHandle);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u67e5\u8be2\u4f7f\u7528\u60c5\u51b5\u3002<br \/>\n\t\/\/<\/p>\n<p>\tStatus = QueryProcessNetworkUsageUnsafe(Process, NetworkUsageInformation);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u91ca\u653e\u81ea\u65cb\u9501\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeReleaseInStackQueuedSpinLock(&LockHandle);<\/p>\n<p>\tif (Status != TRUE) {<br \/>\n\t\treturn Status;<br \/>\n\t}<\/p>\n<p>\treturn Status;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u66f4\u65b0\u67d0\u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\uff08\u4e0d\u4e0a\u9501\uff09\u3002<br \/>\n\/\/<\/p>\n<p>VOID UpdateProcessNetworkUsageUnsafe(<br \/>\n\t__in PEPROCESS Process,<br \/>\n\t__in PNETWORK_USAGE_INFORMATION NetworkUsageInformation<br \/>\n\t)<br \/>\n{<br \/>\n\tNETWORK_USAGE_GENERIC_TABLE_NODE TableNode;<br \/>\n\tPVOID EntryFound;<\/p>\n<p>\tTableNode.Process = Process;<br \/>\n\tTableNode.NetworkUsageInformation = *NetworkUsageInformation;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u5220\u9664\u5df2\u6709\u8282\u70b9\u3002<br \/>\n\t\/\/<\/p>\n<p>\tEntryFound = RtlLookupElementGenericTable(&NetworkUsageGenericTable.Table,<br \/>\n\t\t(PVOID)&TableNode);<\/p>\n<p>\tif (EntryFound) {<br \/>\n\t\tBOOLEAN Status;<\/p>\n<p>\t\tStatus = RtlDeleteElementGenericTable(&NetworkUsageGenericTable.Table, EntryFound);<\/p>\n<p>\t\tASSERT(Status == TRUE);<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u63d2\u5165\u65b0\u8282\u70b9\u3002<br \/>\n\t\/\/<\/p>\n<p>\t(VOID)RtlInsertElementGenericTable(&NetworkUsageGenericTable.Table,<br \/>\n\t\t(PVOID)&TableNode, sizeof(NETWORK_USAGE_GENERIC_TABLE_NODE), NULL);<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u66f4\u65b0\u67d0\u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u3002<br \/>\n\/\/<\/p>\n<p>VOID UpdateProcessNetworkUsage(<br \/>\n\t__in PEPROCESS Process,<br \/>\n\t__in PNETWORK_USAGE_INFORMATION NetworkUsageInformation<br \/>\n\t)<br \/>\n{<br \/>\n\tKLOCK_QUEUE_HANDLE LockHandle;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u83b7\u53d6\u81ea\u65cb\u9501\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeAcquireInStackQueuedSpinLock(&NetworkUsageGenericTable.TableLock,<br \/>\n\t\t&LockHandle);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u66f4\u65b0\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u3002<br \/>\n\t\/\/<\/p>\n<p>\tUpdateProcessNetworkUsageUnsafe(Process, NetworkUsageInformation);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u91ca\u653e\u81ea\u65cb\u9501\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeReleaseInStackQueuedSpinLock(&LockHandle);<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u8f93\u51fa\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u7edf\u8ba1\u4fe1\u606f\u3002<br \/>\n\/\/<\/p>\n<p>VOID DumpNetworkUsage(<br \/>\n\tVOID<br \/>\n\t)<br \/>\n{<br \/>\n\tKLOCK_QUEUE_HANDLE LockHandle;<br \/>\n\tPVOID CurrentEntry;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u83b7\u53d6\u81ea\u65cb\u9501\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeAcquireInStackQueuedSpinLock(&NetworkUsageGenericTable.TableLock,<br \/>\n\t\t&LockHandle);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u904d\u5386\u7edf\u8ba1\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u901a\u7528\u8868\u3002<br \/>\n\t\/\/<\/p>\n<p>\tfor (CurrentEntry = RtlEnumerateGenericTable(&NetworkUsageGenericTable.Table, TRUE);<br \/>\n\t\tCurrentEntry;<br \/>\n\t\tCurrentEntry = RtlEnumerateGenericTable(&NetworkUsageGenericTable.Table, FALSE)) {<br \/>\n\t\tPNETWORK_USAGE_GENERIC_TABLE_NODE TableNode;<br \/>\n\t\tPEPROCESS Process;<br \/>\n\t\tNETWORK_USAGE_INFORMATION NetworkUsageInformation;<\/p>\n<p>\t\tTableNode = (PNETWORK_USAGE_GENERIC_TABLE_NODE)CurrentEntry;<\/p>\n<p>\t\tProcess = TableNode->Process;<br \/>\n\t\tNetworkUsageInformation = TableNode->NetworkUsageInformation;<\/p>\n<p>\t\t\/\/<br \/>\n\t\t\/\/ \u8f93\u51fa\u4fe1\u606f\u3002<br \/>\n\t\t\/\/<br \/>\n\t\t\/\/ DbgPrint \u5728\u8f93\u51fa 64 \u4f4d\u6574\u6570\u65f6\u4f3c\u4e4e\u4e0d\u80fd\u8bc6\u522b %lld\uff08\u81f3\u5c11\u4e0d\u80fd\u8bc6\u522b %10lld\uff09\uff0c\u56e0\u6b64<br \/>\n\t\t\/\/ \u6b64\u5904\u4f7f\u7528 %I64d\u3002<br \/>\n\t\t\/\/<\/p>\n<p>\t\tDbgWriteLine(\"Process Id: %4d, Sent: %10I64d bytes \/ s Received: %10I64d bytes \/ s.\",<br \/>\n\t\t\tPsGetProcessId(Process),<br \/>\n\t\t\tNetworkUsageInformation.BytesSent \/ MILLISECOND_TO_SECOND(NETWORK_USAGE_DUMP_INTERVAL),<br \/>\n\t\t\tNetworkUsageInformation.BytesReceived \/ MILLISECOND_TO_SECOND(NETWORK_USAGE_DUMP_INTERVAL));<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u6e05\u7a7a\u7edf\u8ba1\u6570\u636e\u3002<br \/>\n\t\/\/<\/p>\n<p>\tDeleteNetworkUsageGenericTableUnsafe();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u91ca\u653e\u81ea\u65cb\u9501\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeReleaseInStackQueuedSpinLock(&LockHandle);<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u7528\u4e8e\u8f93\u51fa\u5f53\u524d\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u5de5\u4f5c\u7ebf\u7a0b\u3002<br \/>\n\/\/<\/p>\n<p>VOID NetworkUsageDumper(<br \/>\n\t__in PVOID Context<br \/>\n\t)<br \/>\n{<br \/>\n\tPNETWORK_USAGE_DUMPER_CONTROL_BLOCK ControlBlock;<\/p>\n<p>\tPAGED_CODE();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u83b7\u5f97\u63a7\u5236\u5757\u6307\u9488\u3002<br \/>\n\t\/\/<\/p>\n<p>\tControlBlock = (PNETWORK_USAGE_DUMPER_CONTROL_BLOCK)Context;<\/p>\n<p>\twhile (!ControlBlock->Exit) {<br \/>\n\t\tLARGE_INTEGER DumpInterval;<\/p>\n<p>\t\t\/\/<br \/>\n\t\t\/\/ \u6bcf\u9694 NETWORK_USAGE_DUMP_INTERVAL \u6beb\u79d2\u8f93\u51fa\u4e00\u6b21\u7edf\u8ba1\u4fe1\u606f\u3002<br \/>\n\t\t\/\/<br \/>\n\t\t\/\/ \u6709\u5173\u4e8e SleepingEvent \u7684\u4f7f\u7528\uff0c\u53c2\u8003 NETWORK_USAGE_DUMPER_CONTROL_BLOCK<br \/>\n\t\t\/\/ \u7684\u5b9a\u4e49\u3002<br \/>\n\t\t\/\/<\/p>\n<p>\t\tDumpInterval.QuadPart = MILLISECOND_TO_KERNEL_DELAY(NETWORK_USAGE_DUMP_INTERVAL);<\/p>\n<p>\t\t(VOID)KeWaitForSingleObject((PVOID)&ControlBlock->SleepingEvent, Executive, KernelMode,<br \/>\n\t\t\tFALSE, &DumpInterval);<\/p>\n<p>\t\t\/\/<br \/>\n\t\t\/\/ \u8f93\u51fa\u7edf\u8ba1\u4fe1\u606f\u3002<br \/>\n\t\t\/\/<\/p>\n<p>\t\tDumpNetworkUsage();<br \/>\n\t}<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u9644\u52a0\u5230\u6307\u5b9a\u8bbe\u5907\u3002<br \/>\n\/\/<\/p>\n<p>NTSTATUS AttachDevice(<br \/>\n\t__out PDEVICE_ATTACH_STATE DeviceAttachState,<br \/>\n\t__in PDEVICE_OBJECT AttachingDevice,<br \/>\n\t__in PUNICODE_STRING DeviceName<br \/>\n\t)<br \/>\n{<br \/>\n\tNTSTATUS Status;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u9644\u52a0\u5230\u6307\u5b9a\u8bbe\u5907\u3002<br \/>\n\t\/\/<\/p>\n<p>\tStatus = IoAttachDevice(AttachingDevice, DeviceName, &DeviceAttachState->AttachedDevice);<\/p>\n<p>\tif (!NT_SUCCESS(Status)) {<br \/>\n\t\treturn Status;<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u586b\u5145\u9644\u52a0\u72b6\u6001\u4fe1\u606f\u3002<br \/>\n\t\/\/<\/p>\n<p>\tDeviceAttachState->AttachingDevice = AttachingDevice;<\/p>\n<p>\treturn Status;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u521b\u5efa\u4e00\u4e2a\u8bbe\u5907\u5bf9\u8c61\u5e76\u5c06\u5176\u9644\u52a0\u5230\u6307\u5b9a\u7684\u8bbe\u5907\u4e0a\u3002<br \/>\n\/\/<\/p>\n<p>NTSTATUS CreateAndAttachDevice(<br \/>\n\t__out PDEVICE_OBJECT *AttachingDevice,<br \/>\n\t__in PUNICODE_STRING DeviceName<br \/>\n\t)<br \/>\n{<br \/>\n\tPATTACHING_DEVICE_EXTENSION DeviceExtension;<br \/>\n\tPDEVICE_OBJECT LocalAttachingDevice;<br \/>\n\tNTSTATUS Status;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u521b\u5efa\u7528\u4e8e\u9644\u52a0\u64cd\u4f5c\u7684\u8bbe\u5907\u5bf9\u8c61\u3002<br \/>\n\t\/\/<\/p>\n<p>\tStatus = IoCreateDevice(FlowWatcherDriverObject,<br \/>\n\t\tsizeof(ATTACHING_DEVICE_EXTENSION),\tNULL, FILE_DEVICE_NETWORK, 0, FALSE,<br \/>\n\t\t&LocalAttachingDevice);<\/p>\n<p>\tif (!NT_SUCCESS(Status)) {<br \/>\n\t\treturn Status;<br \/>\n\t}<\/p>\n<p>\tDeviceExtension = (PATTACHING_DEVICE_EXTENSION)LocalAttachingDevice->DeviceExtension;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u5c06\u8bbe\u5907\u9644\u52a0\u5230\u6307\u5b9a\u7684\u8bbe\u5907\u4e0a\u3002<br \/>\n\t\/\/<\/p>\n<p>\tStatus = AttachDevice(&DeviceExtension->AttachState, LocalAttachingDevice, DeviceName);<\/p>\n<p>\tif (!NT_SUCCESS(Status)) {<br \/>\n\t\tIoDeleteDevice(LocalAttachingDevice);<\/p>\n<p>\t\treturn Status;<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u5c06\u65b0\u521b\u5efa\u7684\u8bbe\u5907\u5bf9\u8c61\u8fd4\u56de\u7ed9\u8c03\u7528\u65b9\u3002<br \/>\n\t\/\/<\/p>\n<p>\t*AttachingDevice = LocalAttachingDevice;<\/p>\n<p>\treturn Status;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u4ece\u4e4b\u524d\u9644\u52a0\u5230\u7684\u8bbe\u5907\u4e0a\u5206\u79bb\u3002<br \/>\n\/\/<\/p>\n<p>VOID DetachDevice(<br \/>\n\t__in PDEVICE_ATTACH_STATE DeviceAttachState<br \/>\n\t)<br \/>\n{<br \/>\n\tPAGED_CODE();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u5206\u79bb\u3002<br \/>\n\t\/\/<\/p>\n<p>\tIoDetachDevice(DeviceAttachState->AttachedDevice);<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u4ece\u4e4b\u524d\u9644\u52a0\u5230\u7684\u8bbe\u5907\u4e0a\u5206\u79bb\u5e76\u91ca\u653e\u4e3a\u9644\u52a0\u64cd\u4f5c\u521b\u5efa\u7684\u8bbe\u5907\u5bf9\u8c61\u3002<br \/>\n\/\/<\/p>\n<p>VOID DeleteAndDetachDevice(<br \/>\n\t__in PDEVICE_ATTACH_STATE DeviceAttachState<br \/>\n\t)<br \/>\n{<br \/>\n\tPAGED_CODE();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u5206\u79bb\u8bbe\u5907\u3002<br \/>\n\t\/\/<\/p>\n<p>\tDetachDevice(DeviceAttachState);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u5220\u9664\u8bbe\u5907\u3002<br \/>\n\t\/\/<\/p>\n<p>\tIoDeleteDevice(DeviceAttachState->AttachingDevice);<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u9644\u52a0\u5230\u5404\u4e2a\uff08TCP \/ UDP \/ RAW IP\uff09 TDI \u9a71\u52a8\u7684\u8bbe\u5907\u5bf9\u8c61\u4e0a\u3002<br \/>\n\/\/<\/p>\n<p>NTSTATUS AttachDevices(<br \/>\n\tVOID<br \/>\n\t)<br \/>\n{<br \/>\n\tULONG DeviceIndex;<br \/>\n\tNTSTATUS Status;\t<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u9644\u52a0\u5230 TDI \u7684\u8bbe\u5907\u4e0a\u3002<br \/>\n\t\/\/<\/p>\n<p>\tfor (DeviceIndex = 0; DeviceIndex < CountOf(DeviceAttachments); DeviceIndex++) {\n\t\tULONG DeviceIndex2;\n\n\t\t\/\/\n\t\t\/\/ \u9644\u52a0\u5230\u8be5\u8bbe\u5907\u4e0a\u3002\n\t\t\/\/\n\n\t\tStatus = CreateAndAttachDevice(&#038;DeviceAttachments[DeviceIndex].AttachingDevice,\n\t\t\t&#038;DeviceAttachments[DeviceIndex].TargetDeviceName);\n\n\t\tif (!NT_SUCCESS(Status)) {\n\n\t\t\t\/\/\n\t\t\t\/\/ \u64a4\u9500\u5df2\u7ecf\u6210\u529f\u7684\u9644\u52a0\u64cd\u4f5c\u3002\n\t\t\t\/\/\n\n\t\t\tfor (DeviceIndex2 = 0; DeviceIndex2 < DeviceIndex; DeviceIndex2++) {\n\n\t\t\t\t\/\/\n\t\t\t\t\/\/ \u5206\u79bb\u8bbe\u5907\u5e76\u5220\u9664\u521b\u5efa\u7684\u8bbe\u5907\u3002\n\t\t\t\t\/\/\n\n\t\t\t\tDeleteAndDetachDevice(&#038;ATTACHING_DEVICE_EXTENSION(\n\t\t\t\t\tDeviceAttachments[DeviceIndex2].AttachingDevice)->AttachState);<br \/>\n\t\t\t}<\/p>\n<p>\t\t\tbreak;<br \/>\n\t\t}<br \/>\n\t}<\/p>\n<p>\treturn Status;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u4ece TDI \u7684\u5404\u4e2a\u8bbe\u5907\u5bf9\u8c61\u4e0a\u5206\u79bb\u3002<br \/>\n\/\/<\/p>\n<p>VOID DetachDevices(<br \/>\n\tVOID<br \/>\n\t)<br \/>\n{<br \/>\n\tULONG DeviceIndex;<\/p>\n<p>\tPAGED_CODE();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u64a4\u9500\u9644\u52a0\u5230 TDI \u7684\u8bbe\u5907\u7684\u64cd\u4f5c\u3002<br \/>\n\t\/\/<\/p>\n<p>\tfor (DeviceIndex = 0; DeviceIndex < CountOf(DeviceAttachments); DeviceIndex++) {\n\n\t\t\/\/\n\t\t\/\/ \u5206\u79bb\u8bbe\u5907\u5e76\u5220\u9664\u521b\u5efa\u7684\u8bbe\u5907\u3002\n\t\t\/\/\n\n\t\tDeleteAndDetachDevice(&#038;ATTACHING_DEVICE_EXTENSION(\n\t\t\tDeviceAttachments[DeviceIndex].AttachingDevice)->AttachState);<br \/>\n\t}<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u521b\u5efa\u7528\u4e8e\u8f93\u51fa\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u7ebf\u7a0b\u3002<br \/>\n\/\/<\/p>\n<p>NTSTATUS CreateNetworkUsageDumper(<br \/>\n\tVOID<br \/>\n\t)<br \/>\n{<br \/>\n\tHANDLE ThreadHandle;<br \/>\n\tNTSTATUS Status;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u521d\u59cb\u5316\u7ebf\u7a0b\u63a7\u5236\u5757\u3002<br \/>\n\t\/\/<\/p>\n<p>\tNetworkUsageDumperControlBlock.Exit = FALSE;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u7528\u4e8e\u7ebf\u7a0b\u4f11\u7720\u7684\u4e8b\u4ef6\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeInitializeEvent(&NetworkUsageDumperControlBlock.SleepingEvent, NotificationEvent, FALSE);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u521b\u5efa\u7ebf\u7a0b\u3002<br \/>\n\t\/\/<\/p>\n<p>\tStatus = PsCreateSystemThread(&ThreadHandle, 0, NULL, 0, NULL, NetworkUsageDumper,<br \/>\n\t\t(PVOID)&NetworkUsageDumperControlBlock);<\/p>\n<p>\tif (!NT_SUCCESS(Status)) {<br \/>\n\t\treturn Status;<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u83b7\u5f97\u7ebf\u7a0b\u7684 ETHREAD\u3002<br \/>\n\t\/\/<\/p>\n<p>\tStatus = ObReferenceObjectByHandle(ThreadHandle, 0, *PsThreadType, KernelMode,<br \/>\n\t\t(PVOID *)&NetworkUsageDumperControlBlock.Worker, NULL);<\/p>\n<p>\tZwClose(ThreadHandle);<\/p>\n<p>\tif (!NT_SUCCESS(Status)) {<br \/>\n\t\tNetworkUsageDumperControlBlock.Exit = TRUE;<br \/>\n\t\tKeSetEvent(&NetworkUsageDumperControlBlock.SleepingEvent, 0, FALSE);<\/p>\n<p>\t\treturn Status;<br \/>\n\t}<\/p>\n<p>\treturn Status;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u7ed3\u675f\u7528\u4e8e\u8f93\u51fa\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u7ebf\u7a0b\u3002<br \/>\n\/\/<\/p>\n<p>VOID TerminateNetworkUsageDumper(<br \/>\n\tVOID<br \/>\n\t)<br \/>\n{<br \/>\n\tPAGED_CODE();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u901a\u77e5\u7ebf\u7a0b\u9000\u51fa\u3002<br \/>\n\t\/\/<\/p>\n<p>\tNetworkUsageDumperControlBlock.Exit = TRUE;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u5524\u9192\u7ebf\u7a0b\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeSetEvent(&NetworkUsageDumperControlBlock.SleepingEvent, 0, TRUE);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u7b49\u5f85\u7ebf\u7a0b\u9000\u51fa\u3002<br \/>\n\t\/\/<\/p>\n<p>\tKeWaitForSingleObject((PVOID)NetworkUsageDumperControlBlock.Worker, Executive, KernelMode,<br \/>\n\t\tFALSE, NULL);<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u7528\u4e8e\u7edf\u8ba1\u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u3002<br \/>\n\/\/<br \/>\n\/\/ \u6b64\u5904\u53ea\u80fd\u5904\u7406 IRP_MJ_INTERNAL_DEVICE_CONTROL \u7c7b\u578b\u7684 IRP\uff0c\u5bf9\u4e8e<br \/>\n\/\/ IRP_MJ_DEVICE_CONTROL\uff0c\u9700\u8981\u4f7f\u7528 TdiMapUserRequest \u5c06\u5176\u6620\u5c04\u4e3a<br \/>\n\/\/ IRP_MJ_INTERNAL_DEVICE_CONTROL \u7c7b\u578b\u7684 IRP\u3002<br \/>\n\/\/<\/p>\n<p>VOID AnalyzeNetworkIrp(<br \/>\n\t__in PIRP Irp<br \/>\n\t)<br \/>\n{<br \/>\n\tPEPROCESS Process;<br \/>\n\tPIO_STACK_LOCATION IoStackLocation;<br \/>\n\tNETWORK_USAGE_INFORMATION NetworkUsageInformation;<\/p>\n<p>\tIoStackLocation = IoGetCurrentIrpStackLocation(Irp);<\/p>\n<p>\tASSERT(IoStackLocation->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL);<\/p>\n<p>\tProcess = PsGetCurrentProcess();<\/p>\n<p>\tif (QueryProcessNetworkUsage(Process, &NetworkUsageInformation) == FALSE) {<\/p>\n<p>\t\t\/\/<br \/>\n\t\t\/\/ \u82e5\u67e5\u8be2\u4e0d\u5230\u5f53\u524d\u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\uff0c\u5219\u8868\u793a\u901a\u7528\u8868\u4e2d\u8fd8\u6ca1\u6709\u8fd9\u4e2a\u8fdb\u7a0b<br \/>\n\t\t\/\/ \u76f8\u5173\u7684\u8868\u9879\uff0c\u90a3\u4e48\u5c31\u5c06\u8be5\u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u521d\u59cb\u5316\u6210 0\u3002<br \/>\n\t\t\/\/<\/p>\n<p>\t\tNetworkUsageInformation.BytesReceived = 0;<br \/>\n\t\tNetworkUsageInformation.BytesSent = 0;<br \/>\n\t}<\/p>\n<p>\tif (IoStackLocation->MinorFunction == TDI_RECEIVE) {<br \/>\n\t\tPTDI_REQUEST_KERNEL_RECEIVE Parameters;<\/p>\n<p>\t\tParameters = (PTDI_REQUEST_KERNEL_RECEIVE)&IoStackLocation->Parameters;<\/p>\n<p>\t\t\/\/<br \/>\n\t\t\/\/ \u7edf\u8ba1\u63a5\u53d7\u7684\u5b57\u8282\u6570\u3002<br \/>\n\t\t\/\/<\/p>\n<p>\t\tNetworkUsageInformation.BytesReceived += Parameters->ReceiveLength;<br \/>\n\t} else if (IoStackLocation->MinorFunction == TDI_SEND) {<br \/>\n\t\tPTDI_REQUEST_KERNEL_SEND Parameters;<\/p>\n<p>\t\tParameters = (PTDI_REQUEST_KERNEL_SEND)&IoStackLocation->Parameters;<\/p>\n<p>\t\t\/\/<br \/>\n\t\t\/\/ \u7edf\u8ba1\u53d1\u9001\u7684\u5b57\u8282\u6570\u3002<br \/>\n\t\t\/\/<\/p>\n<p>\t\tNetworkUsageInformation.BytesSent += Parameters->SendLength;<br \/>\n\t} else if (IoStackLocation->MinorFunction == TDI_RECEIVE_DATAGRAM) {<br \/>\n\t\tPTDI_REQUEST_KERNEL_RECEIVEDG Parameters;<\/p>\n<p>\t\tParameters = (PTDI_REQUEST_KERNEL_RECEIVEDG)&IoStackLocation->Parameters;<\/p>\n<p>\t\t\/\/<br \/>\n\t\t\/\/ \u7edf\u8ba1\u63a5\u53d7\u7684\u5b57\u8282\u6570\u3002<br \/>\n\t\t\/\/<\/p>\n<p>\t\tNetworkUsageInformation.BytesReceived += Parameters->ReceiveLength;<br \/>\n\t} else if (IoStackLocation->MinorFunction == TDI_SEND_DATAGRAM) {<br \/>\n\t\tPTDI_REQUEST_KERNEL_SENDDG Parameters;<\/p>\n<p>\t\tParameters = (PTDI_REQUEST_KERNEL_SENDDG)&IoStackLocation->Parameters;<\/p>\n<p>\t\t\/\/<br \/>\n\t\t\/\/ \u7edf\u8ba1\u53d1\u9001\u7684\u5b57\u8282\u6570\u3002<br \/>\n\t\t\/\/<\/p>\n<p>\t\tNetworkUsageInformation.BytesSent += Parameters->SendLength;<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u66f4\u65b0\u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u3002<br \/>\n\t\/\/<\/p>\n<p>\tUpdateProcessNetworkUsage(Process, &NetworkUsageInformation);<\/p>\n<p>\treturn;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u901a\u7528\u7684\u4f20\u9012 IRP \u5230\u4e0b\u5c42\u9a71\u52a8\u7684\u6d3e\u9063\u51fd\u6570\u3002<br \/>\n\/\/<\/p>\n<p>NTSTATUS GeneralPassthroughDispath(<br \/>\n\t__in PDEVICE_OBJECT DeviceObject,<br \/>\n\t__inout PIRP Irp<br \/>\n\t)<br \/>\n{<br \/>\n\tPDEVICE_OBJECT LowerDeviceObject;<br \/>\n\tPIO_STACK_LOCATION IoStackLocation;<\/p>\n<p>\tASSERT(ATTACHING_DEVICE_EXTENSION(DeviceObject));<\/p>\n<p>\tLowerDeviceObject = ATTACHING_DEVICE_EXTENSION(DeviceObject)->AttachState.AttachedDevice;<\/p>\n<p>\tIoStackLocation = IoGetCurrentIrpStackLocation(Irp);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u5bf9\u4e8e IRP_MJ_DEVICE_CONTROL \u7c7b\u578b\u8bf7\u6c42\uff0c\u5c06\u5176\u8f6c\u6362\u4e3a IRP_MJ_INTERNAL_DEVICE_CONTROL<br \/>\n\t\/\/ \u7c7b\u578b\u540e\u518d\u5904\u7406\u3002<br \/>\n\t\/\/<\/p>\n<p>\tif (IoStackLocation->MajorFunction == IRP_MJ_DEVICE_CONTROL) {<\/p>\n<p>\t\t\/\/<br \/>\n\t\t\/\/ \u82e5\u8f6c\u6362\u5931\u8d25\uff0c\u5219 IRP \u4f9d\u7136\u662f IRP_MJ_DEVICE_CONTROL \u7c7b\u578b\uff0c\u90a3\u4e48\u5c31\u4e0d\u4f1a\u88ab\u63d0\u4ea4\u7ed9<br \/>\n\t\t\/\/ AnalyzeNetworkIrp \u505a\u8fdb\u4e00\u6b65\u5904\u7406\u3002<br \/>\n\t\t\/\/<br \/>\n\t\t\/\/ \u7531\u4e8e\u7a0d\u540e\u4f1a\u518d\u6b21\u5224\u65ad IRP \u7684\u7c7b\u578b\uff0c\u56e0\u6b64\u6b64\u5904\u53ef\u4ee5\u5ffd\u7565 TdiMapUserRequest \u7684\u8fd4\u56de\u503c\u3002<br \/>\n\t\t\/\/<\/p>\n<p>\t\t(VOID)TdiMapUserRequest(DeviceObject, Irp, IoStackLocation);<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u82e5\u662f IRP_MJ_INTERNAL_DEVICE_CONTROL \u7c7b\u578b\u8bf7\u6c42\uff0c\u5219\u8bb0\u5f55\u8fdb\u7a0b\u7684\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u3002<br \/>\n\t\/\/<\/p>\n<p>\tif (IoStackLocation->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) {<br \/>\n\t\tAnalyzeNetworkIrp(Irp);<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u8df3\u8fc7\u5f53\u524d IRP \u53c2\u6570\u6808\u3002<br \/>\n\t\/\/<\/p>\n<p>\tIoSkipCurrentIrpStackLocation(Irp);<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u4e0b\u53d1 IRP\u3002<br \/>\n\t\/\/<\/p>\n<p>\treturn IoCallDriver(LowerDeviceObject, Irp);<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u9a71\u52a8\u5165\u53e3\u70b9\u3002<br \/>\n\/\/<\/p>\n<p>NTSTATUS DriverEntry(<br \/>\n\t__inout PDRIVER_OBJECT DriverObject,<br \/>\n\t__in PUNICODE_STRING RegistryPath<br \/>\n\t)<br \/>\n{<br \/>\n\tULONG MajorFunctionIndex;<br \/>\n\tNTSTATUS Status;<\/p>\n<p>\tFlowWatcherDriverObject = DriverObject;<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u586b\u5145\u56de\u8c03\u8868\u3002<br \/>\n\t\/\/<\/p>\n<p>\tDriverObject->DriverUnload = DriverUnload;<\/p>\n<p>\tfor (MajorFunctionIndex = 0; MajorFunctionIndex <= IRP_MJ_MAXIMUM_FUNCTION;\n\t\tMajorFunctionIndex++) {\n\t\tDriverObject->MajorFunction[MajorFunctionIndex] = GeneralPassthroughDispath;<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u521d\u59cb\u5316\u8bb0\u5f55\u8fdb\u7a0b\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u901a\u7528\u8868\u3002<br \/>\n\t\/\/<\/p>\n<p>\tInitializeNetworkUsageGenericTable();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u9644\u52a0\u5230 TDI \u7684\u8bbe\u5907\u5bf9\u8c61\u4e0a\u3002<br \/>\n\t\/\/<\/p>\n<p>\tStatus = AttachDevices();<\/p>\n<p>\tif (!NT_SUCCESS(Status)) {<br \/>\n\t\treturn Status;<br \/>\n\t}<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u521b\u5efa\u8f93\u51fa\u7f51\u7edc\u4f7f\u7528\u4fe1\u606f\u7684\u7ebf\u7a0b\u3002<br \/>\n\t\/\/<\/p>\n<p>\tStatus = CreateNetworkUsageDumper();<\/p>\n<p>\tif (!NT_SUCCESS(Status)) {<br \/>\n\t\tDetachDevices();<\/p>\n<p>\t\treturn Status;<br \/>\n\t}<\/p>\n<p>\treturn Status;<br \/>\n}<\/p>\n<p>\/\/<br \/>\n\/\/ \u9a71\u52a8\u5378\u8f7d\u56de\u8c03\u3002<br \/>\n\/\/<\/p>\n<p>VOID DriverUnload(<br \/>\n\t__in PDRIVER_OBJECT DriverObject<br \/>\n\t)<br \/>\n{<br \/>\n\tPAGED_CODE();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u7ed3\u675f\u8f93\u51fa\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u7ebf\u7a0b\u3002<br \/>\n\t\/\/<\/p>\n<p>\tTerminateNetworkUsageDumper();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u4ece TDI \u7684\u8bbe\u5907\u5bf9\u8c61\u4e0a\u5206\u79bb\u3002<br \/>\n\t\/\/<\/p>\n<p>\tDetachDevices();<\/p>\n<p>\t\/\/<br \/>\n\t\/\/ \u91ca\u653e\u7528\u4e8e\u7edf\u8ba1\u8fdb\u7a0b\u7f51\u7edc\u4f7f\u7528\u60c5\u51b5\u7684\u901a\u7528\u8868\u3002<br \/>\n\t\/\/<\/p>\n<p>\tDeleteNetworkUsageGenericTable();<\/p>\n<p>\treturn;<br \/>\n}<\/code><\/p>\n<p>Update at 19:24 2012\/8\/21: <\/p>\n<p>\u4f3c\u4e4e\u5e94\u8be5\u5728 IoAttachDevice \u4e4b\u524d\u53bb\u6389 DeviceObject->Flags \u4e2d\u7684 DO_DEVICE_INITIALIZING\uff0c\u540c\u65f6\u8981\u628a TDI \u7684 DeviceObject \u7684 Flags \u590d\u5236\u8fc7\u6765\u3002<br \/>\n\u53e6\u5916\u7528 Timer Object \u8981\u6bd4\u7528 Event \u6765\u7684\u5408\u7406\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u8981\u63a7\u5236\u6d41\u91cf\u5927\u6982\u662f\u5728 IoCompletion \u91cc\u9762\u8fd4\u56de STATUS_MORE_PROCESSING_REQU [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-570","post","type-post","status-publish","format-standard","hentry","category-1"],"_links":{"self":[{"href":"https:\/\/newbiecoder.0ginr.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/570","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/newbiecoder.0ginr.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/newbiecoder.0ginr.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/newbiecoder.0ginr.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/newbiecoder.0ginr.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=570"}],"version-history":[{"count":6,"href":"https:\/\/newbiecoder.0ginr.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/570\/revisions"}],"predecessor-version":[{"id":672,"href":"https:\/\/newbiecoder.0ginr.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/570\/revisions\/672"}],"wp:attachment":[{"href":"https:\/\/newbiecoder.0ginr.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/newbiecoder.0ginr.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/newbiecoder.0ginr.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}