Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1597 lines
42 KiB

  1. /*********************************************************************/
  2. /** Microsoft Generic Packet Scheduler **/
  3. /** Copyright(c) Microsoft Corp., 1996-1997 **/
  4. /********************************************************************/
  5. #ifndef __GPCDEF
  6. #define __GPCDEF
  7. //*** gpcdef.h - GPC internal definitions & prototypes
  8. //
  9. // This file containes all the GPC data structures & defines
  10. /*
  11. /////////////////////////////////////////////////////////////////
  12. //
  13. // defines
  14. //
  15. /////////////////////////////////////////////////////////////////
  16. */
  17. //
  18. // Max number of clients per blob (same CF)
  19. //
  20. // AbhisheV - This can not be more than sizeof(ULONG)*8.
  21. //
  22. #define MAX_CLIENTS_CTX_PER_BLOB 32
  23. //
  24. // Max pattern size,
  25. // GPC_IP_PATTERN = 24 bytes
  26. // GPC_IPX_PATTERN = 24 bytes
  27. //
  28. #define MAX_PATTERN_SIZE sizeof(GPC_IP_PATTERN)
  29. extern BOOLEAN IsItChanging;
  30. //
  31. // Pattern flags
  32. //
  33. #define PATTERN_SPECIFIC 0x00000001
  34. #define PATTERN_AUTO 0x00000002
  35. #define PATTERN_REMOVE_CB_BLOB 0x00000004
  36. // Following flag to be set and unset only in addspecificpatternwithtimer.
  37. // It indicates pattern has been created but not on timer list yet.
  38. // It is set before inserting it into the hash table i.e calling
  39. // AddSpecificPattern.
  40. // It is supposed to be reset after putting pattern on timer list
  41. // which in turn should occur after the pattern has been added into
  42. // the hash table i.e. a successful call to addspecificpattern
  43. #define PATTERN_AUTO_NOT_READY 0x00000008
  44. //
  45. // Auto Pattern defines
  46. //
  47. // Every PATTERN_TIMEOUT seconds, the PatternTimerExpiry Routine gets called.
  48. #define PATTERN_TIMEOUT 60000 // 60 seconds
  49. // This is the amount of time that a Pattern created for optimization
  50. // lives on the Pattern List.
  51. #define AUTO_PATTERN_ENTRY_TIMEOUT 300000 // 5 minutes
  52. // This is the number of timer granularity.
  53. #define NUMBER_OF_WHEELS (AUTO_PATTERN_ENTRY_TIMEOUT/PATTERN_TIMEOUT)
  54. //
  55. // The size of structure to be allocated for TCP query with 1 address
  56. #define ROUTING_INFO_ADDR_1_SIZE \
  57. FIELD_OFFSET(GPC_TCP_QUERY_CONTEXT ,RouteInfo) + \
  58. FIELD_OFFSET(TDI_ROUTING_INFO, Address) + \
  59. FIELD_OFFSET(TRANSPORT_ADDRESS, Address) + \
  60. FIELD_OFFSET(TA_ADDRESS, Address) + sizeof(TDI_ADDRESS_IP)
  61. //
  62. // For 2 addresses
  63. #define ROUTING_INFO_ADDR_2_SIZE ROUTING_INFO_ADDR_1_SIZE + \
  64. FIELD_OFFSET(TA_ADDRESS, Address) + sizeof(TDI_ADDRESS_IP)
  65. // New debug locks [ShreeM]
  66. // This will enable us to figure out who took the lock last
  67. // and who released it last. New structure defined below and
  68. // lock_acquire and lock_release macros are redefined later.
  69. typedef struct _GPC_LOCK {
  70. NDIS_SPIN_LOCK Lock;
  71. #if DBG
  72. PETHREAD CurrentThread;
  73. KIRQL CurrentIRQL;
  74. LONG LockAcquired; // is it current held?
  75. UCHAR LastAcquireFile[8];
  76. ULONG LastAcquireLine;
  77. UCHAR LastReleaseFile[8];
  78. ULONG LastReleaseLine;
  79. #endif
  80. } GPC_LOCK, PGPC_LOCK;
  81. //
  82. //
  83. // states for blobs, patterns and more
  84. //
  85. typedef enum {
  86. GPC_STATE_READY = 0,
  87. GPC_STATE_INIT,
  88. GPC_STATE_ADD,
  89. GPC_STATE_MODIFY,
  90. GPC_STATE_REMOVE,
  91. GPC_STATE_FORCE_REMOVE,
  92. GPC_STATE_DELETE,
  93. GPC_STATE_INVALID,
  94. GPC_STATE_NOTREADY,
  95. GPC_STATE_ERROR,
  96. GPC_STATE_PENDING
  97. } GPC_STATE;
  98. //
  99. // ObjectVerification macro
  100. //
  101. #define VERIFY_OBJECT(_obj, _val) if(_obj) \
  102. {if(*(GPC_ENUM_OBJECT_TYPE *)_obj!=_val) return STATUS_INVALID_HANDLE;}
  103. //Use this macro when you want to catch the error and not directly
  104. //return from the function
  105. #define VERIFY_OBJECT_WITH_STATUS(_obj, _val,__status) if(_obj) \
  106. {if(*(GPC_ENUM_OBJECT_TYPE *)_obj!=_val) __status = STATUS_INVALID_HANDLE;}
  107. //
  108. // define event log error codes
  109. //
  110. #define GPC_ERROR_INIT_MAIN 0x00010000
  111. #define GPC_ERROR_INIT_IOCTL 0x00020000
  112. #define GPC_FLAGS_USERMODE_CLIENT 0x80000000
  113. #define IS_USERMODE_CLIENT(_pc) \
  114. TEST_BIT_ON((_pc)->Flags,GPC_FLAGS_USERMODE_CLIENT)
  115. #define IS_USERMODE_CLIENT_EX(_pc) \
  116. TEST_BIT_ON((_pc)->Flags,GPC_FLAGS_USERMODE_CLIENT_EX)
  117. //
  118. // for ioctl
  119. //
  120. #define SHUTDOWN_DELETE_DEVICE 0x00000100
  121. #define SHUTDOWN_DELETE_SYMLINK 0x00000200
  122. //
  123. // helper macros
  124. //
  125. #define TEST_BIT_ON(_v,_b) (((_v)&(_b))==(_b))
  126. #define TEST_BIT_OFF(_v,_b) (((_v)&(_b))==0)
  127. //
  128. // Define Default AutoPatternLimits
  129. //
  130. #define DEFAULT_SMALL_SYSTEM_AUTO_PATTERN_LIMIT 2000
  131. #define DEFAULT_MEDIUM_SYSTEM_AUTO_PATTERN_LIMIT 8000
  132. #define DEFAULT_LARGE_SYSTEM_AUTO_PATTERN_LIMIT 12000
  133. //
  134. // Define Registry settings to read into
  135. //
  136. #define GPC_REG_KEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\GPC"
  137. //
  138. // Work Buffer size for reading from the registry
  139. //
  140. #define WORK_BUFFER_SIZE 256
  141. //
  142. // Reg Key under which the limit on the number of autopatterns is stored
  143. //
  144. #define GPC_REG_AUTO_PATTERN_LIMIT L"AutoPatternLimit"
  145. #define GPC_AUTO_PATTERN_MIN 2000
  146. #define GPC_AUTO_PATTERN_MAX 20000
  147. #if DBG
  148. #define NDIS_INIT_LOCK(_sl) {\
  149. NdisAllocateSpinLock(&(_sl)->Lock); \
  150. TRACE(LOCKS,(_sl),(_sl)->Lock.OldIrql,"LOCK");\
  151. (_sl)->LockAcquired = -1; \
  152. strncpy((_sl)->LastAcquireFile, strrchr(__FILE__,'\\')+1, 7); \
  153. (_sl)->LastAcquireLine = __LINE__; \
  154. strncpy((_sl)->LastReleaseFile, strrchr(__FILE__,'\\')+1, 7); \
  155. (_sl)->LastReleaseLine = __LINE__; \
  156. (_sl)->CurrentIRQL = KeGetCurrentIrql(); \
  157. (_sl)->CurrentThread = PsGetCurrentThread(); \
  158. }
  159. #define NDIS_LOCK(_sl) {\
  160. NdisAcquireSpinLock(&(_sl)->Lock);\
  161. TRACE(LOCKS,(_sl),(_sl)->Lock.OldIrql,"LOCK");\
  162. (_sl)->LockAcquired = TRUE; \
  163. strncpy((_sl)->LastAcquireFile, strrchr(__FILE__,'\\')+1, 7); \
  164. (_sl)->LastAcquireLine = __LINE__; \
  165. (_sl)->CurrentIRQL = KeGetCurrentIrql(); \
  166. (_sl)->CurrentThread = PsGetCurrentThread(); \
  167. }
  168. #define NDIS_UNLOCK(_sl) {\
  169. (_sl)->LockAcquired = FALSE; \
  170. strncpy((_sl)->LastReleaseFile, strrchr(__FILE__,'\\')+1, 7); \
  171. (_sl)->LastReleaseLine = __LINE__; \
  172. TRACE(LOCKS,(_sl),(_sl)->Lock.OldIrql,"UNLOCK");\
  173. NdisReleaseSpinLock(&(_sl)->Lock);\
  174. }
  175. #define NDIS_DPR_LOCK(_sl) {\
  176. NdisDprAcquireSpinLock(&(_sl)->Lock);\
  177. TRACE(LOCKS,(_sl),(_sl)->Lock.OldIrql,"DPR_LOCK");\
  178. (_sl)->LockAcquired = TRUE; \
  179. strncpy((_sl)->LastAcquireFile, strrchr(__FILE__,'\\')+1, 7); \
  180. (_sl)->LastAcquireLine = __LINE__; \
  181. (_sl)->CurrentIRQL = KeGetCurrentIrql(); \
  182. (_sl)->CurrentThread = PsGetCurrentThread(); \
  183. }
  184. #define NDIS_DPR_UNLOCK(_sl) {\
  185. (_sl)->LockAcquired = FALSE; \
  186. strncpy((_sl)->LastReleaseFile, strrchr(__FILE__,'\\')+1, 7); \
  187. (_sl)->LastReleaseLine = __LINE__; \
  188. TRACE(LOCKS,(_sl),(_sl)->Lock.OldIrql,"DPR_UNLOCK");\
  189. NdisDprReleaseSpinLock(&(_sl)->Lock);\
  190. }
  191. #else
  192. #define NDIS_INIT_LOCK(_sl) NdisAllocateSpinLock(&(_sl)->Lock)
  193. #define NDIS_LOCK(_sl) NdisAcquireSpinLock(&(_sl)->Lock)
  194. #define NDIS_UNLOCK(_sl) NdisReleaseSpinLock(&(_sl)->Lock)
  195. #define NDIS_DPR_LOCK(_sl) NdisDprAcquireSpinLock(&(_sl)->Lock)
  196. #define NDIS_DPR_UNLOCK(_sl) NdisDprReleaseSpinLock(&(_sl)->Lock)
  197. #endif
  198. #if DBG && EXTRA_DBG
  199. #define VERIFY_LIST(_l) DbgVerifyList(_l)
  200. #else
  201. #define VERIFY_LIST(_l)
  202. #endif
  203. #define GpcRemoveEntryList(_pl) {PLIST_ENTRY _q = (_pl)->Flink;VERIFY_LIST(_pl);RemoveEntryList(_pl);InitializeListHead(_pl);VERIFY_LIST(_q);}
  204. #define GpcInsertTailList(_l,_e) VERIFY_LIST(_l);InsertTailList(_l,_e);VERIFY_LIST(_e)
  205. #define GpcInsertHeadList(_l,_e) VERIFY_LIST(_l);InsertHeadList(_l,_e);VERIFY_LIST(_e)
  206. #if 0
  207. #define GpcInterlockedInsertTailList(_l,_e,_s) \
  208. NdisInterlockedInsertTailList(_l,_e,_s)
  209. #else
  210. #define GpcInterlockedInsertTailList(_l,_e,_s) \
  211. {NDIS_LOCK(_s);VERIFY_LIST(_l);InsertTailList(_l,_e);VERIFY_LIST(_l);NDIS_UNLOCK(_s);}
  212. #endif
  213. #if NEW_MRSW
  214. #define INIT_LOCK InitializeMRSWLock
  215. #define READ_LOCK EnterReader
  216. #define READ_UNLOCK ExitReader
  217. #define WRITE_LOCK EnterWriter
  218. #define WRITE_UNLOCK ExitWriter
  219. #else
  220. #define INIT_LOCK InitializeMRSWLock
  221. #define READ_LOCK AcquireReadLock
  222. #define READ_UNLOCK ReleaseReadLock
  223. #define WRITE_LOCK AcquireWriteLock
  224. #define WRITE_UNLOCK ReleaseWriteLock
  225. #endif
  226. //
  227. // Get the CF index from the client block
  228. //
  229. #define GetCFIndexFromClient(_cl) (((PCLIENT_BLOCK)(_cl))->pCfBlock->AssignedIndex)
  230. //
  231. // Get the client index from the client block
  232. //
  233. #define GetClientIndexFromClient(_cl) (((PCLIENT_BLOCK)(_cl))->AssignedIndex)
  234. //
  235. // return the blob block pointer for the pattern:
  236. // for specific patterns - its the blob entry in the CB
  237. // for generic patterns - its the pBlobBlock
  238. //
  239. #define GetBlobFromPattern(_p,_i) (_p)->arpBlobBlock[_i]
  240. //
  241. // return the index bit to the ULONG
  242. //
  243. #define ReleaseClientIndex(_v,_i) _v&=~(1<<_i) // clear the bit
  244. //
  245. // statistics macros
  246. //
  247. #define StatInc(_m) (glStat._m)++
  248. #define StatDec(_m) (glStat._m)--
  249. #define CfStatInc(_cf,_m) (glStat.CfStat[_cf]._m)++
  250. #define CfStatDec(_cf,_m) (glStat.CfStat[_cf]._m)--
  251. #define ProtocolStatInc(_p,_m) (glStat.ProtocolStat[_p]._m)++
  252. #define ProtocolStatDec(_p,_m) (glStat.ProtocolStat[_p]._m)--
  253. /*
  254. /////////////////////////////////////////////////////////////////
  255. //
  256. // typedef
  257. //
  258. /////////////////////////////////////////////////////////////////
  259. */
  260. //
  261. // completion opcodes
  262. //
  263. typedef enum {
  264. OP_ANY_CFINFO,
  265. OP_ADD_CFINFO,
  266. OP_MODIFY_CFINFO,
  267. OP_REMOVE_CFINFO
  268. } GPC_COMPLETION_OP;
  269. //
  270. // define object type enum for handle verification
  271. //
  272. typedef enum {
  273. GPC_ENUM_INVALID,
  274. GPC_ENUM_CLIENT_TYPE,
  275. GPC_ENUM_CFINFO_TYPE,
  276. GPC_ENUM_PATTERN_TYPE
  277. } GPC_ENUM_OBJECT_TYPE;
  278. typedef struct _CF_BLOCK CF_BLOCK;
  279. typedef struct _PATTERN_BLOCK PATTERN_BLOCK;
  280. //
  281. // A queued notification structure
  282. //
  283. typedef struct _QUEUED_NOTIFY {
  284. LIST_ENTRY Linkage;
  285. GPC_NOTIFY_REQUEST_RES NotifyRes;
  286. PFILE_OBJECT FileObject;
  287. } QUEUED_NOTIFY, *PQUEUED_NOTIFY;
  288. //
  289. // A queued completion structure
  290. //
  291. typedef struct _QUEUED_COMPLETION {
  292. GPC_COMPLETION_OP OpCode; // what completed
  293. GPC_HANDLE ClientHandle;
  294. GPC_HANDLE CfInfoHandle;
  295. GPC_STATUS Status;
  296. } QUEUED_COMPLETION, *PQUEUED_COMPLETION;
  297. //
  298. // A pending IRP structure
  299. //
  300. typedef struct _PENDING_IRP {
  301. LIST_ENTRY Linkage;
  302. PIRP Irp;
  303. PFILE_OBJECT FileObject;
  304. QUEUED_COMPLETION QComp;
  305. } PENDING_IRP, *PPENDING_IRP;
  306. #if NEW_MRSW
  307. //
  308. // Multiple Readers Single Write definitions
  309. // code has been taken from (tdi\tcpipmerge\ip\ipmlock.h)
  310. //
  311. typedef struct _MRSW_LOCK
  312. {
  313. KSPIN_LOCK rlReadLock;
  314. KSPIN_LOCK rlWriteLock;
  315. LONG lReaderCount;
  316. } MRSW_LOCK, *PMRSW_LOCK;
  317. #else
  318. //
  319. // Multiple Readers Single Write definitions
  320. // code has been taken from the filter driver project (routing\ip\fltrdrvr)
  321. //
  322. typedef struct _MRSW_LOCK
  323. {
  324. KSPIN_LOCK SpinLock;
  325. LONG ReaderCount;
  326. } MRSW_LOCK, *PMRSW_LOCK;
  327. #endif
  328. //
  329. // The generic pattern database struct
  330. //
  331. typedef struct _GENERIC_PATTERN_DB {
  332. MRSW_LOCK Lock;
  333. Rhizome *pRhizome; // pointer to a Rhizome
  334. } GENERIC_PATTERN_DB, *PGENERIC_PATTERN_DB;
  335. //
  336. // A client block is used to store specific client context
  337. //
  338. typedef struct _CLIENT_BLOCK {
  339. //
  340. // !!! MUST BE FIRST FIELD !!!
  341. //
  342. GPC_ENUM_OBJECT_TYPE ObjectType;
  343. LIST_ENTRY ClientLinkage; // client blocks list link
  344. LIST_ENTRY BlobList; // list of blobs of the client
  345. CF_BLOCK *pCfBlock;
  346. GPC_CLIENT_HANDLE ClientCtx;
  347. ULONG AssignedIndex;
  348. ULONG Flags;
  349. ULONG State;
  350. GPC_LOCK Lock;
  351. REF_CNT RefCount;
  352. PFILE_OBJECT pFileObject; // used for async completion
  353. GPC_HANDLE ClHandle; // handle returned to the client
  354. GPC_CLIENT_FUNC_LIST FuncList;
  355. } CLIENT_BLOCK, *PCLIENT_BLOCK;
  356. //
  357. // A blob (A.K.A CF_INFO) block holds a GPC header + client specific data
  358. //
  359. typedef struct _BLOB_BLOCK {
  360. //
  361. // !!! MUST BE FIRST FIELD !!!
  362. //
  363. GPC_ENUM_OBJECT_TYPE ObjectType;
  364. LIST_ENTRY ClientLinkage; // linked on the client
  365. LIST_ENTRY PatternList; // head of pattern linked list
  366. LIST_ENTRY CfLinkage; // blobs on the CF
  367. //PCLIENT_BLOCK pClientBlock; // pointer to installer
  368. REF_CNT RefCount;
  369. GPC_STATE State;
  370. ULONG Flags;
  371. GPC_CLIENT_HANDLE arClientCtx[MAX_CLIENTS_CTX_PER_BLOB];
  372. ULONG ClientStatusCountDown;
  373. GPC_STATUS LastStatus;
  374. GPC_LOCK Lock;
  375. CTEBlockStruc WaitBlockAddFailed;
  376. PCLIENT_BLOCK arpClientStatus[MAX_CLIENTS_CTX_PER_BLOB];
  377. ULONG ClientDataSize;
  378. PVOID pClientData;
  379. ULONG NewClientDataSize;
  380. PVOID pNewClientData;
  381. PCLIENT_BLOCK pOwnerClient;
  382. PCLIENT_BLOCK pCallingClient;
  383. PCLIENT_BLOCK pCallingClient2;
  384. HANDLE OwnerClientHandle;
  385. GPC_CLIENT_HANDLE OwnerClientCtx;
  386. GPC_HANDLE ClHandle; // handle returned to the client
  387. // New fields to keep track of the additional information
  388. //
  389. // Rules:
  390. // (1) FileObject is referenced if NOT NULL
  391. // (2) Pattern needs to be freed if NOT NULL; should be used for AddPattern
  392. //
  393. PFILE_OBJECT FileObject;
  394. PGPC_IP_PATTERN Pattern;
  395. //
  396. //
  397. // assume only one client can accept the flow
  398. //
  399. PCLIENT_BLOCK pNotifiedClient;
  400. GPC_CLIENT_HANDLE NotifiedClientCtx;
  401. #if NO_USER_PENDING
  402. CTEBlockStruc WaitBlock;
  403. #endif
  404. } BLOB_BLOCK, *PBLOB_BLOCK;
  405. //
  406. // The classification block is an array of blob pointers
  407. //
  408. typedef struct _CLASSIFICATION_BLOCK {
  409. REF_CNT RefCount;
  410. ULONG NumberOfElements;
  411. HFHandle ClassificationHandle; // how to get back to index tbl
  412. // must be last
  413. PBLOB_BLOCK arpBlobBlock[1];
  414. } CLASSIFICATION_BLOCK, *PCLASSIFICATION_BLOCK;
  415. //
  416. // A pattern block holds specific data for the pattern
  417. //
  418. typedef struct _PATTERN_BLOCK {
  419. //
  420. // !!! MUST BE FIRST FIELD !!!
  421. //
  422. GPC_ENUM_OBJECT_TYPE ObjectType;
  423. GPC_STATE State;
  424. LIST_ENTRY BlobLinkage[GPC_CF_MAX]; // linked on the blob
  425. LIST_ENTRY TimerLinkage;
  426. PBLOB_BLOCK arpBlobBlock[GPC_CF_MAX];
  427. PCLIENT_BLOCK pClientBlock;
  428. PCLIENT_BLOCK pAutoClient;
  429. PCLASSIFICATION_BLOCK pClassificationBlock;
  430. ULONG WheelIndex;
  431. REF_CNT RefCount;
  432. ULONG ClientRefCount;
  433. ULONG TimeToLive; // for internal patterns
  434. ULONG Flags;
  435. ULONG Priority; // for generic pattern
  436. PVOID DbCtx;
  437. GPC_LOCK Lock;
  438. GPC_HANDLE ClHandle; // handle returned to the client
  439. ULONG ProtocolTemplate;
  440. } PATTERN_BLOCK, *PPATTERN_BLOCK;
  441. //
  442. // A CF block struct. This would construct a linked list of Cf blocks.
  443. //
  444. typedef struct _CF_BLOCK {
  445. REF_CNT RefCount;
  446. LIST_ENTRY Linkage; // on the global list
  447. LIST_ENTRY ClientList; // for the client blocks
  448. LIST_ENTRY BlobList; // list of blobs
  449. ULONG NumberOfClients;
  450. ULONG AssignedIndex;
  451. ULONG ClientIndexes;
  452. GPC_LOCK Lock;
  453. //MRSW_LOCK ClientSync;
  454. GPC_LOCK ClientSync;
  455. ULONG MaxPriorities;
  456. PGENERIC_PATTERN_DB arpGenericDb[GPC_PROTOCOL_TEMPLATE_MAX];
  457. } CF_BLOCK, *PCF_BLOCK;
  458. typedef struct _SPECIFIC_PATTERN_DB {
  459. MRSW_LOCK Lock;
  460. PatHashTable *pDb;
  461. } SPECIFIC_PATTERN_DB, *PSPECIFIC_PATTERN_DB;
  462. typedef struct _FRAGMENT_DB {
  463. MRSW_LOCK Lock;
  464. PatHashTable *pDb;
  465. } FRAGMENT_DB, *PFRAGMENT_DB;
  466. //
  467. // A context structure to pass to the pathash scan routine
  468. //
  469. typedef struct _SCAN_STRUCT {
  470. PCLIENT_BLOCK pClientBlock;
  471. PPATTERN_BLOCK pPatternBlock;
  472. PBLOB_BLOCK pBlobBlock;
  473. ULONG Priority;
  474. BOOLEAN bRemove;
  475. } SCAN_STRUCT, *PSCAN_STRUCT;
  476. //
  477. // A protocol block holds pointers to databases for a specific
  478. // protocol template
  479. //
  480. typedef struct _PROTOCOL_BLOCK {
  481. LIST_ENTRY TimerPatternList[NUMBER_OF_WHEELS];
  482. ULONG CurrentWheelIndex;
  483. ULONG SpecificPatternCount;
  484. ULONG GenericPatternCount;
  485. ULONG AutoSpecificPatternCount;
  486. ULONG ProtocolTemplate;
  487. ULONG PatternSize;
  488. SPECIFIC_PATTERN_DB SpecificDb;
  489. PVOID pProtocolDb; // fragments
  490. GPC_LOCK PatternTimerLock[NUMBER_OF_WHEELS];
  491. NDIS_TIMER PatternTimer;
  492. } PROTOCOL_BLOCK, *PPROTOCOL_BLOCK;
  493. //
  494. // Global data block
  495. //
  496. typedef struct _GLOBAL_BLOCK {
  497. LIST_ENTRY CfList; // CF list head
  498. LIST_ENTRY gRequestList; // Maintain a request list to deal with contention...
  499. GPC_LOCK Lock;
  500. GPC_LOCK RequestListLock;
  501. HandleFactory *pCHTable; // Hash table maps user mode handle to kmode pointer
  502. MRSW_LOCK ChLock; // lock for pCHTable
  503. PPROTOCOL_BLOCK pProtocols; // pointer to array of supported protocols
  504. MM_SYSTEMSIZE SystemSizeHint;
  505. ULONG AutoPatternLimit;
  506. } GLOBAL_BLOCK, *PGLOBAL_BLOCK;
  507. //
  508. // TCP Query Context . Allocated before calling TcpQueryInfo.
  509. // When calling TcpQueryInfo only pass Offset into this structure
  510. // pointing at RouteInfo.
  511. // into TCP.
  512. // Initialize the TcpPattern with remote address and remote port
  513. // before the call and check on call completion if the values are
  514. // of relevance : this will happen when protocol = UDP and stack
  515. // gives us only one IP address on TcpQueryInfo call completion
  516. //
  517. typedef struct _GPC_TCP_QUERY_CONTEXT
  518. {
  519. PGPC_IP_PATTERN pTcpPattern;
  520. PMDL pMdl;
  521. //This should be the last field
  522. //ROUTING_INFO_ADDR_1_SIZE
  523. //depends on that
  524. TDI_ROUTING_INFO RouteInfo;
  525. } GPC_TCP_QUERY_CONTEXT, *PGPC_TCP_QUERY_CONTEXT;
  526. //
  527. // New request block. This will be used to store the event and linkage.
  528. // Therefore, when a thread needs to block, allocate a request_block, allocate
  529. // an event, grab the requestlist lock , put this on the list and wait.
  530. //
  531. typedef struct _REQUEST_BLOCK {
  532. LIST_ENTRY Linkage;
  533. NDIS_EVENT RequestEvent;
  534. } REQUEST_BLOCK, *PREQUEST_BLOCK;
  535. #if NEW_MRSW
  536. //
  537. // VOID
  538. // InitRwLock(
  539. // PMRSW_LOCK pLock
  540. // )
  541. //
  542. // Initializes the spin locks and the reader count
  543. //
  544. #define InitializeMRSWLock(l) { \
  545. KeInitializeSpinLock(&((l)->rlReadLock)); \
  546. KeInitializeSpinLock(&((l)->rlWriteLock)); \
  547. (l)->lReaderCount = 0; \
  548. }
  549. //
  550. // VOID
  551. // EnterReader(
  552. // PMRSW_LOCK pLock,
  553. // PKIRQL pCurrIrql
  554. // )
  555. //
  556. // Acquires the Reader Spinlock (now thread is at DPC).
  557. // InterlockedIncrements the reader count (interlocked because the reader
  558. // lock is not taken when the count is decremented in ExitReader())
  559. // If the thread is the first reader, also acquires the Writer Spinlock (at
  560. // DPC to be more efficient) to block writers
  561. // Releases the Reader Spinlock from DPC, so that it remains at DPC
  562. // for the duration of the lock being held
  563. //
  564. // If a writer is in the code, the first reader will wait on the Writer
  565. // Spinlock and all subsequent readers will wait on the Reader Spinlock
  566. // If a reader is in the code and is executing the EnterReader, then a new
  567. // reader will wait for sometime on the Reader Spinlock, and then proceed
  568. // on to the code (at DPC)
  569. //
  570. #define EnterReader(l, q) {\
  571. KeAcquireSpinLock(&((l)->rlReadLock), (q)); \
  572. TRACE(LOCKS,l,*q,"EnterReader"); \
  573. if(InterlockedIncrement(&((l)->lReaderCount)) == 1) { \
  574. TRACE(LOCKS,l,(l)->lReaderCount,"EnterReader1"); \
  575. KeAcquireSpinLockAtDpcLevel(&((l)->rlWriteLock)); \
  576. TRACE(LOCKS,l,(l)->rlWriteLock,"EnterReader2"); \
  577. } \
  578. TRACE(LOCKS,l,(l)->lReaderCount,"EnterReader3"); \
  579. KeReleaseSpinLockFromDpcLevel(&((l)->rlReadLock)); \
  580. }
  581. #define EnterReaderAtDpcLevel(l) {\
  582. KeAcquireSpinLockAtDpcLevel(&((l)->rlReadLock)); \
  583. if(InterlockedIncrement(&((l)->lReaderCount)) == 1) \
  584. KeAcquireSpinLockAtDpcLevel(&((l)->rlWriteLock)); \
  585. KeReleaseSpinLockFromDpcLevel(&((l)->rlReadLock)); \
  586. }
  587. //
  588. // VOID
  589. // ExitReader(
  590. // PMRSW_LOCK pLock,
  591. // KIRQL kiOldIrql
  592. // )
  593. //
  594. // InterlockedDec the reader count.
  595. // If this is the last reader, then release the Writer Spinlock to let
  596. // other writers in
  597. // Otherwise, just lower the irql to what was before the lock was
  598. // acquired. Either way, the irql is down to original irql
  599. //
  600. #define ExitReader(l, q) {\
  601. TRACE(LOCKS,l,q,"ExitReader");\
  602. if(InterlockedDecrement(&((l)->lReaderCount)) == 0) { \
  603. TRACE(LOCKS,(l)->rlWriteLock,q,"ExitReader1"); \
  604. KeReleaseSpinLock(&((l)->rlWriteLock), q); \
  605. } \
  606. else { \
  607. TRACE(LOCKS,l,(l)->lReaderCount,"ExitReader2"); \
  608. KeLowerIrql(q); \
  609. } \
  610. }
  611. #define ExitReaderFromDpcLevel(l) {\
  612. if(InterlockedDecrement(&((l)->lReaderCount)) == 0) \
  613. KeReleaseSpinLockFromDpcLevel(&((l)->rlWriteLock)); \
  614. }
  615. //
  616. // EnterWriter(
  617. // PMRSW_LOCK pLock,
  618. // PKIRQL pCurrIrql
  619. // )
  620. //
  621. // Acquire the reader and then the writer spin lock
  622. // If there are readers in the code, the first writer will wait
  623. // on the Writer Spinlock. All other writers will wait (with readers)
  624. // on the Reader Spinlock
  625. // If there is a writer in the code then a new writer will wait on
  626. // the Reader Spinlock
  627. #define EnterWriter(l, q) {\
  628. KeAcquireSpinLock(&((l)->rlReadLock), (q)); \
  629. TRACE(LOCKS,l,*q,"EnterWriter"); \
  630. TRACE(LOCKS,l,(l)->rlWriteLock,"EnterWrite1"); \
  631. KeAcquireSpinLockAtDpcLevel(&((l)->rlWriteLock)); \
  632. }
  633. #define EnterWriterAtDpcLevel(l) { \
  634. KeAcquireSpinLockAtDpcLevel(&((l)->rlReadLock)); \
  635. KeAcquireSpinLockAtDpcLevel(&((l)->rlWriteLock)); \
  636. }
  637. //
  638. // ExitWriter(
  639. // PMRSW_LOCK pLock,
  640. // KIRQL kiOldIrql
  641. // )
  642. //
  643. // Release both the locks
  644. //
  645. #define ExitWriter(l, q) {\
  646. TRACE(LOCKS,l,(l)->rlWriteLock,"ExitWrite1"); \
  647. KeReleaseSpinLockFromDpcLevel(&((l)->rlWriteLock)); \
  648. TRACE(LOCKS,l,q,"ExitWrite1"); \
  649. KeReleaseSpinLock(&((l)->rlReadLock), q); \
  650. }
  651. #define ExitWriterFromDpcLevel(l) {\
  652. KeReleaseSpinLockFromDpcLevel(&((l)->rlWriteLock)); \
  653. KeReleaseSpinLockFromDpcLevel(&((l)->rlReadLock)); \
  654. }
  655. #else
  656. #define InitializeMRSWLock(_pLock) { \
  657. (_pLock)->ReaderCount = 0; \
  658. KeInitializeSpinLock(&((_pLock)->SpinLock)); \
  659. }
  660. #define AcquireReadLock(_pLock,_pOldIrql) { \
  661. TRACE(LOCKS, _pLock, (_pLock)->ReaderCount, "RL.1"); \
  662. KeAcquireSpinLock(&((_pLock)->SpinLock),_pOldIrql); \
  663. InterlockedIncrement(&((_pLock)->ReaderCount)); \
  664. TRACE(LOCKS, _pLock, (_pLock)->ReaderCount, "RL.2"); \
  665. KeReleaseSpinLockFromDpcLevel(&((_pLock)->SpinLock)); \
  666. TRACE(LOCKS, _pLock, *(_pOldIrql), "RL.3"); \
  667. }
  668. #define ReleaseReadLock(_pLock,_OldIrql) { \
  669. TRACE(LOCKS, _pLock, (_pLock)->ReaderCount, "RU.1"); \
  670. InterlockedDecrement(&((_pLock)->ReaderCount)); \
  671. TRACE(LOCKS, _pLock, (_pLock)->ReaderCount, "RU.2"); \
  672. KeLowerIrql(_OldIrql); \
  673. TRACE(LOCKS, _pLock, _OldIrql, "RU.3"); \
  674. }
  675. #define AcquireWriteLock(_pLock,_pOldIrql) { \
  676. TRACE(LOCKS, _pLock, _pOldIrql, "WL.1"); \
  677. KeAcquireSpinLock(&((_pLock)->SpinLock),_pOldIrql); \
  678. TRACE(LOCKS, _pLock, (_pLock)->ReaderCount, "WL.2"); \
  679. while(InterlockedDecrement(&((_pLock)->ReaderCount))>=0)\
  680. { \
  681. InterlockedIncrement (&((_pLock)->ReaderCount)); \
  682. } \
  683. TRACE(LOCKS, _pLock, (_pLock)->ReaderCount, "WL.3"); \
  684. }
  685. #define ReleaseWriteLock(_pLock,_OldIrql) { \
  686. TRACE(LOCKS, _pLock, (_pLock)->ReaderCount, "WU.1"); \
  687. InterlockedExchange(&(_pLock)->ReaderCount,0); \
  688. TRACE(LOCKS, _pLock, (_pLock)->ReaderCount, "WU.2"); \
  689. KeReleaseSpinLock(&((_pLock)->SpinLock),_OldIrql); \
  690. TRACE(LOCKS, _pLock, _OldIrql, "WU.3"); \
  691. }
  692. #endif
  693. #if 1
  694. #define RSC_READ_LOCK(_l,_i) NDIS_LOCK(_l)
  695. #define RSC_READ_UNLOCK(_l,_i) NDIS_UNLOCK(_l)
  696. #define RSC_WRITE_LOCK(_l,_i) NDIS_LOCK(_l)
  697. #define RSC_WRITE_UNLOCK(_l,_i) NDIS_UNLOCK(_l)
  698. #else
  699. #define RSC_READ_LOCK WRITE_LOCK
  700. #define RSC_READ_UNLOCK WRITE_UNLOCK
  701. #define RSC_WRITE_LOCK WRITE_LOCK
  702. #define RSC_WRITE_UNLOCK WRITE_UNLOCK
  703. #endif
  704. /*
  705. /////////////////////////////////////////////////////////////////
  706. //
  707. // IP definitions
  708. //
  709. /////////////////////////////////////////////////////////////////
  710. */
  711. #define DEFAULT_VERLEN 0x45 // Default version and length.
  712. #define IP_VERSION 0x40
  713. #define IP_VER_FLAG 0xF0
  714. #define IP_RSVD_FLAG 0x0080 // Reserved.
  715. #define IP_DF_FLAG 0x0040 // 'Don't fragment' flag
  716. #define IP_MF_FLAG 0x0020 // 'More fragments flag'
  717. #define IP_OFFSET_MASK ~0x00E0 // Mask for extracting offset field.
  718. #if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175))
  719. #define net_short(_x) _byteswap_ushort((USHORT)(_x))
  720. #define net_long(_x) _byteswap_ulong(_x)
  721. #else
  722. #define net_short(x) ((((x)&0xff) << 8) | (((x)&0xff00) >> 8))
  723. #define net_long(x) (((((ulong)(x))&0xffL)<<24) | \
  724. ((((ulong)(x))&0xff00L)<<8) | \
  725. ((((ulong)(x))&0xff0000L)>>8) | \
  726. ((((ulong)(x))&0xff000000L)>>24))
  727. #endif
  728. /*
  729. * Protocols (from winsock.h)
  730. */
  731. #define IPPROTO_IP 0 /* dummy for IP */
  732. #define IPPROTO_ICMP 1 /* control message protocol */
  733. #define IPPROTO_IGMP 2 /* group management protocol */
  734. #define IPPROTO_GGP 3 /* gateway^2 (deprecated) */
  735. #define IPPROTO_TCP 6 /* tcp */
  736. #define IPPROTO_PUP 12 /* pup */
  737. #define IPPROTO_UDP 17 /* user datagram protocol */
  738. #define IPPROTO_IDP 22 /* xns idp */
  739. #define IPPROTO_ND 77 /* UNOFFICIAL net disk proto */
  740. #define IPPROTO_IPSEC 51 /* ???????? */
  741. #define IPPROTO_RAW 255 /* raw IP packet */
  742. #define IPPROTO_MAX 256
  743. //
  744. // UDP header definition
  745. //
  746. typedef struct _UDP_HEADER {
  747. ushort uh_src;
  748. ushort uh_dest;
  749. ushort uh_length;
  750. ushort uh_xsum;
  751. } UDP_HEADER, *PUDP_HEADER;
  752. //
  753. //* IP Header format.
  754. //
  755. typedef struct _IP_HEADER {
  756. uchar iph_verlen; // Version and length.
  757. uchar iph_tos; // Type of service.
  758. ushort iph_length; // Total length of datagram.
  759. ushort iph_id; // Identification.
  760. ushort iph_offset; // Flags and fragment offset.
  761. uchar iph_ttl; // Time to live.
  762. uchar iph_protocol; // Protocol.
  763. ushort iph_xsum; // Header checksum.
  764. ULONG iph_src; // Source address.
  765. ULONG iph_dest; // Destination address.
  766. } IP_HEADER, *PIP_HEADER;
  767. //
  768. // Definition of the IPX header.
  769. //
  770. typedef struct _IPX_HEADER {
  771. USHORT CheckSum;
  772. UCHAR PacketLength[2];
  773. UCHAR TransportControl;
  774. UCHAR PacketType;
  775. UCHAR DestinationNetwork[4];
  776. UCHAR DestinationNode[6];
  777. USHORT DestinationSocket;
  778. UCHAR SourceNetwork[4];
  779. UCHAR SourceNode[6];
  780. USHORT SourceSocket;
  781. } IPX_HEADER, *PIPX_HEADER;
  782. /*
  783. /////////////////////////////////////////////////////////////////
  784. //
  785. // extern
  786. //
  787. /////////////////////////////////////////////////////////////////
  788. */
  789. extern GLOBAL_BLOCK glData;
  790. extern GPC_STAT glStat;
  791. #ifdef STANDALONE_DRIVER
  792. extern GPC_EXPORTED_CALLS glGpcExportedCalls;
  793. #endif
  794. // tags
  795. extern ULONG ClassificationFamilyTag;
  796. extern ULONG ClientTag;
  797. extern ULONG PatternTag;
  798. extern ULONG CfInfoTag;
  799. extern ULONG QueuedNotificationTag;
  800. extern ULONG PendingIrpTag;
  801. extern ULONG HandleFactoryTag;
  802. extern ULONG PathHashTag;
  803. extern ULONG RhizomeTag;
  804. extern ULONG GenPatternDbTag;
  805. extern ULONG FragmentDbTag;
  806. extern ULONG CfInfoDataTag;
  807. extern ULONG ClassificationBlockTag;
  808. extern ULONG ProtocolTag;
  809. extern ULONG DebugTag;
  810. extern ULONG TcpPatternTag;
  811. extern ULONG TcpQueryContextTag;
  812. // Lookaside lists
  813. extern NPAGED_LOOKASIDE_LIST ClassificationFamilyLL;
  814. extern NPAGED_LOOKASIDE_LIST ClientLL;
  815. extern NPAGED_LOOKASIDE_LIST PatternLL;
  816. //extern NPAGED_LOOKASIDE_LIST CfInfoLL;
  817. extern ULONG CfInfoLLSize;
  818. extern NPAGED_LOOKASIDE_LIST QueuedNotificationLL;
  819. extern NPAGED_LOOKASIDE_LIST PendingIrpLL;
  820. /*
  821. /////////////////////////////////////////////////////////////////
  822. //
  823. // prototypes
  824. //
  825. /////////////////////////////////////////////////////////////////
  826. */
  827. NTSTATUS
  828. DriverEntry(
  829. IN PDRIVER_OBJECT DriverObject,
  830. IN PUNICODE_STRING RegistryPath
  831. );
  832. GPC_STATUS
  833. InitSpecificPatternDb(
  834. IN PSPECIFIC_PATTERN_DB pDb,
  835. IN ULONG PatternSize
  836. );
  837. GPC_STATUS
  838. UninitSpecificPatternDb(
  839. IN PSPECIFIC_PATTERN_DB pDb
  840. );
  841. GPC_STATUS
  842. InitClassificationHandleTbl(
  843. IN HandleFactory **ppCHTable
  844. );
  845. VOID
  846. UninitClassificationHandleTbl(
  847. IN HandleFactory *pCHTable
  848. );
  849. GPC_STATUS
  850. InitializeGenericDb(
  851. IN PGENERIC_PATTERN_DB *ppGenericDb,
  852. IN ULONG NumEntries,
  853. IN ULONG PatternSize
  854. );
  855. VOID
  856. UninitializeGenericDb(
  857. IN PGENERIC_PATTERN_DB *ppGenericDb,
  858. IN ULONG NumEntries
  859. );
  860. PCLIENT_BLOCK
  861. CreateNewClientBlock(VOID);
  862. VOID
  863. ReleaseCfBlock(
  864. IN PCF_BLOCK pCf
  865. );
  866. PCF_BLOCK
  867. CreateNewCfBlock(
  868. IN ULONG CfId,
  869. IN ULONG MaxPriorities
  870. );
  871. VOID
  872. ReleaseClientBlock(
  873. IN PCLIENT_BLOCK pClientBlock
  874. );
  875. PPATTERN_BLOCK
  876. CreateNewPatternBlock(
  877. IN ULONG Flags
  878. );
  879. VOID
  880. ReleasePatternBlock(
  881. IN PPATTERN_BLOCK pPatternBlock
  882. );
  883. PCLASSIFICATION_BLOCK
  884. CreateNewClassificationBlock(
  885. IN ULONG NumEntries
  886. );
  887. ULONG
  888. AssignNewClientIndex(
  889. IN PCF_BLOCK pCfBlock
  890. );
  891. GPC_STATUS
  892. AddGenericPattern(
  893. IN PCLIENT_BLOCK pClient,
  894. IN PUCHAR pPatternBits,
  895. IN PUCHAR pMaskBits,
  896. IN ULONG Priority,
  897. IN PBLOB_BLOCK pBlob,
  898. IN PPROTOCOL_BLOCK pProtocol,
  899. IN OUT PPATTERN_BLOCK *ppPattern
  900. );
  901. GPC_STATUS
  902. AddSpecificPattern(
  903. IN PCLIENT_BLOCK pClient,
  904. IN PUCHAR pPatternBits,
  905. IN PUCHAR pMaskBits,
  906. IN PBLOB_BLOCK pBlob,
  907. IN PPROTOCOL_BLOCK pProtocol,
  908. IN OUT PPATTERN_BLOCK *ppPattern,
  909. OUT PCLASSIFICATION_HANDLE pCH
  910. );
  911. ULONG
  912. GpcCalcHash(
  913. IN ULONG ProtocolTempId,
  914. IN PUCHAR pPattern
  915. );
  916. VOID
  917. DereferencePattern(
  918. IN PPATTERN_BLOCK pPattern
  919. );
  920. VOID
  921. DereferenceBlob(
  922. IN PBLOB_BLOCK pBlob
  923. );
  924. PBLOB_BLOCK
  925. CreateNewBlobBlock(
  926. IN ULONG ClientDataSize,
  927. IN PVOID pClientData,
  928. BOOLEAN fChargeQuota
  929. );
  930. VOID
  931. ReleaseBlobBlock(
  932. IN PBLOB_BLOCK pBlobBlock
  933. );
  934. GPC_STATUS
  935. HandleFragment(
  936. IN PCLIENT_BLOCK pClientBlock,
  937. IN PPROTOCOL_BLOCK pProtocol,
  938. IN BOOLEAN bFirstFrag,
  939. IN BOOLEAN bLastFrag,
  940. IN ULONG PacketId,
  941. IN OUT PPATTERN_BLOCK *ppPatternBlock,
  942. OUT PBLOB_BLOCK *ppBlob
  943. );
  944. NTSTATUS
  945. InternalSearchPattern(
  946. IN PCLIENT_BLOCK pClientBlock,
  947. IN PPROTOCOL_BLOCK pProtocol,
  948. IN PVOID pPatternKey,
  949. OUT PPATTERN_BLOCK *ppPatternBlock,
  950. OUT PCLASSIFICATION_HANDLE pClassificationHandle,
  951. IN BOOLEAN bNoCache
  952. );
  953. GPC_STATUS
  954. InitFragmentDb(
  955. IN PFRAGMENT_DB *ppFragDb
  956. );
  957. GPC_STATUS
  958. UninitFragmentDb(
  959. IN PFRAGMENT_DB pFragDb
  960. );
  961. VOID
  962. DereferenceClient(
  963. IN PCLIENT_BLOCK pClient
  964. );
  965. GPC_STATUS
  966. ClientAddCfInfo(
  967. IN PCLIENT_BLOCK pClient,
  968. IN PBLOB_BLOCK pBlob,
  969. OUT PGPC_CLIENT_HANDLE pClientCfInfoContext
  970. );
  971. VOID
  972. ClientAddCfInfoComplete(
  973. IN PCLIENT_BLOCK pClient,
  974. IN PBLOB_BLOCK pBlob,
  975. IN GPC_STATUS Status
  976. );
  977. GPC_STATUS
  978. ClientModifyCfInfo(
  979. IN PCLIENT_BLOCK pClient,
  980. IN PBLOB_BLOCK pBlob,
  981. IN ULONG CfInfoSize,
  982. IN PVOID pClientData
  983. );
  984. VOID
  985. ClientModifyCfInfoComplete(
  986. IN PCLIENT_BLOCK pClient,
  987. IN PBLOB_BLOCK pBlob,
  988. IN GPC_STATUS Status
  989. );
  990. GPC_STATUS
  991. ClientRemoveCfInfo(
  992. IN PCLIENT_BLOCK pClient,
  993. IN PBLOB_BLOCK pBlob,
  994. IN GPC_CLIENT_HANDLE ClientCfInfoContext
  995. );
  996. VOID
  997. ClientRemoveCfInfoComplete(
  998. IN PCLIENT_BLOCK pClient,
  999. IN PBLOB_BLOCK pBlob,
  1000. IN GPC_STATUS Status
  1001. );
  1002. GPC_STATUS
  1003. RemoveSpecificPattern(
  1004. IN PCLIENT_BLOCK pClient,
  1005. IN PPROTOCOL_BLOCK pProtocol,
  1006. IN PPATTERN_BLOCK pPattern,
  1007. IN BOOLEAN ForceRemoval,
  1008. IN BOOLEAN DbLocked
  1009. );
  1010. VOID
  1011. ClientRefsExistForSpecificPattern(
  1012. IN PCLIENT_BLOCK pClient,
  1013. IN PPROTOCOL_BLOCK pProtocol,
  1014. IN PPATTERN_BLOCK pPattern,
  1015. IN BOOLEAN dbLocked
  1016. );
  1017. VOID
  1018. ReadySpecificPatternForDeletion(
  1019. IN PCLIENT_BLOCK pClient,
  1020. IN PPROTOCOL_BLOCK pProtocol,
  1021. IN PPATTERN_BLOCK pPattern,
  1022. IN BOOLEAN DbLocked
  1023. );
  1024. GPC_STATUS
  1025. RemoveGenericPattern(
  1026. IN PCLIENT_BLOCK pClient,
  1027. IN PPROTOCOL_BLOCK pProtocol,
  1028. IN PPATTERN_BLOCK pPattern
  1029. );
  1030. VOID
  1031. ReleaseClassificationBlock(
  1032. IN PCLASSIFICATION_BLOCK pClassificationBlock
  1033. );
  1034. VOID
  1035. ClearPatternLinks(
  1036. IN PPATTERN_BLOCK pPattern,
  1037. IN PPROTOCOL_BLOCK pProtocol,
  1038. IN ULONG CfIndex
  1039. );
  1040. VOID
  1041. ModifyCompleteClients(
  1042. IN PCLIENT_BLOCK pClient,
  1043. IN PBLOB_BLOCK pBlob
  1044. );
  1045. //CLASSIFICATION_HANDLE
  1046. //GetClassificationHandle(
  1047. // IN PCLIENT_BLOCK pClient,
  1048. // IN PPATTERN_BLOCK pPattern
  1049. // );
  1050. VOID
  1051. FreeClassificationHandle(
  1052. IN PCLIENT_BLOCK pClient,
  1053. IN CLASSIFICATION_HANDLE CH
  1054. );
  1055. GPC_STATUS
  1056. CleanupBlobs(
  1057. IN PCLIENT_BLOCK pClient
  1058. );
  1059. VOID
  1060. GpcReadRegistry();
  1061. NTSTATUS
  1062. OpenRegKey(
  1063. PHANDLE HandlePtr,
  1064. PWCHAR KeyName
  1065. );
  1066. NTSTATUS
  1067. GetRegDWORDValue(
  1068. HANDLE KeyHandle,
  1069. PWCHAR ValueName,
  1070. PULONG ValueData
  1071. );
  1072. VOID
  1073. GPC_REG_READ_DWORD(
  1074. HANDLE hRegKey,
  1075. PWCHAR pwcName,
  1076. PULONG pulData,
  1077. ULONG ulDefault,
  1078. ULONG ulMax,
  1079. ULONG ulMin);
  1080. #ifdef STANDALONE_DRIVER
  1081. /*
  1082. /////////////////////////////////////////////////////////////////
  1083. //
  1084. // GPC inetrface APIs
  1085. //
  1086. /////////////////////////////////////////////////////////////////
  1087. */
  1088. GPC_STATUS
  1089. GpcGetCfInfoClientContext(
  1090. IN GPC_HANDLE ClientHandle,
  1091. IN CLASSIFICATION_HANDLE ClassificationHandle,
  1092. OUT PGPC_CLIENT_HANDLE pClientCfInfoContext
  1093. );
  1094. GPC_CLIENT_HANDLE
  1095. GpcGetCfInfoClientContextWithRef(
  1096. IN GPC_HANDLE ClientHandle,
  1097. IN CLASSIFICATION_HANDLE ClassificationHandle,
  1098. IN ULONG Offset
  1099. );
  1100. GPC_STATUS
  1101. GpcGetUlongFromCfInfo(
  1102. IN GPC_HANDLE ClientHandle,
  1103. IN CLASSIFICATION_HANDLE ClassificationHandle,
  1104. IN ULONG Offset,
  1105. IN PULONG pValue
  1106. );
  1107. GPC_STATUS
  1108. GpcRegisterClient(
  1109. IN ULONG CfId,
  1110. IN ULONG Flags,
  1111. IN ULONG MaxPriorities,
  1112. IN PGPC_CLIENT_FUNC_LIST pClientFuncList,
  1113. IN GPC_CLIENT_HANDLE ClientContext,
  1114. OUT PGPC_HANDLE pClientHandle
  1115. );
  1116. GPC_STATUS
  1117. GpcDeregisterClient(
  1118. IN GPC_HANDLE ClientHandle
  1119. );
  1120. GPC_STATUS
  1121. GpcAddCfInfo(
  1122. IN GPC_HANDLE ClientHandle,
  1123. IN ULONG CfInfoSize,
  1124. IN PVOID pClientCfInfo,
  1125. IN GPC_CLIENT_HANDLE ClientCfInfoContext,
  1126. OUT PGPC_HANDLE pGpcCfInfoHandle
  1127. );
  1128. GPC_STATUS
  1129. GpcAddPattern(
  1130. IN GPC_HANDLE ClientHandle,
  1131. IN ULONG ProtocolTemplate,
  1132. IN PVOID Pattern,
  1133. IN PVOID Mask,
  1134. IN ULONG Priority,
  1135. IN GPC_HANDLE GpcCfInfoHandle,
  1136. OUT PGPC_HANDLE pGpcPatternHandle,
  1137. OUT PCLASSIFICATION_HANDLE pClassificationHandle
  1138. );
  1139. VOID
  1140. GpcAddCfInfoNotifyComplete(
  1141. IN GPC_HANDLE ClientHandle,
  1142. IN GPC_HANDLE GpcCfInfoHandle,
  1143. IN GPC_STATUS Status,
  1144. IN GPC_CLIENT_HANDLE ClientCfInfoContext
  1145. );
  1146. GPC_STATUS
  1147. GpcModifyCfInfo (
  1148. IN GPC_HANDLE ClientHandle,
  1149. IN GPC_HANDLE GpcCfInfoHandle,
  1150. IN ULONG CfInfoSize,
  1151. IN PVOID pClientCfInfo
  1152. );
  1153. VOID
  1154. GpcModifyCfInfoNotifyComplete(
  1155. IN GPC_HANDLE ClientHandle,
  1156. IN GPC_HANDLE GpcCfInfoHandle,
  1157. IN GPC_STATUS Status
  1158. );
  1159. GPC_STATUS
  1160. GpcRemoveCfInfo (
  1161. IN GPC_HANDLE ClientHandle,
  1162. IN GPC_HANDLE GpcCfInfoHandle
  1163. );
  1164. VOID
  1165. GpcRemoveCfInfoNotifyComplete(
  1166. IN GPC_HANDLE ClientHandle,
  1167. IN GPC_HANDLE GpcCfInfoHandle,
  1168. IN GPC_STATUS Status
  1169. );
  1170. GPC_STATUS
  1171. GpcRemovePattern (
  1172. IN GPC_HANDLE ClientHandle,
  1173. IN GPC_HANDLE GpcPatternHandle
  1174. );
  1175. GPC_STATUS
  1176. GpcClassifyPattern (
  1177. IN GPC_HANDLE ClientHandle,
  1178. IN ULONG ProtocolTemplate,
  1179. IN PVOID pPattern,
  1180. OUT PGPC_CLIENT_HANDLE pClientCfInfoContext,
  1181. IN OUT PCLASSIFICATION_HANDLE pClassificationHandle,
  1182. IN ULONG Offset,
  1183. IN PULONG pValue,
  1184. IN BOOLEAN bNoCache
  1185. );
  1186. GPC_STATUS
  1187. GpcClassifyPacket (
  1188. IN GPC_HANDLE ClientHandle,
  1189. IN ULONG ProtocolTemplate,
  1190. IN PVOID pNdisPacket,
  1191. IN ULONG TransportHeaderOffset,
  1192. IN PTC_INTERFACE_ID InterfaceId,
  1193. OUT PGPC_CLIENT_HANDLE pClientCfInfoContext,
  1194. OUT PCLASSIFICATION_HANDLE pClassificationHandle
  1195. );
  1196. GPC_STATUS
  1197. GpcEnumCfInfo (
  1198. IN GPC_HANDLE ClientHandle,
  1199. IN OUT PHANDLE pCfInfoHandle,
  1200. OUT PHANDLE pCfInfoMapHandle,
  1201. IN OUT PULONG pCfInfoCount,
  1202. IN OUT PULONG pBufferSize,
  1203. OUT PGPC_ENUM_CFINFO_BUFFER Buffer
  1204. );
  1205. #endif // STANDALONE_DRIVER
  1206. GPC_STATUS
  1207. GetClientCtxAndUlongFromCfInfo(
  1208. IN GPC_HANDLE ClientHandle,
  1209. IN OUT PCLASSIFICATION_HANDLE pClassificationHandle,
  1210. OUT PGPC_CLIENT_HANDLE pClientCfInfoContext,
  1211. IN ULONG Offset,
  1212. IN PULONG pValue
  1213. );
  1214. GPC_STATUS
  1215. privateGpcAddCfInfo(
  1216. IN GPC_HANDLE ClientHandle,
  1217. IN ULONG CfInfoSize,
  1218. IN PVOID pClientCfInfoPtr,
  1219. IN GPC_CLIENT_HANDLE ClientCfInfoContext,
  1220. IN PFILE_OBJECT FileObject,
  1221. IN PGPC_IP_PATTERN Pattern,
  1222. OUT PGPC_HANDLE pGpcCfInfoHandle
  1223. );
  1224. GPC_STATUS
  1225. privateGpcRemoveCfInfo(
  1226. IN GPC_HANDLE ClientHandle,
  1227. IN GPC_HANDLE GpcCfInfoHandle,
  1228. IN ULONG Flags
  1229. );
  1230. GPC_STATUS
  1231. privateGpcRemovePattern(
  1232. IN GPC_HANDLE ClientHandle,
  1233. IN GPC_HANDLE GpcPatternHandle,
  1234. IN BOOLEAN ForceRemoval,
  1235. IN BOOLEAN DbLocked
  1236. );
  1237. VOID
  1238. UMClientRemoveCfInfoNotify(
  1239. IN PCLIENT_BLOCK pClient,
  1240. IN PBLOB_BLOCK pBlob
  1241. );
  1242. VOID
  1243. UMCfInfoComplete(
  1244. IN GPC_COMPLETION_OP OpCode,
  1245. IN PCLIENT_BLOCK pClient,
  1246. IN PBLOB_BLOCK pBlob,
  1247. IN GPC_STATUS Status
  1248. );
  1249. VOID
  1250. CloseAllObjects(
  1251. IN PFILE_OBJECT FileObject,
  1252. IN PIRP Irp
  1253. );
  1254. NTSTATUS
  1255. IoctlInitialize(
  1256. IN PDRIVER_OBJECT DriverObject,
  1257. IN PULONG InitShutdownMask
  1258. );
  1259. NTSTATUS
  1260. CheckQueuedNotification(
  1261. IN PIRP Irp,
  1262. IN OUT ULONG *outputBufferLength
  1263. );
  1264. NTSTATUS
  1265. CheckQueuedCompletion(
  1266. IN PQUEUED_COMPLETION pQItem,
  1267. IN PIRP Irp
  1268. );
  1269. VOID
  1270. PatternTimerExpired(
  1271. IN PVOID SystemSpecific1,
  1272. IN PVOID FunctionContext,
  1273. IN PVOID SystemSpecific2,
  1274. IN PVOID SystemSpecific3
  1275. );
  1276. GPC_STATUS
  1277. AddSpecificPatternWithTimer(
  1278. IN PCLIENT_BLOCK pClient,
  1279. IN ULONG ProtocolTemplate,
  1280. IN PVOID PatternKey,
  1281. OUT PPATTERN_BLOCK *ppPattern,
  1282. OUT PCLASSIFICATION_HANDLE pClassificationHandle
  1283. );
  1284. NTSTATUS
  1285. InitPatternTimer(
  1286. IN ULONG ProtocolTemplate
  1287. );
  1288. #endif // __GPCDEF