Source code of Windows XP (NT5)
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.

1550 lines
39 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. rm.h
  5. Abstract:
  6. "Resource Manager" structures and APIs
  7. Author:
  8. Revision History:
  9. Who When What
  10. -------- -------- ----
  11. josephj 11-10-98 created
  12. --*/
  13. //=================================================================================
  14. // O S - S P E C I F I C T Y P E S
  15. //=================================================================================
  16. #define RM_OS_LOCK NDIS_SPIN_LOCK
  17. #define OS_WORK_ITEM NDIS_WORK_ITEM
  18. #define OS_TIMER NDIS_TIMER
  19. #define RM_STATUS NDIS_STATUS
  20. #define RM_OS_FILL_MEMORY(_dest, _len, _fill) NdisFillMemory(_dest, _len, _fill)
  21. #define RM_OS_ZERO_MEMORY(_dest, _len) NdisZeroMemory(_dest, _len)
  22. #define RM_OS_GET_CURRENT_THREAD_HANDLE() NULL
  23. // If set, the object tree is explicitly maintained.
  24. //
  25. #define RM_TRACK_OBJECT_TREE 1
  26. //=================================================================================
  27. // F O R W A R D R E F E R E N C E S
  28. //=================================================================================
  29. typedef struct _RM_STACK_RECORD RM_STACK_RECORD, *PRM_STACK_RECORD;
  30. typedef struct _RM_OBJECT_HEADER RM_OBJECT_HEADER, *PRM_OBJECT_HEADER;
  31. typedef struct _RM_TASK RM_TASK, *PRM_TASK;
  32. typedef struct _RM_RESOURCE_TABLE_ENTRY
  33. RM_RESOURCE_TABLE_ENTRY, *PRM_RESOURCE_TABLE_ENTRY;
  34. //=================================================================================
  35. // T Y P E D E F S
  36. //=================================================================================
  37. //
  38. // RM_DBG_LOCK_INFO Keeps debugging information specific to an instance of a RM_LOCK.
  39. //
  40. typedef struct _RM_DBG_LOCK_INFO
  41. {
  42. //
  43. // If nonzero, LocID is a magic number which uniquely identifies the source
  44. // location where the lock was aquired.
  45. //
  46. ULONG uLocID;
  47. //
  48. // pSR points to the stack record of the currently owning thread, if there
  49. // is one. If a function F expects an object pObj to be locked on entry,
  50. // it can ASSERT(pObj->pLock->pDbgInfo->pSR == pSR);
  51. //
  52. struct _RM_STACK_RECORD *pSR;
  53. } RM_DBG_LOCK_INFO, *PRM_DBG_LOCK_INFO;
  54. //
  55. // RM_LOCK keeps information about a lock.
  56. //
  57. typedef struct _RM_LOCK
  58. {
  59. //
  60. // Native, os-provided lock structure.
  61. //
  62. RM_OS_LOCK OsLock;
  63. //
  64. // Level of this lock. Multiple locks can only be acquired in increasing order
  65. // of this value.
  66. //
  67. ULONG Level;
  68. //
  69. // Pointer to debugging info for this lock. Could be NULL.
  70. //
  71. PRM_DBG_LOCK_INFO pDbgInfo;
  72. #if RM_EXTRA_CHECKING
  73. RM_DBG_LOCK_INFO DbgInfo;
  74. #endif // RM_EXTRA_CHECKING
  75. } RM_LOCK, *PRM_LOCK;
  76. typedef
  77. ULONG
  78. (*PFNLOCKVERIFIER) (
  79. PRM_LOCK pLock,
  80. BOOLEAN fLock,
  81. PVOID pContext,
  82. PRM_STACK_RECORD pSR
  83. );
  84. // RM_LOCKING_INFO keeps information about a particular lock being held.
  85. // In non-checking mode, this is just the pointer to the lock.
  86. // In checking mode, this additionally contains information that can be used
  87. // to verify that the entity being protected by the lock is not changed when
  88. // the lock is not being held.
  89. //
  90. typedef struct
  91. {
  92. PRM_LOCK pLock;
  93. #if RM_EXTRA_CHECKING
  94. PFNLOCKVERIFIER pfnVerifier;
  95. PVOID pVerifierContext;
  96. #endif // RM_EXTRA_CHECKING
  97. } RM_LOCKING_INFO, PRM_LOCKING_INFO;
  98. //
  99. // RM_STACK_RECORD keeps information relevant to the current call tree.
  100. //
  101. typedef struct _RM_STACK_RECORD
  102. {
  103. //
  104. // LockInfo contains information about currently-held locks.
  105. //
  106. struct
  107. {
  108. //
  109. // Level of the currently held lock. Locks must be claimed in
  110. // order of increasing Level values. The lowest level value is 1. Level
  111. // 0 indicates no locks held.
  112. //
  113. UINT CurrentLevel;
  114. //
  115. // Pointer to the first location to store a pointers to a locks.
  116. //
  117. PRM_LOCKING_INFO *pFirst;
  118. //
  119. // Pointer to the next free location to store a pointer to a lock
  120. // that has been claimed in this call tree.
  121. //
  122. PRM_LOCKING_INFO *pNextFree;
  123. //
  124. // Pointer to the last valid location to store a lock pointer.
  125. //
  126. PRM_LOCKING_INFO *pLast;
  127. } LockInfo;
  128. //
  129. // Count of tmp refs taken with this stack record.
  130. //
  131. ULONG TmpRefs;
  132. #if DBG
  133. //
  134. // DbgInfo contains diagnostic information relevant to this call tree.
  135. //
  136. struct
  137. {
  138. //
  139. // Verbosity level
  140. //
  141. ULONG Level;
  142. //
  143. // Points to the os-provided thread handle of the current thread.
  144. // if there is one.
  145. //
  146. PVOID pvThread;
  147. } DbgInfo;
  148. #endif // DBG
  149. } RM_STACK_RECORD, *PRM_STACK_RECORD;
  150. #if DBG
  151. #define RM_INIT_DBG_STACK_RECORD(_sr, _dbglevel) \
  152. _sr.DbgInfo.Level = _dbglevel; \
  153. _sr.DbgInfo.pvThread = RM_OS_GET_CURRENT_THREAD_HANDLE();
  154. #else
  155. #define RM_INIT_DBG_STACK_RECORD(_sr, _dbglevel)
  156. #endif
  157. //
  158. // RM_DECLARE_STACK_RECORD_EX is a macro to reserve some stack space for
  159. // a stack record.
  160. //
  161. #define RM_DECLARE_STACK_RECORD_EX(_sr, _max_locks, _dbglevel) \
  162. RM_LOCKING_INFO rm_lock_array[_max_locks]; \
  163. RM_STACK_RECORD _sr; \
  164. RM_OS_ZERO_MEMORY(rm_lock_array, sizeof(rm_lock_array)); \
  165. _sr.TmpRefs = 0; \
  166. _sr.LockInfo.CurrentLevel = 0; \
  167. _sr.LockInfo.pFirst = rm_lock_array; \
  168. _sr.LockInfo.pNextFree = rm_lock_array; \
  169. _sr.LockInfo.pLast = rm_lock_array+(_max_locks)-1; \
  170. RM_INIT_DBG_STACK_RECORD(_sr, _dbglevel);
  171. //
  172. // RM_DECLARE_STACK_RECORD is a macro to reserve default stack space for
  173. // a stack record.
  174. //
  175. #define RM_DECLARE_STACK_RECORD(_sr) \
  176. RM_DECLARE_STACK_RECORD_EX(_sr, 4, 0)
  177. //
  178. // Generic memory allocator prototype
  179. //
  180. typedef
  181. PVOID
  182. (*PFN_RM_MEMORY_ALLOCATOR)(
  183. PVOID pAllocationContext,
  184. UINT Size // in bytes
  185. );
  186. //
  187. // Generic memory deallocator prototype
  188. //
  189. typedef
  190. PVOID
  191. (*PFN_RM_MEMORY_DEALLOCATOR)(
  192. PVOID pMem,
  193. PVOID pAllocationContext
  194. );
  195. // RM_HASH_LINK is the field in the structures being hashed that is
  196. // used to link all items in the same bucket. It also contains the
  197. // "HashKey", which is a potentially-nonunique UINT-sized hash of the
  198. // real key.
  199. //
  200. typedef struct _RM_HASH_LINK
  201. {
  202. struct _RM_HASH_LINK *pNext;
  203. UINT uHash;
  204. } RM_HASH_LINK, *PRM_HASH_LINK;
  205. //
  206. // Hash table comparison function.
  207. //
  208. typedef
  209. BOOLEAN
  210. (*PFN_RM_COMPARISON_FUNCTION)(
  211. PVOID pKey,
  212. PRM_HASH_LINK pItem
  213. );
  214. //
  215. // Hash computation function.
  216. //
  217. typedef
  218. ULONG
  219. (*PFN_RM_HASH_FUNCTION)(
  220. PVOID pKey
  221. );
  222. //
  223. // RM_HASH_INFO specifies customizing information about a hash table.
  224. //
  225. typedef struct
  226. {
  227. // Allocator used to allocate the hash table if it needs to grow.
  228. //
  229. PFN_RM_MEMORY_ALLOCATOR pfnTableAllocator;
  230. // Free function for the above allocator.
  231. PFN_RM_MEMORY_DEALLOCATOR pfnTableDeallocator;
  232. // Comparison function for strict equality.
  233. //
  234. PFN_RM_COMPARISON_FUNCTION pfnCompare;
  235. // Function to generate a ULONG-sized hash.
  236. //
  237. PFN_RM_HASH_FUNCTION pfnHash;
  238. #if OBSOLETE
  239. // Offset in sizeof(UINT) to location of the place to keep
  240. // the next pointer for the bucket list.
  241. //
  242. UINT OffsetNext;
  243. // Offset in sizeof(UINT) to location of UINT-sized Temp ref
  244. //
  245. UINT OffsetTmpRef;
  246. // Offset in sizeof(UINT) to location of UINT-sized Tot ref
  247. //
  248. UINT OffsetTotRef;
  249. // Offset in sizeof(UINT) to location of ULONG-sized hash key.
  250. //
  251. UINT OffsetHashKey;
  252. #endif // OBSOLETE
  253. } RM_HASH_INFO, *PRM_HASH_INFO;
  254. #define RM_MIN_HASH_TABLE_SIZE 4
  255. //
  256. // RM_HASH_TABLE is a hash table.
  257. //
  258. typedef struct
  259. {
  260. // Number of items currently in hash table.
  261. //
  262. UINT NumItems;
  263. // Stats is a 32-bit quantity keeps a running total of number of accesses
  264. // (add+search+remove) in the HIWORD and the total number of list nodes
  265. // traversed in the LOWORD. This field gets updated even on searches, but
  266. // it is not protected by the hash table lock -- instead it is
  267. // updated using an interlocked operation. This allows us to use
  268. // a read lock for searches while still updating this statistic value.
  269. // The Stats field is re-scaled when the counts get too high, to avoid
  270. // overflow and also to favor more recent stats in preference to older
  271. // stats.
  272. //
  273. // NumItems, Stats and TableLength are used to decide whether to
  274. // dynamically resize the hash table.
  275. //
  276. ULONG Stats;
  277. // Length of hash table in units of PVOID
  278. //
  279. ULONG TableLength;
  280. // Pointer to TableLength-sized array of PVOIDs -- this is the actual hash table
  281. //
  282. PRM_HASH_LINK *pTable;
  283. // The hash table
  284. //
  285. PRM_HASH_LINK InitialTable[RM_MIN_HASH_TABLE_SIZE];
  286. // Static information about this hash table.
  287. //
  288. PRM_HASH_INFO pHashInfo;
  289. // Passed into the allocate/deallocate functions.
  290. //
  291. PVOID pAllocationContext;
  292. } RM_HASH_TABLE, *PRM_HASH_TABLE;
  293. // Returns approximate value of (num-nodes-traversed)/(num-accesses)
  294. //
  295. #define RM_HASH_TABLE_TRAVERSE_RATIO(_pHash_Table) \
  296. (((_pHash_Table)->Stats & 0xffff) / (1+((_pHash_Table)->Stats >> 16)))
  297. //
  298. // NOTE: the "1+" above is simply to guard against devide-by-zero.
  299. //
  300. // RM_OBJECT_DIAGNOSTIC_INFO keeps diagnostic info specific to an instance of
  301. // an object.
  302. //
  303. // This structure is for private use of the RM APIs.
  304. // The only field of general interest is PrevState.
  305. //
  306. typedef struct
  307. {
  308. // Back pointer to owning object.
  309. //
  310. RM_OBJECT_HEADER *pOwningObject;
  311. // Each time the object-specific State field is updated, it's previous
  312. // value is saved here.
  313. //
  314. ULONG PrevState;
  315. // Used for correctly updating PrevState.
  316. //
  317. ULONG TmpState;
  318. // Diagnostic-related state.
  319. //
  320. ULONG DiagState;
  321. #define fRM_PRIVATE_DISABLE_LOCK_CHECKING (0x1<<0)
  322. // This is an object-specific checksum that is computed and
  323. // saved just before the object is unlocked. It is checked
  324. // just after the object is locked.
  325. //
  326. ULONG Checksum;
  327. // Native OS lock to be *only* to serialize access to the information
  328. // in this structure.
  329. //
  330. RM_OS_LOCK OsLock;
  331. // Keeps an associative list of all entities which have been registered
  332. // (using RmDbgAddAssociation) with this object. Ths includes objects which
  333. // have been linked to this object using the RmLinkObjects call, as well
  334. // as childen and parents of this object.
  335. //
  336. RM_HASH_TABLE AssociationTable;
  337. // Following is set to TRUE IFF there was an allocation failure when trying to
  338. // add an association. If there'e been an allocation failure, we don't complain
  339. // (i.e. ASSERT) if an attempt is made to remove an assertion that doesn't
  340. // exist. In this way we gracefully deal with allocation failures of the
  341. // association table entries.
  342. //
  343. INT AssociationTableAllocationFailure;
  344. // The per-object list of log entries.
  345. // This is serialized by the global rm lock, not the local rm-private lock!
  346. //
  347. LIST_ENTRY listObjectLog;
  348. // Count of entries in this object's log.
  349. // This is serialized by the global rm lock, not the local rm-private lock!
  350. //
  351. UINT NumObjectLogEntries;
  352. #if TODO // We haven't implemented the following yet...
  353. // Future:
  354. // RM_STATE_HISTORY -- generalization of PrevState.
  355. #endif // TODO
  356. } RM_OBJECT_DIAGNOSTIC_INFO, *PRM_OBJECT_DIAGNOSTIC_INFO;
  357. typedef
  358. PRM_OBJECT_HEADER
  359. (*PFN_CREATE_OBJECT)(
  360. PRM_OBJECT_HEADER pParentObject,
  361. PVOID pCreateParams,
  362. PRM_STACK_RECORD psr
  363. );
  364. typedef
  365. VOID
  366. (*PFN_DELETE_OBJECT)(PRM_OBJECT_HEADER, PRM_STACK_RECORD psr);
  367. //
  368. // RM_STATIC_OBJECT_INFO keeps information that is common to all instances of
  369. // a particular type of object.
  370. //
  371. typedef struct
  372. {
  373. ULONG TypeUID;
  374. ULONG TypeFlags;
  375. char* szTypeName;
  376. UINT Timeout;
  377. //
  378. // Various Handlers
  379. //
  380. PFN_CREATE_OBJECT pfnCreate;
  381. PFN_DELETE_OBJECT pfnDelete;
  382. PFNLOCKVERIFIER pfnLockVerifier;
  383. //
  384. // Resource Information
  385. //
  386. UINT NumResourceTableEntries;
  387. struct _RM_RESOURCE_TABLE_ENTRY * pResourceTable;
  388. //
  389. // Hash-table info, if this object is part of a group.
  390. //
  391. PRM_HASH_INFO pHashInfo;
  392. } RM_STATIC_OBJECT_INFO, *PRM_STATIC_OBJECT_INFO;
  393. //
  394. // RM_OBJECT_HEADER is the common header for all objects.
  395. //
  396. typedef struct _RM_OBJECT_HEADER
  397. {
  398. //
  399. // Object-type-specific signature.
  400. //
  401. ULONG Sig;
  402. //
  403. // Description of this object (could be the same as pStaticInfo->szTypeName,
  404. // but may be something more specific).
  405. // Used only for debugging purposes.
  406. // TODO: consider moving this into the pDiagInfo struct. For now, leave it
  407. // here because it's useful when debugging.
  408. //
  409. const char *szDescription;
  410. //
  411. // Object-specific state.
  412. //
  413. ULONG State;
  414. ULONG RmState; // One or more RMOBJSTATE_* or RMTSKSTATE_* flags below...
  415. //
  416. // RM state flags....
  417. //
  418. // Object allocation state...
  419. //
  420. #define RMOBJSTATE_ALLOCMASK 0x00f
  421. #define RMOBJSTATE_ALLOCATED 0x001
  422. #define RMOBJSTATE_DEALLOCATED 0x000
  423. // Task state ...
  424. //
  425. #define RMTSKSTATE_MASK 0x0f0
  426. #define RMTSKSTATE_IDLE 0x000
  427. #define RMTSKSTATE_STARTING 0x010
  428. #define RMTSKSTATE_ACTIVE 0x020
  429. #define RMTSKSTATE_PENDING 0x030
  430. #define RMTSKSTATE_ENDING 0x040
  431. // Task delay state
  432. //
  433. #define RMTSKDELSTATE_MASK 0x100
  434. #define RMTSKDELSTATE_DELAYED 0x100
  435. // Task abort state
  436. //
  437. #define RMTSKABORTSTATE_MASK 0x200
  438. #define RMTSKABORTSTATE_ABORT_DELAY 0x200
  439. //
  440. // Bitmap identifying resources used by this object.
  441. //
  442. ULONG ResourceMap;
  443. // Total reference count.
  444. //
  445. //
  446. ULONG TotRefs;
  447. //
  448. // Pointer to a RM_LOCK object used to serialize access to this object.
  449. //
  450. PRM_LOCK pLock;
  451. //
  452. // Pointer to information common to all instances of this object type.
  453. //
  454. PRM_STATIC_OBJECT_INFO pStaticInfo;
  455. //
  456. // Points to diagnostic information about this object. Could be NULL.
  457. //
  458. PRM_OBJECT_DIAGNOSTIC_INFO pDiagInfo;
  459. //
  460. // Points to the parent object.
  461. //
  462. struct _RM_OBJECT_HEADER *pParentObject;
  463. //
  464. // Points to the root (ancestor of all object) -- could be the same
  465. // as pParentObject;
  466. //
  467. struct _RM_OBJECT_HEADER *pRootObject;
  468. //
  469. // This is a private lock used exclusively by the RM apis. It is
  470. // never left unlocked by the RM apis.
  471. // TODO: maybe make this a native-os lock.
  472. //
  473. RM_LOCK RmPrivateLock;
  474. // Used to create groups of objects.
  475. // TODO: make this a private field, present only if the object is
  476. // meant to be in a group.
  477. //
  478. RM_HASH_LINK HashLink;
  479. #if RM_TRACK_OBJECT_TREE
  480. LIST_ENTRY listChildren; // Protected by this object's RmPrivateLock.
  481. LIST_ENTRY linkSiblings; // Protected by parent object's RmPrivateLock.
  482. #endif // RM_TRACK_OBJECT_TREE
  483. ULONG TempRefs;
  484. } RM_OBJECT_HEADER, *PRM_OBJECT_HEADER;
  485. //
  486. // Diagnostic resource tracking.
  487. //
  488. typedef struct
  489. {
  490. ULONG_PTR Instance;
  491. ULONG TypeUID;
  492. PRM_OBJECT_HEADER pParentObject;
  493. ULONG CallersUID;
  494. ULONG CallersSrUID;
  495. } RM_DBG_RESOURCE_ENTRY;
  496. typedef enum
  497. {
  498. RM_RESOURCE_OP_LOAD,
  499. RM_RESOURCE_OP_UNLOAD
  500. } RM_RESOURCE_OPERATION;
  501. typedef
  502. RM_STATUS
  503. (*PFN_RM_RESOURCE_HANDLER)(
  504. PRM_OBJECT_HEADER pObj,
  505. RM_RESOURCE_OPERATION Op,
  506. PVOID pvUserParams,
  507. PRM_STACK_RECORD psr
  508. );
  509. typedef struct _RM_RESOURCE_TABLE_ENTRY
  510. {
  511. UINT ID;
  512. PFN_RM_RESOURCE_HANDLER pfnHandler;
  513. } RM_RESOURCE_TABLE_ENTRY, *PRM_RESOURCE_TABLE_ENTRY;
  514. typedef struct
  515. {
  516. UINT u;
  517. } RM_OBJECT_INDEX, *PRM_OBJECT_INDEX;
  518. typedef struct
  519. {
  520. PRM_OBJECT_HEADER pOwningObject;
  521. const char * szDescription;
  522. PRM_STATIC_OBJECT_INFO pStaticInfo;
  523. RM_HASH_TABLE HashTable;
  524. // Private lock used ONLY by group access functions.
  525. //
  526. RM_OS_LOCK OsLock;
  527. // When non-NULL, points to the task responsible for unloading all objects
  528. // in this group.
  529. //
  530. PRM_TASK pUnloadTask;
  531. BOOLEAN fEnabled;
  532. } RM_GROUP, *PRM_GROUP;
  533. typedef enum
  534. {
  535. RM_TASKOP_START,
  536. RM_TASKOP_PENDCOMPLETE,
  537. RM_TASKOP_END,
  538. RM_TASKOP_PRIVATE,
  539. RM_TASKOP_ABORT,
  540. RM_TASKOP_TIMEOUT
  541. } RM_TASK_OPERATION;
  542. typedef
  543. RM_STATUS
  544. (*PFN_RM_TASK_HANDLER)(
  545. IN struct _RM_TASK * pTask,
  546. IN RM_TASK_OPERATION Op,
  547. IN UINT_PTR UserParam,
  548. IN PRM_STACK_RECORD pSR
  549. );
  550. //
  551. // For START and PENDCOMPLETE, a return value other than PENDING causes
  552. // the task to end. Of course, it is illegal to return non-pending when
  553. // the task is in a pending state.
  554. //
  555. // Task allocator prototype
  556. //
  557. typedef
  558. RM_STATUS
  559. (*PFN_RM_TASK_ALLOCATOR)(
  560. IN PRM_OBJECT_HEADER pParentObject,
  561. IN PFN_RM_TASK_HANDLER pfnHandler,
  562. IN UINT Timeout,
  563. IN const char * szDescription,
  564. OUT PRM_TASK *ppTask,
  565. IN PRM_STACK_RECORD pSR
  566. );
  567. typedef struct _RM_TASK
  568. {
  569. RM_OBJECT_HEADER Hdr;
  570. PFN_RM_TASK_HANDLER pfnHandler;
  571. LIST_ENTRY linkFellowPendingTasks;
  572. LIST_ENTRY listTasksPendingOnMe;
  573. struct _RM_TASK * pTaskIAmPendingOn;
  574. // In the case that we need to asynchronously notify the completion of a
  575. // pending operation, we can save the completion param here.
  576. //
  577. UINT_PTR AsyncCompletionParam;
  578. UINT SuspendContext;
  579. } RM_TASK, *PRM_TASK;
  580. typedef
  581. VOID
  582. (*PFN_DBG_DUMP_LOG_ENTRY) (
  583. char *szFormatString,
  584. UINT_PTR Param1,
  585. UINT_PTR Param2,
  586. UINT_PTR Param3,
  587. UINT_PTR Param4
  588. );
  589. #if RM_EXTRA_CHECKING
  590. // (For debugging only)
  591. // Keeps track of a single association (See RmDbgAddAssociation)
  592. // This is a PRIVATE data structure, and is only here because
  593. // the kd extension refers to it.
  594. //
  595. typedef struct
  596. {
  597. ULONG LocID;
  598. ULONG_PTR Entity1;
  599. ULONG_PTR Entity2;
  600. ULONG AssociationID;
  601. const char * szFormatString;
  602. RM_HASH_LINK HashLink;
  603. } RM_PRIVATE_DBG_ASSOCIATION;
  604. // (For debugging only)
  605. // Keeps track of a single per-object log entry.
  606. // This is a PRIVATE data structure, and is only here because
  607. // the kd extension refers to it.
  608. //
  609. typedef struct
  610. {
  611. // Link to other entries for this object
  612. //
  613. LIST_ENTRY linkObjectLog;
  614. // Link to other entries in the global list.
  615. //
  616. LIST_ENTRY linkGlobalLog;
  617. // Object this entry belongs to
  618. //
  619. PRM_OBJECT_HEADER pObject;
  620. // Function to be used for dumping the log.
  621. //
  622. PFN_DBG_DUMP_LOG_ENTRY pfnDumpEntry;
  623. // Prefix string to be dumped *before* the log display.
  624. // This was added so we could log associations properly, otherwise it's
  625. // extra baggage. Can be null.
  626. //
  627. char *szPrefix;
  628. // Format string for log display -- 1st arg to pfnDumpEntry
  629. //
  630. char *szFormatString;
  631. // Remaining args to pfnDumpEntry;
  632. //
  633. //
  634. UINT_PTR Param1;
  635. UINT_PTR Param2;
  636. UINT_PTR Param3;
  637. UINT_PTR Param4;
  638. // If non-NULL, piece of memory to be freed when the log entry is freed.
  639. // TODO: See notes.txt entry "03/07/1999 ... Registering root objects with RM"
  640. // on how we will find the deallocator function. For now we simply
  641. // use NdisFreeMemory.
  642. //
  643. PVOID pvBuf;
  644. } RM_DBG_LOG_ENTRY;
  645. #endif RM_EXTRA_CHECKING
  646. //=================================================================================
  647. // U T I L I T Y M A C R O S
  648. //=================================================================================
  649. #define RM_PARENT_OBJECT(_pObj) \
  650. ((_pObj)->Hdr.pParentObject)
  651. #define RM_PEND_CODE(_pTask) \
  652. ((_pTask)->SuspendContext)
  653. #define RM_ASSERT_SAME_LOCK_AS_PARENT(_pObj) \
  654. ASSERTEX( \
  655. ((_pObj)->Hdr.pLock == (_pObj)->Hdr.pParentObject->pLock), \
  656. (_pObj))
  657. #define RM_SET_STATE(_pObj, _Mask, _Val) \
  658. (((_pObj)->Hdr.State) = (((_pObj)->Hdr.State) & ~(_Mask)) | (_Val))
  659. #define RM_CHECK_STATE(_pObj, _Mask, _Val) \
  660. ((((_pObj)->Hdr.State) & (_Mask)) == (_Val))
  661. #define RM_GET_STATE(_pObj, _Mask) \
  662. (((_pObj)->Hdr.State) & (_Mask))
  663. // Asserts that the object is in the "zombie" state, i.e., it
  664. // lives on just because of references.
  665. // WARNING: It is upto the caller to synchronize access to this -- for example
  666. // if they're going to do thing's like if (!RM_IS_ZOMBIE(pObj)) {do-stuff}, they
  667. // had better make sure that only one of them goes on to "does-stuff".
  668. //
  669. #define RM_IS_ZOMBIE(_pobj) \
  670. (((_pobj)->Hdr.RmState&RMOBJSTATE_ALLOCMASK)==RMOBJSTATE_DEALLOCATED)
  671. // Asserts that no locks are held.
  672. //
  673. #define RM_ASSERT_NOLOCKS(_psr) \
  674. ASSERTEX((_psr)->LockInfo.CurrentLevel == 0, (_psr))
  675. // Assert that no locks or tmprefs are held.
  676. //
  677. #define RM_ASSERT_CLEAR(_psr) \
  678. ASSERTEX(((_psr)->LockInfo.CurrentLevel==0), (_psr)); \
  679. ASSERTEX((_psr)->TmpRefs==0, (_psr));
  680. #if RM_EXTRA_CHECKING
  681. //
  682. // TODO: rename the following to something better...
  683. //
  684. #define RM_DBG_ASSERT_LOCKED0(_pLk, _pSR) \
  685. ASSERTEX((_pLk)->DbgInfo.pSR == (_pSR), (_pHdr))
  686. // TODO -- replace calls to this by calls to RM_ASSERT_OBJLOCKED
  687. #define RM_DBG_ASSERT_LOCKED(_pHdr, _pSR) \
  688. ASSERTEX((_pHdr)->pLock->DbgInfo.pSR == (_pSR), (_pHdr))
  689. #define RM_ASSERT_OBJLOCKED(_pHdr, _pSR) \
  690. ASSERTEX((_pHdr)->pLock->DbgInfo.pSR == (_pSR), (_pHdr))
  691. // Note that we can't assume DbgInfo.pSR is NULL below (it could be locked
  692. // by some other thread), but we CAN assert that DbgInfo.pSR is not equal to the
  693. // current pSR!
  694. //
  695. #define RM_ASSERT_OBJUNLOCKED(_pHdr, _pSR) \
  696. ASSERTEX((_pHdr)->pLock->DbgInfo.pSR != (_pSR), (_pHdr))
  697. #else // !RM_EXTRA_CHECKING
  698. #define RM_DBG_ASSERT_LOCKED0(_pLk, _pSR) (0)
  699. #define RM_DBG_ASSERT_LOCKED(_pHdr, _pSR) (0)
  700. #define RM_ASSERT_OBJLOCKED(_pHdr, _pSR) (0)
  701. #define RM_ASSERT_OBJUNLOCKED(_pHdr, _pSR) (0)
  702. #endif // !RM_EXTRA_CHECKING
  703. #define RM_NUM_ITEMS_IN_GROUP(_pGroup) \
  704. ((_pGroup)->HashTable.NumItems)
  705. //=================================================================================
  706. // F U N C T I O N P R O T O T Y P E S
  707. //=================================================================================
  708. VOID
  709. RmInitializeRm(VOID);
  710. VOID
  711. RmDeinitializeRm(VOID);
  712. VOID
  713. RmInitializeHeader(
  714. IN PRM_OBJECT_HEADER pParentObject,
  715. IN PRM_OBJECT_HEADER pObject,
  716. IN UINT Sig,
  717. IN PRM_LOCK pLock,
  718. IN PRM_STATIC_OBJECT_INFO pStaticInfo,
  719. IN const char * szDescription,
  720. IN PRM_STACK_RECORD pSR
  721. );
  722. //
  723. // Object allocation and deallocation APIs
  724. //
  725. VOID
  726. RmDeallocateObject(
  727. IN PRM_OBJECT_HEADER pObject,
  728. IN PRM_STACK_RECORD pSR
  729. );
  730. //
  731. // locking
  732. //
  733. VOID
  734. RmInitializeLock(
  735. IN PRM_LOCK pLock,
  736. IN UINT Level
  737. );
  738. VOID
  739. RmDoWriteLock(
  740. PRM_LOCK pLock,
  741. PRM_STACK_RECORD pSR
  742. );
  743. #if TODO
  744. VOID
  745. RmDoReadLock(
  746. IN PRM_OBJECT_HEADER pObj,
  747. IN PRM_STACK_RECORD pSR
  748. );
  749. #else //!TODO
  750. #define RmDoReadLock RmDoWriteLock
  751. #endif //!TODO
  752. VOID
  753. RmDoUnlock(
  754. PRM_LOCK pLock,
  755. PRM_STACK_RECORD pSR
  756. );
  757. #if TODO
  758. VOID
  759. RmReadLockObject(
  760. IN PRM_OBJECT_HEADER pObj,
  761. #if RM_EXTRA_CHECKING
  762. UINT uLocID,
  763. #endif //RM_EXTRA_CHECKING
  764. IN PRM_STACK_RECORD pSR
  765. );
  766. #else //!TODO
  767. #define RmReadLockObject RmWriteLockObject
  768. #endif //!TODO
  769. VOID
  770. RmWriteLockObject(
  771. IN PRM_OBJECT_HEADER pObj,
  772. #if RM_EXTRA_CHECKING
  773. UINT uLocID,
  774. #endif //RM_EXTRA_CHECKING
  775. IN PRM_STACK_RECORD pSR
  776. );
  777. VOID
  778. RmUnlockObject(
  779. IN PRM_OBJECT_HEADER pObj,
  780. IN PRM_STACK_RECORD pSR
  781. );
  782. VOID
  783. RmUnlockAll(
  784. IN PRM_STACK_RECORD pSR
  785. );
  786. VOID
  787. RmDbgChangeLockScope(
  788. IN PRM_OBJECT_HEADER pPreviouslyLockedObject,
  789. IN PRM_OBJECT_HEADER pObject,
  790. IN ULONG LocID,
  791. IN PRM_STACK_RECORD
  792. );
  793. //
  794. // reference counting
  795. //
  796. VOID
  797. RmLinkObjects(
  798. IN PRM_OBJECT_HEADER pObj1,
  799. IN PRM_OBJECT_HEADER pObj2,
  800. IN PRM_STACK_RECORD pSr
  801. );
  802. VOID
  803. RmUnlinkObjects(
  804. IN PRM_OBJECT_HEADER pObj1,
  805. IN PRM_OBJECT_HEADER pObj2,
  806. IN PRM_STACK_RECORD pSr
  807. );
  808. VOID
  809. RmLinkObjectsEx(
  810. IN PRM_OBJECT_HEADER pObj1,
  811. IN PRM_OBJECT_HEADER pObj2,
  812. IN ULONG LocID,
  813. IN ULONG AssocID,
  814. IN const char * szAssociationFormat,
  815. IN ULONG InvAssocID,
  816. IN const char * szInvAssociationFormat,
  817. IN PRM_STACK_RECORD pSR
  818. );
  819. VOID
  820. RmUnlinkObjectsEx(
  821. IN PRM_OBJECT_HEADER pObj1,
  822. IN PRM_OBJECT_HEADER pObj2,
  823. IN ULONG LocID,
  824. IN ULONG AssocID,
  825. IN ULONG InvAssocID,
  826. IN PRM_STACK_RECORD pSR
  827. );
  828. VOID
  829. RmLinkToExternalEx(
  830. IN PRM_OBJECT_HEADER pObj,
  831. IN ULONG LocID,
  832. IN UINT_PTR ExternalEntity,
  833. IN ULONG AssocID,
  834. IN const char * szAssociationFormat,
  835. IN PRM_STACK_RECORD pSR
  836. );
  837. VOID
  838. RmUnlinkFromExternalEx(
  839. IN PRM_OBJECT_HEADER pObj,
  840. IN ULONG LocID,
  841. IN UINT_PTR ExternalEntity,
  842. IN ULONG AssocID,
  843. IN PRM_STACK_RECORD pSR
  844. );
  845. VOID
  846. RmLinkToExternalFast( // TODO make inline
  847. IN PRM_OBJECT_HEADER pObj
  848. );
  849. VOID
  850. RmUnlinkFromExternalFast( // TODO make inline
  851. IN PRM_OBJECT_HEADER pObj
  852. );
  853. VOID
  854. RmTmpReferenceObject(
  855. IN PRM_OBJECT_HEADER pObj,
  856. IN PRM_STACK_RECORD pSR
  857. );
  858. VOID
  859. RmTmpDereferenceObject(
  860. IN PRM_OBJECT_HEADER pObj,
  861. IN PRM_STACK_RECORD pSR
  862. );
  863. //
  864. // Generic resource management
  865. //
  866. RM_STATUS
  867. RmLoadGenericResource(
  868. IN PRM_OBJECT_HEADER pObj,
  869. IN UINT GenericResourceID,
  870. IN PRM_STACK_RECORD pSR
  871. );
  872. VOID
  873. RmUnloadGenericResource(
  874. IN PRM_OBJECT_HEADER pObj,
  875. IN UINT GenericResourceID,
  876. IN PRM_STACK_RECORD pSR
  877. );
  878. VOID
  879. RmUnloadAllGenericResources(
  880. IN PRM_OBJECT_HEADER pObj,
  881. IN PRM_STACK_RECORD pSR
  882. );
  883. //
  884. // Diagnostic per-object tracking of arbitrary "associations"
  885. //
  886. //
  887. // NOTE: AssociationID must not have the high-bit set. Associations with the
  888. // high bit set are reserved for internal use of the Rm API implementation.
  889. //
  890. VOID
  891. RmDbgAddAssociation(
  892. IN ULONG LocID,
  893. IN PRM_OBJECT_HEADER pObject,
  894. IN ULONG_PTR Instance1,
  895. IN ULONG_PTR Instance2,
  896. IN ULONG AssociationID,
  897. IN const char * szFormatString, OPTIONAL
  898. IN PRM_STACK_RECORD pSR
  899. );
  900. VOID
  901. RmDbgDeleteAssociation(
  902. IN ULONG LocID,
  903. IN PRM_OBJECT_HEADER pObject,
  904. IN ULONG_PTR Entity1,
  905. IN ULONG_PTR Entity2,
  906. IN ULONG AssociationID,
  907. IN PRM_STACK_RECORD pSR
  908. );
  909. VOID
  910. RmDbgPrintAssociations(
  911. IN PRM_OBJECT_HEADER pObject,
  912. IN PRM_STACK_RECORD pSR
  913. );
  914. //
  915. // Diagnostic per-object logging.
  916. //
  917. VOID
  918. RmDbgLogToObject(
  919. IN PRM_OBJECT_HEADER pObject,
  920. IN char * szPrefix, OPTIONAL
  921. IN char * szFormatString,
  922. IN UINT_PTR Param1,
  923. IN UINT_PTR Param2,
  924. IN UINT_PTR Param3,
  925. IN UINT_PTR Param4,
  926. IN PFN_DBG_DUMP_LOG_ENTRY pfnDumpEntry, OPTIONAL
  927. IN PVOID pvBuf OPTIONAL
  928. );
  929. VOID
  930. RmDbgPrintObjectLog(
  931. IN PRM_OBJECT_HEADER pObject
  932. );
  933. VOID
  934. RmDbgPrintGlobalLog(VOID);
  935. //
  936. // Groups of Objects
  937. //
  938. VOID
  939. RmInitializeGroup(
  940. IN PRM_OBJECT_HEADER pOwningObject,
  941. IN PRM_STATIC_OBJECT_INFO pStaticInfo,
  942. IN PRM_GROUP pGroup,
  943. IN const char* szDescription,
  944. IN PRM_STACK_RECORD pSR
  945. );
  946. VOID
  947. RmDeinitializeGroup(
  948. IN PRM_GROUP pGroup,
  949. IN PRM_STACK_RECORD pSR
  950. );
  951. RM_STATUS
  952. RmLookupObjectInGroup(
  953. IN PRM_GROUP pGroup,
  954. IN ULONG Flags, // Lookup flags defined below
  955. IN PVOID pvKey,
  956. IN PVOID pvCreateParams,
  957. OUT PRM_OBJECT_HEADER * ppObject,
  958. OUT INT * pfCreated,
  959. IN PRM_STACK_RECORD pSR
  960. );
  961. //
  962. // Lookup flags
  963. //
  964. #define RM_CREATE 0x1
  965. #define RM_NEW (0x1<<1)
  966. #define RM_LOCKED (0x1<<2)
  967. #define RM_CREATE_AND_LOCK_OBJECT_IN_GROUP(_pGrp, _pKey, _pParams, _ppHdr, _fC,_psr)\
  968. RmLookupObjectInGroup( \
  969. (_pGrp), \
  970. RM_CREATE|RM_NEW|RM_LOCKED, \
  971. (_pKey), \
  972. (_pParams), \
  973. (_ppHdr), \
  974. (_fC), \
  975. (_psr) \
  976. );
  977. // RM_STATUS
  978. // RM_LOOKUP_AND_LOCK_OBJECT_IN_GROUP(
  979. // PRM_GROUP _pGrp,
  980. // PVOID _pKey,
  981. // PRM_OBJECT_HEADER * _ppHdr,
  982. // PRM_STACK_RECORD _psr
  983. // )
  984. // Lookup (don't create) and lock an object in the specified group.
  985. //
  986. #define RM_LOOKUP_AND_LOCK_OBJECT_IN_GROUP(_pGrp, _pKey, _ppHdr, _psr) \
  987. RmLookupObjectInGroup( \
  988. (_pGrp), \
  989. RM_LOCKED, \
  990. (_pKey), \
  991. NULL, \
  992. (_ppHdr), \
  993. NULL, \
  994. (_psr) \
  995. );
  996. RM_STATUS
  997. RmGetNextObjectInGroup(
  998. IN PRM_GROUP pGroup,
  999. IN PRM_OBJECT_HEADER pCurrentObject, OPTIONAL
  1000. OUT PRM_OBJECT_HEADER * ppNextObject,
  1001. IN PRM_STACK_RECORD pSR
  1002. );
  1003. VOID
  1004. RmFreeObjectInGroup(
  1005. IN PRM_GROUP pGroup,
  1006. IN PRM_OBJECT_HEADER pObject,
  1007. IN struct _RM_TASK *pTask, OPTIONAL
  1008. IN PRM_STACK_RECORD pSR
  1009. );
  1010. VOID
  1011. RmFreeAllObjectsInGroup(
  1012. IN PRM_GROUP pGroup,
  1013. IN struct _RM_TASK *pTask, OPTIONAL
  1014. IN PRM_STACK_RECORD pSR
  1015. );
  1016. VOID
  1017. RmUnloadAllObjectsInGroup(
  1018. IN PRM_GROUP pGroup,
  1019. PFN_RM_TASK_ALLOCATOR pfnUnloadTaskAllocator,
  1020. PFN_RM_TASK_HANDLER pfnUnloadTaskHandler,
  1021. PVOID pvUserParam,
  1022. IN struct _RM_TASK *pTask, OPTIONAL
  1023. IN UINT uTaskPendCode, OPTIONAL
  1024. IN PRM_STACK_RECORD pSR
  1025. );
  1026. VOID
  1027. RmEnableGroup(
  1028. IN PRM_GROUP pGroup,
  1029. IN PRM_STACK_RECORD pSR
  1030. );
  1031. // Enumeration function prototype. This function is passed into
  1032. // RmEnumerateObjectsInGroup and gets called for each object in the group
  1033. // until the function returns FALSE.
  1034. //
  1035. typedef
  1036. INT
  1037. (*PFN_RM_GROUP_ENUMERATOR) (
  1038. PRM_OBJECT_HEADER pHdr,
  1039. PVOID pvContext,
  1040. PRM_STACK_RECORD pSR
  1041. );
  1042. VOID
  1043. RmEnumerateObjectsInGroup(
  1044. PRM_GROUP pGroup,
  1045. PFN_RM_GROUP_ENUMERATOR pfnFunction,
  1046. PVOID pvContext,
  1047. INT fStrong,
  1048. PRM_STACK_RECORD pSR
  1049. );
  1050. VOID
  1051. RmWeakEnumerateObjectsInGroup(
  1052. PRM_GROUP pGroup,
  1053. PFN_RM_GROUP_ENUMERATOR pfnFunction,
  1054. PVOID pvContext,
  1055. PRM_STACK_RECORD pSR
  1056. );
  1057. //
  1058. // Task APIs
  1059. //
  1060. VOID
  1061. RmInitializeTask(
  1062. IN PRM_TASK pTask,
  1063. IN PRM_OBJECT_HEADER pParentObject,
  1064. IN PFN_RM_TASK_HANDLER pfnHandler,
  1065. IN PRM_STATIC_OBJECT_INFO pStaticInfo, OPTIONAL
  1066. IN const char * szDescription, OPTIONAL
  1067. IN UINT Timeout,
  1068. IN PRM_STACK_RECORD pSR
  1069. );
  1070. RM_STATUS
  1071. RmStartTask(
  1072. IN PRM_TASK pTask,
  1073. IN UINT_PTR UserParam,
  1074. IN PRM_STACK_RECORD pSR
  1075. );
  1076. VOID
  1077. RmAbortTask(
  1078. IN PRM_TASK pTask,
  1079. IN PRM_STACK_RECORD pSR
  1080. );
  1081. VOID
  1082. RmDbgDumpTask(
  1083. IN PRM_TASK pTask,
  1084. IN PRM_STACK_RECORD pSR
  1085. );
  1086. RM_STATUS
  1087. RmSuspendTask(
  1088. IN PRM_TASK pTask,
  1089. IN UINT SuspendContext,
  1090. IN PRM_STACK_RECORD pSR
  1091. );
  1092. VOID
  1093. RmUnsuspendTask(
  1094. IN PRM_TASK pTask,
  1095. IN PRM_STACK_RECORD pSR
  1096. );
  1097. VOID
  1098. RmResumeTask(
  1099. IN PRM_TASK pTask,
  1100. IN UINT_PTR SuspendCompletionParam,
  1101. IN PRM_STACK_RECORD pSR
  1102. );
  1103. VOID
  1104. RmResumeTaskAsync(
  1105. IN PRM_TASK pTask,
  1106. IN UINT_PTR SuspendCompletionParam,
  1107. IN OS_WORK_ITEM * pOsWorkItem,
  1108. IN PRM_STACK_RECORD pSR
  1109. );
  1110. VOID
  1111. RmResumeTaskDelayed(
  1112. IN PRM_TASK pTask,
  1113. IN UINT_PTR SuspendCompletionParam,
  1114. IN ULONG MsDelay,
  1115. IN OS_TIMER * pOsTimerObject,
  1116. IN PRM_STACK_RECORD pSR
  1117. );
  1118. VOID
  1119. RmResumeDelayedTaskNow(
  1120. IN PRM_TASK pTask,
  1121. IN OS_TIMER * pOsTimer,
  1122. OUT PUINT pTaskResumed,
  1123. IN PRM_STACK_RECORD pSR
  1124. );
  1125. RM_STATUS
  1126. RmPendTaskOnOtherTask(
  1127. IN PRM_TASK pTask,
  1128. IN UINT SuspendContext,
  1129. IN PRM_TASK pOtherTask,
  1130. IN PRM_STACK_RECORD pSR
  1131. );
  1132. // See 03/26/1999 notes.txt entry "Some proposed ..."
  1133. //
  1134. RM_STATUS
  1135. RmPendOnOtherTaskV2(
  1136. IN PRM_TASK pTask,
  1137. IN UINT SuspendContext,
  1138. IN PRM_TASK pOtherTask,
  1139. IN PRM_STACK_RECORD pSR
  1140. );
  1141. VOID
  1142. RmCancelPendOnOtherTask(
  1143. IN PRM_TASK pTask,
  1144. IN PRM_TASK pOtherTask,
  1145. IN UINT_PTR UserParam,
  1146. IN PRM_STACK_RECORD pSR
  1147. );
  1148. //
  1149. // Timer management
  1150. //
  1151. VOID
  1152. RmResetAgeingTimer(
  1153. IN PRM_OBJECT_HEADER pObj,
  1154. IN UINT Timeout,
  1155. IN PRM_STACK_RECORD pSR
  1156. );
  1157. //
  1158. // Hash table manipulation.
  1159. //
  1160. VOID
  1161. RmInitializeHashTable(
  1162. PRM_HASH_INFO pHashInfo,
  1163. PVOID pAllocationContext,
  1164. PRM_HASH_TABLE pHashTable
  1165. );
  1166. VOID
  1167. RmDeinitializeHashTable(
  1168. PRM_HASH_TABLE pHashTable
  1169. );
  1170. BOOLEAN
  1171. RmLookupHashTable(
  1172. PRM_HASH_TABLE pHashTable,
  1173. PRM_HASH_LINK ** pppLink,
  1174. PVOID pvRealKey
  1175. );
  1176. BOOLEAN
  1177. RmNextHashTableItem(
  1178. PRM_HASH_TABLE pHashTable,
  1179. PRM_HASH_LINK pCurrentLink, // OPTIONAL
  1180. PRM_HASH_LINK * ppNextLink
  1181. );
  1182. VOID
  1183. RmAddHashItem(
  1184. PRM_HASH_TABLE pHashTable,
  1185. PRM_HASH_LINK * ppLink,
  1186. PRM_HASH_LINK pLink,
  1187. PVOID pvKey
  1188. );
  1189. VOID
  1190. RmRemoveHashItem(
  1191. PRM_HASH_TABLE pHashTable,
  1192. PRM_HASH_LINK pLinkToRemove
  1193. );
  1194. typedef
  1195. VOID
  1196. (*PFN_ENUM_HASH_TABLE)
  1197. (
  1198. PRM_HASH_LINK pLink,
  1199. PVOID pvContext,
  1200. PRM_STACK_RECORD pSR
  1201. );
  1202. VOID
  1203. RmEnumHashTable(
  1204. PRM_HASH_TABLE pHashTable,
  1205. PFN_ENUM_HASH_TABLE pfnEnumerator,
  1206. PVOID pvContext,
  1207. PRM_STACK_RECORD pSR
  1208. );
  1209. #if OBSOLETE
  1210. //
  1211. // Indexes of objects.
  1212. //
  1213. RM_STATUS
  1214. RmAllocateObjectIndex(
  1215. IN PRM_OBJECT_HEADER pParentObject,
  1216. // OBSOLETE IN PRM_OBJECT_ALLOCATOR pObjectAllocator,
  1217. IN PRM_STATIC_OBJECT_INFO pStaticInfo,
  1218. IN PULONG Flags,
  1219. OUT PRM_OBJECT_INDEX * ppObjectIndex,
  1220. IN PRM_STACK_RECORD pSR
  1221. );
  1222. VOID
  1223. RmFreeObjectIndex(
  1224. IN PRM_OBJECT_INDEX pObjectIndex,
  1225. IN PRM_STACK_RECORD pSR
  1226. );
  1227. RM_STATUS
  1228. RmLookupObjectInIndex(
  1229. IN PRM_OBJECT_INDEX pObjectIndex,
  1230. IN PULONG Flags, // create, remove, lock
  1231. IN PVOID pvKey,
  1232. OUT PRM_OBJECT_HEADER * ppObject,
  1233. IN PRM_STACK_RECORD pSR
  1234. );
  1235. RM_STATUS
  1236. RmRemoveObjectFromIndex(
  1237. IN PRM_OBJECT_INDEX pObjectIndex,
  1238. IN PRM_OBJECT_HEADER pObject,
  1239. IN PRM_STACK_RECORD pSR
  1240. );
  1241. typedef
  1242. RM_STATUS
  1243. (*PFN_RM_OBJECT_INDEX_ENUMERATOR)(
  1244. IN PRM_OBJECT_HEADER pObject,
  1245. IN PVOID pvContext,
  1246. IN PRM_STACK_RECORD pSR
  1247. );
  1248. RmEnumerateObjectsInIndex(
  1249. IN PRM_OBJECT_INDEX pObjectIndex,
  1250. IN PFN_RM_OBJECT_INDEX_ENUMERATOR
  1251. pfnEnumerator,
  1252. IN PRM_STACK_RECORD pSR
  1253. );
  1254. #endif // OBSOLETE