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.

372 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. RegState.c
  5. Abstract:
  6. This module contains helper functions for maintaining
  7. user mode state for registry objects
  8. Author:
  9. Adam Edwards (adamed) 06-May-1998
  10. Key Functions:
  11. StateObjectInit
  12. StateObjectListInit
  13. StateObjectListIsEmpty
  14. StateObjectListRemove
  15. StateObjectListFind
  16. StateObjectListAdd
  17. StateObjectListClear
  18. Notes:
  19. The StateObjectList stores the most frequently accessed
  20. objects at the head of the list for quick retrieval. All
  21. objects in the list must inherit from StateObject, and must
  22. be distinguishable by a unique 32-bit key. Duplicate
  23. objects are not supported, so the client must take care
  24. not to store duplicates (two objects with the same key) in
  25. the list.
  26. --*/
  27. #ifdef LOCAL
  28. #include <rpc.h>
  29. #include "regrpc.h"
  30. #include "localreg.h"
  31. #include "regstate.h"
  32. VOID StateObjectInit(
  33. StateObject* pObject,
  34. PVOID pvKey)
  35. /*++
  36. Routine Description:
  37. This function will initialize a StateObject. All objects
  38. which inherit from this must call this function before doing
  39. any custom initialization.
  40. Arguments:
  41. pObject -- the object to initialize.
  42. pvKey -- a unique key for the object used for searches and comparisons
  43. between objects.
  44. Return Value:
  45. None -- the function does nothing which could fail.
  46. --*/
  47. {
  48. RtlZeroMemory(pObject, sizeof(*pObject));
  49. pObject->pvKey = pvKey;
  50. }
  51. VOID StateObjectListInit(
  52. StateObjectList* pList,
  53. PVOID pvKey)
  54. /*++
  55. Routine Description:
  56. This function will initialize a StateObjectList. All objects
  57. which inherit from this must call this function before doing
  58. any custom initialization.
  59. Arguments:
  60. pList -- pointer to list to initialize.
  61. pvKey -- a unique key that identifies the list. This parameter is
  62. necessary since the list itself is a StateObject, which requires a
  63. key. It can be set to 0 if this list will not be searched for
  64. as part of another list, but should be set otherwise to a unique
  65. value.
  66. Return Value:
  67. None -- the function does nothing which could fail.
  68. --*/
  69. {
  70. StateObjectInit(
  71. (StateObject*) pList,
  72. pvKey);
  73. pList->pHead = NULL;
  74. }
  75. BOOL StateObjectListIsEmpty(StateObjectList* pList)
  76. /*++
  77. Routine Description:
  78. This function returns information on whether or not this
  79. list is empty.
  80. Arguments:
  81. pList -- pointer to list in question
  82. Return Value:
  83. TRUE if the list is empty,
  84. FALSE if not.
  85. --*/
  86. {
  87. return NULL == pList->pHead;
  88. }
  89. StateObject* StateObjectListRemove(
  90. StateObjectList* pList,
  91. PVOID pvKey)
  92. /*++
  93. Routine Description:
  94. This function will remove an object from the list --
  95. it does *not* destroy the object.
  96. Arguments:
  97. pList -- the list to remove the object from
  98. pvKey -- a unique key identifying the object to remove
  99. Return Value:
  100. a pointer to the removed object if successful,
  101. NULL otherwise
  102. --*/
  103. {
  104. StateObject* pObject;
  105. //
  106. // First, we need to find an object with the desired key
  107. //
  108. pObject = StateObjectListFind(
  109. pList,
  110. pvKey);
  111. if (!pObject) {
  112. return NULL;
  113. }
  114. //
  115. // Now that we've executed the find, the object is at the front
  116. // of the list -- we can remove it by setting the head to the
  117. // next object in the list
  118. //
  119. pList->pHead = (StateObject*) (pObject->Links.Flink);
  120. //
  121. // Make sure the new head's previous pointer is NULL since it
  122. // has no predecessor
  123. //
  124. if (pList->pHead) {
  125. pList->pHead->Links.Blink = NULL;
  126. }
  127. return pObject;
  128. }
  129. StateObject* StateObjectListFind(
  130. StateObjectList* pList,
  131. PVOID pvKey)
  132. /*++
  133. Routine Description:
  134. This function will find an object in the list
  135. Arguments:
  136. pList -- the list in which to search
  137. pvKey -- a unique key identifying the object sought
  138. Return Value:
  139. a pointer to the object if an object with a key matching pvKey is found,
  140. NULL otherwise
  141. --*/
  142. {
  143. StateObject* pCurrent;
  144. //
  145. // Loop through all objects in the list until we get to the end
  146. //
  147. for (pCurrent = pList->pHead;
  148. pCurrent != NULL;
  149. pCurrent = (StateObject*) pCurrent->Links.Flink)
  150. {
  151. //
  152. // See if this object's key matches the desired key
  153. //
  154. if (pvKey == pCurrent->pvKey) {
  155. PLIST_ENTRY pFlink;
  156. PLIST_ENTRY pBlink;
  157. //
  158. // If the desired object is at the front, this is a no op --
  159. // we don't have to move anything, just return the object
  160. //
  161. if (pCurrent == pList->pHead) {
  162. return pCurrent;
  163. }
  164. //
  165. // We need to move the found object to the front of the list
  166. //
  167. //
  168. // Remove the object from its current position
  169. // by severing its links
  170. //
  171. pBlink = pCurrent->Links.Blink;
  172. pFlink = pCurrent->Links.Flink;
  173. if (pBlink) {
  174. pBlink->Flink = pFlink;
  175. }
  176. if (pFlink) {
  177. pFlink->Blink = pBlink;
  178. }
  179. //
  180. // Re-add it to the front
  181. //
  182. StateObjectListAdd(
  183. pList,
  184. pCurrent);
  185. return pCurrent;
  186. }
  187. }
  188. //
  189. // We never found an object with the desired key above, so its
  190. // not in the list
  191. //
  192. return NULL;
  193. }
  194. VOID StateObjectListAdd(
  195. StateObjectList* pList,
  196. StateObject* pObject)
  197. /*++
  198. Routine Description:
  199. This function will add an object to the list
  200. Arguments:
  201. pList -- the list in which to add the object
  202. pObject -- pointer to an object which has been initialized
  203. with StateObjectInit; this object will be stored in the list.
  204. Return Value:
  205. None -- this function does nothing which could fail.
  206. Note:
  207. Only one object with a particular key should exist in the list. This
  208. requirement is not enforced by this function or the list itself, so
  209. clients need to ensure that they follow this rule.
  210. --*/
  211. {
  212. //
  213. // Create the links between the object and what's currently
  214. // at the front of the list
  215. //
  216. if (pList->pHead) {
  217. pObject->Links.Flink = (PLIST_ENTRY) pList->pHead;
  218. pList->pHead->Links.Blink = (PLIST_ENTRY) pObject;
  219. }
  220. //
  221. // Put the object at the front of the list
  222. //
  223. pList->pHead = pObject;
  224. pList->pHead->Links.Blink = NULL;
  225. }
  226. VOID StateObjectListClear(
  227. StateObjectList* pList,
  228. PFNDestroyObject pfnDestroy)
  229. /*++
  230. Routine Description:
  231. This function will remove and destroy all objects
  232. in the list.
  233. Arguments:
  234. pList -- the list to clear
  235. pfnDestroy -- pointer to a function which will be called for
  236. each object in order to destroy (free resources such as memory,
  237. kernel objects, etc) it.
  238. Return Value:
  239. None -- this function does nothing which could fail.
  240. --*/
  241. {
  242. StateObject* pCurrent;
  243. //
  244. // Keep removing objects until the list is empty
  245. //
  246. while (!StateObjectListIsEmpty(pList))
  247. {
  248. StateObject* pObject;
  249. //
  250. // Remove whatever's at the front of the list
  251. //
  252. pObject = StateObjectListRemove(
  253. pList,
  254. pList->pHead->pvKey);
  255. ASSERT(pObject);
  256. //
  257. // Destroy the removed object
  258. //
  259. pfnDestroy(pObject);
  260. }
  261. }
  262. #endif // LOCAL