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.

1548 lines
40 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. } RM_OBJECT_HEADER, *PRM_OBJECT_HEADER;
  484. //
  485. // Diagnostic resource tracking.
  486. //
  487. typedef struct
  488. {
  489. ULONG_PTR Instance;
  490. ULONG TypeUID;
  491. PRM_OBJECT_HEADER pParentObject;
  492. ULONG CallersUID;
  493. ULONG CallersSrUID;
  494. } RM_DBG_RESOURCE_ENTRY;
  495. typedef enum
  496. {
  497. RM_RESOURCE_OP_LOAD,
  498. RM_RESOURCE_OP_UNLOAD
  499. } RM_RESOURCE_OPERATION;
  500. typedef
  501. RM_STATUS
  502. (*PFN_RM_RESOURCE_HANDLER)(
  503. PRM_OBJECT_HEADER pObj,
  504. RM_RESOURCE_OPERATION Op,
  505. PVOID pvUserParams,
  506. PRM_STACK_RECORD psr
  507. );
  508. typedef struct _RM_RESOURCE_TABLE_ENTRY
  509. {
  510. UINT ID;
  511. PFN_RM_RESOURCE_HANDLER pfnHandler;
  512. } RM_RESOURCE_TABLE_ENTRY, *PRM_RESOURCE_TABLE_ENTRY;
  513. typedef struct
  514. {
  515. UINT u;
  516. } RM_OBJECT_INDEX, *PRM_OBJECT_INDEX;
  517. typedef struct
  518. {
  519. PRM_OBJECT_HEADER pOwningObject;
  520. const char * szDescription;
  521. PRM_STATIC_OBJECT_INFO pStaticInfo;
  522. RM_HASH_TABLE HashTable;
  523. // Private lock used ONLY by group access functions.
  524. //
  525. RM_OS_LOCK OsLock;
  526. // When non-NULL, points to the task responsible for unloading all objects
  527. // in this group.
  528. //
  529. PRM_TASK pUnloadTask;
  530. BOOLEAN fEnabled;
  531. } RM_GROUP, *PRM_GROUP;
  532. typedef enum
  533. {
  534. RM_TASKOP_START,
  535. RM_TASKOP_PENDCOMPLETE,
  536. RM_TASKOP_END,
  537. RM_TASKOP_PRIVATE,
  538. RM_TASKOP_ABORT,
  539. RM_TASKOP_TIMEOUT
  540. } RM_TASK_OPERATION;
  541. typedef
  542. RM_STATUS
  543. (*PFN_RM_TASK_HANDLER)(
  544. IN struct _RM_TASK * pTask,
  545. IN RM_TASK_OPERATION Op,
  546. IN UINT_PTR UserParam,
  547. IN PRM_STACK_RECORD pSR
  548. );
  549. //
  550. // For START and PENDCOMPLETE, a return value other than PENDING causes
  551. // the task to end. Of course, it is illegal to return non-pending when
  552. // the task is in a pending state.
  553. //
  554. // Task allocator prototype
  555. //
  556. typedef
  557. RM_STATUS
  558. (*PFN_RM_TASK_ALLOCATOR)(
  559. IN PRM_OBJECT_HEADER pParentObject,
  560. IN PFN_RM_TASK_HANDLER pfnHandler,
  561. IN UINT Timeout,
  562. IN const char * szDescription,
  563. OUT PRM_TASK *ppTask,
  564. IN PRM_STACK_RECORD pSR
  565. );
  566. typedef struct _RM_TASK
  567. {
  568. RM_OBJECT_HEADER Hdr;
  569. PFN_RM_TASK_HANDLER pfnHandler;
  570. LIST_ENTRY linkFellowPendingTasks;
  571. LIST_ENTRY listTasksPendingOnMe;
  572. struct _RM_TASK * pTaskIAmPendingOn;
  573. // In the case that we need to asynchronously notify the completion of a
  574. // pending operation, we can save the completion param here.
  575. //
  576. UINT_PTR AsyncCompletionParam;
  577. UINT SuspendContext;
  578. } RM_TASK, *PRM_TASK;
  579. typedef
  580. VOID
  581. (_cdecl *PFN_DBG_DUMP_LOG_ENTRY) (
  582. char *szFormatString,
  583. UINT_PTR Param1,
  584. UINT_PTR Param2,
  585. UINT_PTR Param3,
  586. UINT_PTR Param4
  587. );
  588. #if RM_EXTRA_CHECKING
  589. // (For debugging only)
  590. // Keeps track of a single association (See RmDbgAddAssociation)
  591. // This is a PRIVATE data structure, and is only here because
  592. // the kd extension refers to it.
  593. //
  594. typedef struct
  595. {
  596. ULONG LocID;
  597. ULONG_PTR Entity1;
  598. ULONG_PTR Entity2;
  599. ULONG AssociationID;
  600. const char * szFormatString;
  601. RM_HASH_LINK HashLink;
  602. } RM_PRIVATE_DBG_ASSOCIATION;
  603. // (For debugging only)
  604. // Keeps track of a single per-object log entry.
  605. // This is a PRIVATE data structure, and is only here because
  606. // the kd extension refers to it.
  607. //
  608. typedef struct
  609. {
  610. // Link to other entries for this object
  611. //
  612. LIST_ENTRY linkObjectLog;
  613. // Link to other entries in the global list.
  614. //
  615. LIST_ENTRY linkGlobalLog;
  616. // Object this entry belongs to
  617. //
  618. PRM_OBJECT_HEADER pObject;
  619. // Function to be used for dumping the log.
  620. //
  621. PFN_DBG_DUMP_LOG_ENTRY pfnDumpEntry;
  622. // Prefix string to be dumped *before* the log display.
  623. // This was added so we could log associations properly, otherwise it's
  624. // extra baggage. Can be null.
  625. //
  626. char *szPrefix;
  627. // Format string for log display -- 1st arg to pfnDumpEntry
  628. //
  629. char *szFormatString;
  630. // Remaining args to pfnDumpEntry;
  631. //
  632. //
  633. UINT_PTR Param1;
  634. UINT_PTR Param2;
  635. UINT_PTR Param3;
  636. UINT_PTR Param4;
  637. // If non-NULL, piece of memory to be freed when the log entry is freed.
  638. // TODO: See notes.txt entry "03/07/1999 ... Registering root objects with RM"
  639. // on how we will find the deallocator function. For now we simply
  640. // use NdisFreeMemory.
  641. //
  642. PVOID pvBuf;
  643. } RM_DBG_LOG_ENTRY;
  644. #endif RM_EXTRA_CHECKING
  645. //=================================================================================
  646. // U T I L I T Y M A C R O S
  647. //=================================================================================
  648. #define RM_PARENT_OBJECT(_pObj) \
  649. ((_pObj)->Hdr.pParentObject)
  650. #define RM_PEND_CODE(_pTask) \
  651. ((_pTask)->SuspendContext)
  652. #define RM_ASSERT_SAME_LOCK_AS_PARENT(_pObj) \
  653. ASSERTEX( \
  654. ((_pObj)->Hdr.pLock == (_pObj)->Hdr.pParentObject->pLock), \
  655. (_pObj))
  656. #define RM_SET_STATE(_pObj, _Mask, _Val) \
  657. (((_pObj)->Hdr.State) = (((_pObj)->Hdr.State) & ~(_Mask)) | (_Val))
  658. #define RM_CHECK_STATE(_pObj, _Mask, _Val) \
  659. ((((_pObj)->Hdr.State) & (_Mask)) == (_Val))
  660. #define RM_GET_STATE(_pObj, _Mask) \
  661. (((_pObj)->Hdr.State) & (_Mask))
  662. // Asserts that the object is in the "zombie" state, i.e., it
  663. // lives on just because of references.
  664. // WARNING: It is upto the caller to synchronize access to this -- for example
  665. // if they're going to do thing's like if (!RM_IS_ZOMBIE(pObj)) {do-stuff}, they
  666. // had better make sure that only one of them goes on to "does-stuff".
  667. //
  668. #define RM_IS_ZOMBIE(_pobj) \
  669. (((_pobj)->Hdr.RmState&RMOBJSTATE_ALLOCMASK)==RMOBJSTATE_DEALLOCATED)
  670. // Asserts that no locks are held.
  671. //
  672. #define RM_ASSERT_NOLOCKS(_psr) \
  673. ASSERTEX((_psr)->LockInfo.CurrentLevel == 0, (_psr))
  674. // Assert that no locks or tmprefs are held.
  675. //
  676. #define RM_ASSERT_CLEAR(_psr) \
  677. ASSERTEX(((_psr)->LockInfo.CurrentLevel==0) && (_psr)->TmpRefs==0, (_psr))
  678. #if RM_EXTRA_CHECKING
  679. //
  680. // TODO: rename the following to something better...
  681. //
  682. #define RM_DBG_ASSERT_LOCKED0(_pLk, _pSR) \
  683. ASSERTEX((_pLk)->DbgInfo.pSR == (_pSR), (_pHdr))
  684. // TODO -- replace calls to this by calls to RM_ASSERT_OBJLOCKED
  685. #define RM_DBG_ASSERT_LOCKED(_pHdr, _pSR) \
  686. ASSERTEX((_pHdr)->pLock->DbgInfo.pSR == (_pSR), (_pHdr))
  687. #define RM_ASSERT_OBJLOCKED(_pHdr, _pSR) \
  688. ASSERTEX((_pHdr)->pLock->DbgInfo.pSR == (_pSR), (_pHdr))
  689. // Note that we can't assume DbgInfo.pSR is NULL below (it could be locked
  690. // by some other thread), but we CAN assert that DbgInfo.pSR is not equal to the
  691. // current pSR!
  692. //
  693. #define RM_ASSERT_OBJUNLOCKED(_pHdr, _pSR) \
  694. ASSERTEX((_pHdr)->pLock->DbgInfo.pSR != (_pSR), (_pHdr))
  695. #else // !RM_EXTRA_CHECKING
  696. #define RM_DBG_ASSERT_LOCKED0(_pLk, _pSR) (0)
  697. #define RM_DBG_ASSERT_LOCKED(_pHdr, _pSR) (0)
  698. #define RM_ASSERT_OBJLOCKED(_pHdr, _pSR) (0)
  699. #define RM_ASSERT_OBJUNLOCKED(_pHdr, _pSR) (0)
  700. #endif // !RM_EXTRA_CHECKING
  701. #define RM_NUM_ITEMS_IN_GROUP(_pGroup) \
  702. ((_pGroup)->HashTable.NumItems)
  703. //=================================================================================
  704. // F U N C T I O N P R O T O T Y P E S
  705. //=================================================================================
  706. VOID
  707. RmInitializeRm(VOID);
  708. VOID
  709. RmDeinitializeRm(VOID);
  710. VOID
  711. RmInitializeHeader(
  712. IN PRM_OBJECT_HEADER pParentObject,
  713. IN PRM_OBJECT_HEADER pObject,
  714. IN UINT Sig,
  715. IN PRM_LOCK pLock,
  716. IN PRM_STATIC_OBJECT_INFO pStaticInfo,
  717. IN const char * szDescription,
  718. IN PRM_STACK_RECORD pSR
  719. );
  720. //
  721. // Object allocation and deallocation APIs
  722. //
  723. VOID
  724. RmDeallocateObject(
  725. IN PRM_OBJECT_HEADER pObject,
  726. IN PRM_STACK_RECORD pSR
  727. );
  728. //
  729. // locking
  730. //
  731. VOID
  732. RmInitializeLock(
  733. IN PRM_LOCK pLock,
  734. IN UINT Level
  735. );
  736. VOID
  737. RmDoWriteLock(
  738. PRM_LOCK pLock,
  739. PRM_STACK_RECORD pSR
  740. );
  741. #if TODO
  742. VOID
  743. RmDoReadLock(
  744. IN PRM_OBJECT_HEADER pObj,
  745. IN PRM_STACK_RECORD pSR
  746. );
  747. #else //!TODO
  748. #define RmDoReadLock RmDoWriteLock
  749. #endif //!TODO
  750. VOID
  751. RmDoUnlock(
  752. PRM_LOCK pLock,
  753. PRM_STACK_RECORD pSR
  754. );
  755. #if TODO
  756. VOID
  757. RmReadLockObject(
  758. IN PRM_OBJECT_HEADER pObj,
  759. #if RM_EXTRA_CHECKING
  760. UINT uLocID,
  761. #endif //RM_EXTRA_CHECKING
  762. IN PRM_STACK_RECORD pSR
  763. );
  764. #else //!TODO
  765. #define RmReadLockObject RmWriteLockObject
  766. #endif //!TODO
  767. VOID
  768. RmWriteLockObject(
  769. IN PRM_OBJECT_HEADER pObj,
  770. #if RM_EXTRA_CHECKING
  771. UINT uLocID,
  772. #endif //RM_EXTRA_CHECKING
  773. IN PRM_STACK_RECORD pSR
  774. );
  775. VOID
  776. RmUnlockObject(
  777. IN PRM_OBJECT_HEADER pObj,
  778. IN PRM_STACK_RECORD pSR
  779. );
  780. VOID
  781. RmUnlockAll(
  782. IN PRM_STACK_RECORD pSR
  783. );
  784. VOID
  785. RmDbgChangeLockScope(
  786. IN PRM_OBJECT_HEADER pPreviouslyLockedObject,
  787. IN PRM_OBJECT_HEADER pObject,
  788. IN ULONG LocID,
  789. IN PRM_STACK_RECORD
  790. );
  791. //
  792. // reference counting
  793. //
  794. VOID
  795. RmLinkObjects(
  796. IN PRM_OBJECT_HEADER pObj1,
  797. IN PRM_OBJECT_HEADER pObj2,
  798. IN PRM_STACK_RECORD pSr
  799. );
  800. VOID
  801. RmUnlinkObjects(
  802. IN PRM_OBJECT_HEADER pObj1,
  803. IN PRM_OBJECT_HEADER pObj2,
  804. IN PRM_STACK_RECORD pSr
  805. );
  806. VOID
  807. RmLinkObjectsEx(
  808. IN PRM_OBJECT_HEADER pObj1,
  809. IN PRM_OBJECT_HEADER pObj2,
  810. IN ULONG LocID,
  811. IN ULONG AssocID,
  812. IN const char * szAssociationFormat,
  813. IN ULONG InvAssocID,
  814. IN const char * szInvAssociationFormat,
  815. IN PRM_STACK_RECORD pSR
  816. );
  817. VOID
  818. RmUnlinkObjectsEx(
  819. IN PRM_OBJECT_HEADER pObj1,
  820. IN PRM_OBJECT_HEADER pObj2,
  821. IN ULONG LocID,
  822. IN ULONG AssocID,
  823. IN ULONG InvAssocID,
  824. IN PRM_STACK_RECORD pSR
  825. );
  826. VOID
  827. RmLinkToExternalEx(
  828. IN PRM_OBJECT_HEADER pObj,
  829. IN ULONG LocID,
  830. IN UINT_PTR ExternalEntity,
  831. IN ULONG AssocID,
  832. IN const char * szAssociationFormat,
  833. IN PRM_STACK_RECORD pSR
  834. );
  835. VOID
  836. RmUnlinkFromExternalEx(
  837. IN PRM_OBJECT_HEADER pObj,
  838. IN ULONG LocID,
  839. IN UINT_PTR ExternalEntity,
  840. IN ULONG AssocID,
  841. IN PRM_STACK_RECORD pSR
  842. );
  843. VOID
  844. RmLinkToExternalFast( // TODO make inline
  845. IN PRM_OBJECT_HEADER pObj
  846. );
  847. VOID
  848. RmUnlinkFromExternalFast( // TODO make inline
  849. IN PRM_OBJECT_HEADER pObj
  850. );
  851. VOID
  852. RmTmpReferenceObject(
  853. IN PRM_OBJECT_HEADER pObj,
  854. IN PRM_STACK_RECORD pSR
  855. );
  856. VOID
  857. RmTmpDereferenceObject(
  858. IN PRM_OBJECT_HEADER pObj,
  859. IN PRM_STACK_RECORD pSR
  860. );
  861. //
  862. // Generic resource management
  863. //
  864. RM_STATUS
  865. RmLoadGenericResource(
  866. IN PRM_OBJECT_HEADER pObj,
  867. IN UINT GenericResourceID,
  868. IN PRM_STACK_RECORD pSR
  869. );
  870. VOID
  871. RmUnloadGenericResource(
  872. IN PRM_OBJECT_HEADER pObj,
  873. IN UINT GenericResourceID,
  874. IN PRM_STACK_RECORD pSR
  875. );
  876. VOID
  877. RmUnloadAllGenericResources(
  878. IN PRM_OBJECT_HEADER pObj,
  879. IN PRM_STACK_RECORD pSR
  880. );
  881. //
  882. // Diagnostic per-object tracking of arbitrary "associations"
  883. //
  884. //
  885. // NOTE: AssociationID must not have the high-bit set. Associations with the
  886. // high bit set are reserved for internal use of the Rm API implementation.
  887. //
  888. VOID
  889. RmDbgAddAssociation(
  890. IN ULONG LocID,
  891. IN PRM_OBJECT_HEADER pObject,
  892. IN ULONG_PTR Instance1,
  893. IN ULONG_PTR Instance2,
  894. IN ULONG AssociationID,
  895. IN const char * szFormatString, OPTIONAL
  896. IN PRM_STACK_RECORD pSR
  897. );
  898. VOID
  899. RmDbgDeleteAssociation(
  900. IN ULONG LocID,
  901. IN PRM_OBJECT_HEADER pObject,
  902. IN ULONG_PTR Entity1,
  903. IN ULONG_PTR Entity2,
  904. IN ULONG AssociationID,
  905. IN PRM_STACK_RECORD pSR
  906. );
  907. VOID
  908. RmDbgPrintAssociations(
  909. IN PRM_OBJECT_HEADER pObject,
  910. IN PRM_STACK_RECORD pSR
  911. );
  912. //
  913. // Diagnostic per-object logging.
  914. //
  915. VOID
  916. RmDbgLogToObject(
  917. IN PRM_OBJECT_HEADER pObject,
  918. IN char * szPrefix, OPTIONAL
  919. IN char * szFormatString,
  920. IN UINT_PTR Param1,
  921. IN UINT_PTR Param2,
  922. IN UINT_PTR Param3,
  923. IN UINT_PTR Param4,
  924. IN PFN_DBG_DUMP_LOG_ENTRY pfnDumpEntry, OPTIONAL
  925. IN PVOID pvBuf OPTIONAL
  926. );
  927. VOID
  928. RmDbgPrintObjectLog(
  929. IN PRM_OBJECT_HEADER pObject
  930. );
  931. VOID
  932. RmDbgPrintGlobalLog(VOID);
  933. //
  934. // Groups of Objects
  935. //
  936. VOID
  937. RmInitializeGroup(
  938. IN PRM_OBJECT_HEADER pOwningObject,
  939. IN PRM_STATIC_OBJECT_INFO pStaticInfo,
  940. IN PRM_GROUP pGroup,
  941. IN const char* szDescription,
  942. IN PRM_STACK_RECORD pSR
  943. );
  944. VOID
  945. RmDeinitializeGroup(
  946. IN PRM_GROUP pGroup,
  947. IN PRM_STACK_RECORD pSR
  948. );
  949. RM_STATUS
  950. RmLookupObjectInGroup(
  951. IN PRM_GROUP pGroup,
  952. IN ULONG Flags, // Lookup flags defined below
  953. IN PVOID pvKey,
  954. IN PVOID pvCreateParams,
  955. OUT PRM_OBJECT_HEADER * ppObject,
  956. OUT INT * pfCreated,
  957. IN PRM_STACK_RECORD pSR
  958. );
  959. //
  960. // Lookup flags
  961. //
  962. #define RM_CREATE 0x1
  963. #define RM_NEW (0x1<<1)
  964. #define RM_LOCKED (0x1<<2)
  965. #define RM_CREATE_AND_LOCK_OBJECT_IN_GROUP(_pGrp, _pKey, _pParams, _ppHdr, _fC,_psr)\
  966. RmLookupObjectInGroup( \
  967. (_pGrp), \
  968. RM_CREATE|RM_NEW|RM_LOCKED, \
  969. (_pKey), \
  970. (_pParams), \
  971. (_ppHdr), \
  972. (_fC), \
  973. (_psr) \
  974. );
  975. // RM_STATUS
  976. // RM_LOOKUP_AND_LOCK_OBJECT_IN_GROUP(
  977. // PRM_GROUP _pGrp,
  978. // PVOID _pKey,
  979. // PRM_OBJECT_HEADER * _ppHdr,
  980. // PRM_STACK_RECORD _psr
  981. // )
  982. // Lookup (don't create) and lock an object in the specified group.
  983. //
  984. #define RM_LOOKUP_AND_LOCK_OBJECT_IN_GROUP(_pGrp, _pKey, _ppHdr, _psr) \
  985. RmLookupObjectInGroup( \
  986. (_pGrp), \
  987. RM_LOCKED, \
  988. (_pKey), \
  989. NULL, \
  990. (_ppHdr), \
  991. NULL, \
  992. (_psr) \
  993. );
  994. RM_STATUS
  995. RmGetNextObjectInGroup(
  996. IN PRM_GROUP pGroup,
  997. IN PRM_OBJECT_HEADER pCurrentObject, OPTIONAL
  998. OUT PRM_OBJECT_HEADER * ppNextObject,
  999. IN PRM_STACK_RECORD pSR
  1000. );
  1001. VOID
  1002. RmFreeObjectInGroup(
  1003. IN PRM_GROUP pGroup,
  1004. IN PRM_OBJECT_HEADER pObject,
  1005. IN struct _RM_TASK *pTask, OPTIONAL
  1006. IN PRM_STACK_RECORD pSR
  1007. );
  1008. VOID
  1009. RmFreeAllObjectsInGroup(
  1010. IN PRM_GROUP pGroup,
  1011. IN struct _RM_TASK *pTask, OPTIONAL
  1012. IN PRM_STACK_RECORD pSR
  1013. );
  1014. VOID
  1015. RmUnloadAllObjectsInGroup(
  1016. IN PRM_GROUP pGroup,
  1017. PFN_RM_TASK_ALLOCATOR pfnUnloadTaskAllocator,
  1018. PFN_RM_TASK_HANDLER pfnUnloadTaskHandler,
  1019. PVOID pvUserParam,
  1020. IN struct _RM_TASK *pTask, OPTIONAL
  1021. IN UINT uTaskPendCode, OPTIONAL
  1022. IN PRM_STACK_RECORD pSR
  1023. );
  1024. VOID
  1025. RmEnableGroup(
  1026. IN PRM_GROUP pGroup,
  1027. IN PRM_STACK_RECORD pSR
  1028. );
  1029. // Enumeration function prototype. This function is passed into
  1030. // RmEnumerateObjectsInGroup and gets called for each object in the group
  1031. // until the function returns FALSE.
  1032. //
  1033. typedef
  1034. INT
  1035. (*PFN_RM_GROUP_ENUMERATOR) (
  1036. PRM_OBJECT_HEADER pHdr,
  1037. PVOID pvContext,
  1038. PRM_STACK_RECORD pSR
  1039. );
  1040. VOID
  1041. RmEnumerateObjectsInGroup(
  1042. PRM_GROUP pGroup,
  1043. PFN_RM_GROUP_ENUMERATOR pfnFunction,
  1044. PVOID pvContext,
  1045. INT fStrong,
  1046. PRM_STACK_RECORD pSR
  1047. );
  1048. VOID
  1049. RmWeakEnumerateObjectsInGroup(
  1050. PRM_GROUP pGroup,
  1051. PFN_RM_GROUP_ENUMERATOR pfnFunction,
  1052. PVOID pvContext,
  1053. PRM_STACK_RECORD pSR
  1054. );
  1055. //
  1056. // Task APIs
  1057. //
  1058. VOID
  1059. RmInitializeTask(
  1060. IN PRM_TASK pTask,
  1061. IN PRM_OBJECT_HEADER pParentObject,
  1062. IN PFN_RM_TASK_HANDLER pfnHandler,
  1063. IN PRM_STATIC_OBJECT_INFO pStaticInfo, OPTIONAL
  1064. IN const char * szDescription, OPTIONAL
  1065. IN UINT Timeout,
  1066. IN PRM_STACK_RECORD pSR
  1067. );
  1068. RM_STATUS
  1069. RmStartTask(
  1070. IN PRM_TASK pTask,
  1071. IN UINT_PTR UserParam,
  1072. IN PRM_STACK_RECORD pSR
  1073. );
  1074. VOID
  1075. RmAbortTask(
  1076. IN PRM_TASK pTask,
  1077. IN PRM_STACK_RECORD pSR
  1078. );
  1079. VOID
  1080. RmDbgDumpTask(
  1081. IN PRM_TASK pTask,
  1082. IN PRM_STACK_RECORD pSR
  1083. );
  1084. RM_STATUS
  1085. RmSuspendTask(
  1086. IN PRM_TASK pTask,
  1087. IN UINT SuspendContext,
  1088. IN PRM_STACK_RECORD pSR
  1089. );
  1090. VOID
  1091. RmUnsuspendTask(
  1092. IN PRM_TASK pTask,
  1093. IN PRM_STACK_RECORD pSR
  1094. );
  1095. VOID
  1096. RmResumeTask(
  1097. IN PRM_TASK pTask,
  1098. IN UINT_PTR SuspendCompletionParam,
  1099. IN PRM_STACK_RECORD pSR
  1100. );
  1101. VOID
  1102. RmResumeTaskAsync(
  1103. IN PRM_TASK pTask,
  1104. IN UINT_PTR SuspendCompletionParam,
  1105. IN OS_WORK_ITEM * pOsWorkItem,
  1106. IN PRM_STACK_RECORD pSR
  1107. );
  1108. VOID
  1109. RmResumeTaskDelayed(
  1110. IN PRM_TASK pTask,
  1111. IN UINT_PTR SuspendCompletionParam,
  1112. IN ULONG MsDelay,
  1113. IN OS_TIMER * pOsTimerObject,
  1114. IN PRM_STACK_RECORD pSR
  1115. );
  1116. VOID
  1117. RmResumeDelayedTaskNow(
  1118. IN PRM_TASK pTask,
  1119. IN OS_TIMER * pOsTimer,
  1120. OUT PUINT pTaskResumed,
  1121. IN PRM_STACK_RECORD pSR
  1122. );
  1123. RM_STATUS
  1124. RmPendTaskOnOtherTask(
  1125. IN PRM_TASK pTask,
  1126. IN UINT SuspendContext,
  1127. IN PRM_TASK pOtherTask,
  1128. IN PRM_STACK_RECORD pSR
  1129. );
  1130. // See 03/26/1999 notes.txt entry "Some proposed ..."
  1131. //
  1132. RM_STATUS
  1133. RmPendOnOtherTaskV2(
  1134. IN PRM_TASK pTask,
  1135. IN UINT SuspendContext,
  1136. IN PRM_TASK pOtherTask,
  1137. IN PRM_STACK_RECORD pSR
  1138. );
  1139. VOID
  1140. RmCancelPendOnOtherTask(
  1141. IN PRM_TASK pTask,
  1142. IN PRM_TASK pOtherTask,
  1143. IN UINT_PTR UserParam,
  1144. IN PRM_STACK_RECORD pSR
  1145. );
  1146. //
  1147. // Timer management
  1148. //
  1149. VOID
  1150. RmResetAgeingTimer(
  1151. IN PRM_OBJECT_HEADER pObj,
  1152. IN UINT Timeout,
  1153. IN PRM_STACK_RECORD pSR
  1154. );
  1155. //
  1156. // Hash table manipulation.
  1157. //
  1158. VOID
  1159. RmInitializeHashTable(
  1160. PRM_HASH_INFO pHashInfo,
  1161. PVOID pAllocationContext,
  1162. PRM_HASH_TABLE pHashTable
  1163. );
  1164. VOID
  1165. RmDeinitializeHashTable(
  1166. PRM_HASH_TABLE pHashTable
  1167. );
  1168. BOOLEAN
  1169. RmLookupHashTable(
  1170. PRM_HASH_TABLE pHashTable,
  1171. PRM_HASH_LINK ** pppLink,
  1172. PVOID pvRealKey
  1173. );
  1174. BOOLEAN
  1175. RmNextHashTableItem(
  1176. PRM_HASH_TABLE pHashTable,
  1177. PRM_HASH_LINK pCurrentLink, // OPTIONAL
  1178. PRM_HASH_LINK * ppNextLink
  1179. );
  1180. VOID
  1181. RmAddHashItem(
  1182. PRM_HASH_TABLE pHashTable,
  1183. PRM_HASH_LINK * ppLink,
  1184. PRM_HASH_LINK pLink,
  1185. PVOID pvKey
  1186. );
  1187. VOID
  1188. RmRemoveHashItem(
  1189. PRM_HASH_TABLE pHashTable,
  1190. PRM_HASH_LINK pLinkToRemove
  1191. );
  1192. typedef
  1193. VOID
  1194. (*PFN_ENUM_HASH_TABLE)
  1195. (
  1196. PRM_HASH_LINK pLink,
  1197. PVOID pvContext,
  1198. PRM_STACK_RECORD pSR
  1199. );
  1200. VOID
  1201. RmEnumHashTable(
  1202. PRM_HASH_TABLE pHashTable,
  1203. PFN_ENUM_HASH_TABLE pfnEnumerator,
  1204. PVOID pvContext,
  1205. PRM_STACK_RECORD pSR
  1206. );
  1207. #if OBSOLETE
  1208. //
  1209. // Indexes of objects.
  1210. //
  1211. RM_STATUS
  1212. RmAllocateObjectIndex(
  1213. IN PRM_OBJECT_HEADER pParentObject,
  1214. // OBSOLETE IN PRM_OBJECT_ALLOCATOR pObjectAllocator,
  1215. IN PRM_STATIC_OBJECT_INFO pStaticInfo,
  1216. IN PULONG Flags,
  1217. OUT PRM_OBJECT_INDEX * ppObjectIndex,
  1218. IN PRM_STACK_RECORD pSR
  1219. );
  1220. VOID
  1221. RmFreeObjectIndex(
  1222. IN PRM_OBJECT_INDEX pObjectIndex,
  1223. IN PRM_STACK_RECORD pSR
  1224. );
  1225. RM_STATUS
  1226. RmLookupObjectInIndex(
  1227. IN PRM_OBJECT_INDEX pObjectIndex,
  1228. IN PULONG Flags, // create, remove, lock
  1229. IN PVOID pvKey,
  1230. OUT PRM_OBJECT_HEADER * ppObject,
  1231. IN PRM_STACK_RECORD pSR
  1232. );
  1233. RM_STATUS
  1234. RmRemoveObjectFromIndex(
  1235. IN PRM_OBJECT_INDEX pObjectIndex,
  1236. IN PRM_OBJECT_HEADER pObject,
  1237. IN PRM_STACK_RECORD pSR
  1238. );
  1239. typedef
  1240. RM_STATUS
  1241. (*PFN_RM_OBJECT_INDEX_ENUMERATOR)(
  1242. IN PRM_OBJECT_HEADER pObject,
  1243. IN PVOID pvContext,
  1244. IN PRM_STACK_RECORD pSR
  1245. );
  1246. RmEnumerateObjectsInIndex(
  1247. IN PRM_OBJECT_INDEX pObjectIndex,
  1248. IN PFN_RM_OBJECT_INDEX_ENUMERATOR
  1249. pfnEnumerator,
  1250. IN PRM_STACK_RECORD pSR
  1251. );
  1252. #endif // OBSOLETE