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.

390 lines
9.6 KiB

  1. /*++
  2. Copyright (C) 2000 Microsoft Corporation
  3. Module Name:
  4. iterate.c
  5. Abstract:
  6. This module contains routines that iterate over the MM data structures
  7. --*/
  8. #include <precomp.h>
  9. DWORD
  10. IterateClasses(
  11. IN PM_SERVER Server,
  12. IN PVOID ExtraCtxt,
  13. IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
  14. )
  15. {
  16. ARRAY_LOCATION Loc;
  17. DWORD Error;
  18. MM_ITERATE_CTXT Ctxt;
  19. PM_CLASSDEF ClassDef;
  20. Ctxt.ExtraCtxt = ExtraCtxt;
  21. Ctxt.Server = Server;
  22. Error = MemArrayInitLoc( &Server->ClassDefs.ClassDefArray, &Loc );
  23. while( NO_ERROR == Error ) {
  24. Error = MemArrayGetElement(
  25. &Server->ClassDefs.ClassDefArray, &Loc, &ClassDef );
  26. ASSERT( NO_ERROR == Error );
  27. Ctxt.ClassDef = ClassDef;
  28. Error = Callback( &Ctxt );
  29. if( ERROR_KEY_DELETED == Error ) {
  30. //
  31. // Delete this class ..
  32. //
  33. MemArrayDelElement(
  34. &Server->ClassDefs.ClassDefArray, &Loc, &ClassDef );
  35. MemClassDefFree( ClassDef );
  36. Error = MemArrayAdjustLocation(
  37. &Server->ClassDefs.ClassDefArray, &Loc );
  38. } else {
  39. if( NO_ERROR != Error ) return Error;
  40. Error = MemArrayNextLoc(
  41. &Server->ClassDefs.ClassDefArray, &Loc );
  42. }
  43. }
  44. if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
  45. return Error;
  46. }
  47. PM_CLASSDEF
  48. FindClass(
  49. IN PM_SERVER Server,
  50. IN ULONG ClassId
  51. )
  52. {
  53. DWORD Error;
  54. PM_CLASSDEF Class;
  55. if( 0 == ClassId ) return NULL;
  56. Error = MemServerGetClassDef(
  57. Server, ClassId, NULL, 0, NULL, &Class );
  58. ASSERT( NO_ERROR == Error );
  59. if( NO_ERROR == Error ) return Class;
  60. return NULL;
  61. }
  62. DWORD
  63. IterateOptDefs(
  64. IN PM_SERVER Server,
  65. IN PVOID ExtraCtxt,
  66. IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
  67. )
  68. {
  69. ARRAY_LOCATION Loc, Loc2;
  70. DWORD Error;
  71. MM_ITERATE_CTXT Ctxt;
  72. PM_OPTDEF OptDef;
  73. PM_OPTCLASSDEFL_ONE OptClassDefList;
  74. Ctxt.ExtraCtxt = ExtraCtxt;
  75. Ctxt.Server = Server;
  76. Error = MemArrayInitLoc( &Server->OptDefs.Array, &Loc );
  77. while( NO_ERROR == Error ) {
  78. Error = MemArrayGetElement(
  79. &Server->OptDefs.Array, &Loc, &OptClassDefList );
  80. ASSERT( NO_ERROR == Error );
  81. Ctxt.UserClass = FindClass( Server, OptClassDefList->ClassId );
  82. Ctxt.VendorClass = FindClass( Server, OptClassDefList->VendorId );
  83. Error = MemArrayInitLoc(
  84. &OptClassDefList->OptDefList.OptDefArray, &Loc2 );
  85. while( NO_ERROR == Error ) {
  86. Error = MemArrayGetElement(
  87. &OptClassDefList->OptDefList.OptDefArray, &Loc2,
  88. &OptDef );
  89. ASSERT( NO_ERROR == Error );
  90. Ctxt.OptDef = OptDef;
  91. Error = Callback( &Ctxt );
  92. if( ERROR_KEY_DELETED == Error ) {
  93. //
  94. // Delete this optdef..
  95. //
  96. MemArrayDelElement(
  97. &OptClassDefList->OptDefList.OptDefArray,
  98. &Loc2, &OptDef );
  99. MemOptDefFree( OptDef );
  100. Error = MemArrayAdjustLocation(
  101. &OptClassDefList->OptDefList.OptDefArray,
  102. &Loc2 );
  103. } else {
  104. if( NO_ERROR != Error ) return Error;
  105. Error = MemArrayNextLoc(
  106. &OptClassDefList->OptDefList.OptDefArray, &Loc2 );
  107. }
  108. }
  109. if( ERROR_FILE_NOT_FOUND != Error ) return Error;
  110. Error = MemArrayNextLoc( &Server->OptDefs.Array, &Loc );
  111. }
  112. if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
  113. return Error;
  114. }
  115. DWORD
  116. IterateOptionsOnOptClass(
  117. IN PM_SERVER Server,
  118. IN PM_OPTCLASS OptClass,
  119. IN PVOID ExtraCtxt,
  120. IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
  121. )
  122. {
  123. ARRAY_LOCATION Loc, Loc2;
  124. DWORD Error;
  125. MM_ITERATE_CTXT Ctxt;
  126. PM_OPTION Option;
  127. PM_ONECLASS_OPTLIST OptList;
  128. Ctxt.ExtraCtxt = ExtraCtxt;
  129. Ctxt.Server = Server;
  130. Error = MemArrayInitLoc( &OptClass->Array, &Loc );
  131. while( NO_ERROR == Error ) {
  132. Error = MemArrayGetElement(
  133. &OptClass->Array, &Loc, &OptList );
  134. ASSERT( NO_ERROR == Error );
  135. Ctxt.UserClass = FindClass( Server, OptList->ClassId );
  136. Ctxt.VendorClass = FindClass( Server, OptList->VendorId );
  137. Error = MemArrayInitLoc( &OptList->OptList, &Loc2 );
  138. while( NO_ERROR == Error ) {
  139. Error = MemArrayGetElement(
  140. &OptList->OptList, &Loc2, &Option );
  141. ASSERT( NO_ERROR == Error );
  142. Ctxt.Option = Option;
  143. Error = Callback( &Ctxt );
  144. if( NO_ERROR != Error ) return Error;
  145. Error = MemArrayNextLoc( &OptList->OptList, &Loc2 );
  146. }
  147. if( ERROR_FILE_NOT_FOUND != Error ) return Error;
  148. Error = MemArrayNextLoc( &OptClass->Array, &Loc );
  149. }
  150. if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
  151. return Error;
  152. }
  153. DWORD
  154. IterateServerOptions(
  155. IN PM_SERVER Server,
  156. IN PVOID ExtraCtxt,
  157. IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
  158. )
  159. {
  160. return IterateOptionsOnOptClass(
  161. Server, &Server->Options, ExtraCtxt, Callback );
  162. }
  163. DWORD
  164. IterateScopeOptions(
  165. IN PM_SUBNET Subnet,
  166. IN PVOID ExtraCtxt,
  167. IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
  168. )
  169. {
  170. return IterateOptionsOnOptClass(
  171. (PM_SERVER)Subnet->ServerPtr,
  172. &Subnet->Options, ExtraCtxt, Callback );
  173. }
  174. DWORD
  175. IterateReservationOptions(
  176. IN PM_SERVER Server,
  177. IN PM_RESERVATION Res,
  178. IN PVOID ExtraCtxt,
  179. IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
  180. )
  181. {
  182. PM_SUBNET Subnet = NULL;
  183. MemServerGetUAddressInfo(
  184. Server, Res->Address, &Subnet, NULL, NULL, NULL );
  185. return IterateOptionsOnOptClass(
  186. Server, &Res->Options, ExtraCtxt, Callback );
  187. }
  188. PM_SSCOPE
  189. FindSScope(
  190. IN PM_SERVER Server,
  191. IN DWORD SScopeId
  192. )
  193. {
  194. DWORD Error;
  195. PM_SSCOPE SScope;
  196. if( SScopeId == INVALID_SSCOPE_ID ) return NULL;
  197. Error = MemServerFindSScope(
  198. Server, SScopeId, NULL, &SScope );
  199. if( NO_ERROR != Error ) return NULL;
  200. return SScope;
  201. }
  202. DWORD
  203. IterateScopes(
  204. IN PM_SERVER Server,
  205. IN PVOID ExtraCtxt,
  206. IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
  207. )
  208. {
  209. ARRAY_LOCATION Loc;
  210. DWORD Error;
  211. MM_ITERATE_CTXT Ctxt;
  212. PM_SUBNET Scope;
  213. Ctxt.ExtraCtxt = ExtraCtxt;
  214. Ctxt.Server = Server;
  215. Error = MemArrayInitLoc( &Server->Subnets, &Loc );
  216. while( NO_ERROR == Error ) {
  217. Error = MemArrayGetElement(
  218. &Server->Subnets, &Loc, &Scope );
  219. ASSERT( NO_ERROR == Error );
  220. Ctxt.SScope = FindSScope( Server, Scope->SuperScopeId );
  221. Ctxt.Scope = Scope;
  222. Error = Callback( &Ctxt );
  223. if( ERROR_KEY_DELETED == Error ) {
  224. //
  225. // Delete this scope
  226. //
  227. MemArrayDelElement(
  228. &Server->Subnets, &Loc, &Scope );
  229. MemSubnetFree( Scope );
  230. Error = MemArrayAdjustLocation(
  231. &Server->Subnets, &Loc );
  232. } else {
  233. if( NO_ERROR != Error ) return Error;
  234. Error = MemArrayNextLoc( &Server->Subnets, &Loc );
  235. }
  236. }
  237. if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
  238. return Error;
  239. }
  240. DWORD
  241. IterateScopeRanges(
  242. IN PM_SUBNET Scope,
  243. IN PVOID ExtraCtxt,
  244. IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
  245. )
  246. {
  247. ARRAY_LOCATION Loc;
  248. DWORD Error;
  249. MM_ITERATE_CTXT Ctxt;
  250. PM_RANGE Range;
  251. Ctxt.ExtraCtxt = ExtraCtxt;
  252. Ctxt.Server = (PM_SERVER)Scope->ServerPtr;
  253. Error = MemArrayInitLoc( &Scope->Ranges, &Loc );
  254. while( NO_ERROR == Error ) {
  255. Error = MemArrayGetElement(
  256. &Scope->Ranges, &Loc, &Range );
  257. ASSERT( NO_ERROR == Error );
  258. Ctxt.Range = Range;
  259. Error = Callback( &Ctxt );
  260. if( NO_ERROR != Error ) return Error;
  261. Error = MemArrayNextLoc( &Scope->Ranges, &Loc );
  262. }
  263. if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
  264. return Error;
  265. }
  266. DWORD
  267. IterateScopeExclusions(
  268. IN PM_SUBNET Scope,
  269. IN PVOID ExtraCtxt,
  270. IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
  271. )
  272. {
  273. ARRAY_LOCATION Loc;
  274. DWORD Error;
  275. MM_ITERATE_CTXT Ctxt;
  276. PM_EXCL Excl;
  277. Ctxt.ExtraCtxt = ExtraCtxt;
  278. Ctxt.Server = (PM_SERVER)Scope->ServerPtr;
  279. Error = MemArrayInitLoc( &Scope->Exclusions, &Loc );
  280. while( NO_ERROR == Error ) {
  281. Error = MemArrayGetElement(
  282. &Scope->Exclusions, &Loc, &Excl );
  283. ASSERT( NO_ERROR == Error );
  284. Ctxt.Excl = Excl;
  285. Error = Callback( &Ctxt );
  286. if( NO_ERROR != Error ) return Error;
  287. Error = MemArrayNextLoc( &Scope->Exclusions, &Loc );
  288. }
  289. if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
  290. return Error;
  291. }
  292. DWORD
  293. IterateScopeReservations(
  294. IN PM_SUBNET Scope,
  295. IN PVOID ExtraCtxt,
  296. IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
  297. )
  298. {
  299. ARRAY_LOCATION Loc;
  300. DWORD Error;
  301. MM_ITERATE_CTXT Ctxt;
  302. PM_RESERVATION Res;
  303. Ctxt.ExtraCtxt = ExtraCtxt;
  304. Ctxt.Server = (PM_SERVER)Scope->ServerPtr;
  305. Error = MemArrayInitLoc( &Scope->Reservations, &Loc );
  306. while( NO_ERROR == Error ) {
  307. Error = MemArrayGetElement(
  308. &Scope->Reservations, &Loc, &Res );
  309. ASSERT( NO_ERROR == Error );
  310. Ctxt.Res = Res;
  311. Error = Callback( &Ctxt );
  312. if( NO_ERROR != Error ) return Error;
  313. Error = MemArrayNextLoc( &Scope->Reservations, &Loc );
  314. }
  315. if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
  316. return Error;
  317. }