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.

308 lines
6.6 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft corporation
  3. Module Name:
  4. select.c
  5. Abstract:
  6. Implements the partial selection of configuration from the
  7. full MM configuration data structures.
  8. --*/
  9. #include <precomp.h>
  10. typedef struct _SELECT_CTXT {
  11. ULONG *Subnets;
  12. ULONG nSubnets;
  13. } SELECT_CTXT, *PSELECT_CTXT;
  14. DWORD
  15. DeleteScopesCallback(
  16. IN OUT PMM_ITERATE_CTXT Ctxt
  17. )
  18. {
  19. PSELECT_CTXT SelectCtxt = Ctxt->ExtraCtxt;
  20. ULONG *Subnets, nSubnets, i;
  21. Subnets = SelectCtxt->Subnets;
  22. nSubnets = SelectCtxt->nSubnets;
  23. for( i = 0; i < nSubnets; i ++ ) {
  24. if( Subnets[i] == Ctxt->Scope->Address ) break;
  25. }
  26. if( i == nSubnets ) {
  27. //
  28. // Returning KEY_DELETED will cause the IterateScopes
  29. // routine to delete this scope out.
  30. //
  31. return ERROR_KEY_DELETED;
  32. }
  33. return NO_ERROR;
  34. }
  35. DWORD
  36. OptionCheckForClass(
  37. IN OUT PMM_ITERATE_CTXT Ctxt
  38. )
  39. {
  40. PM_CLASSDEF ClassDef = Ctxt->ExtraCtxt;
  41. //
  42. // If the class specified in ExtraCtxt matches the current
  43. // option's user or vendor class, then bummer -- fail
  44. // immediately with error code ERROR_DEVICE_IN_USE to
  45. // indicate that this class is needed and can't be deleted
  46. //
  47. if( Ctxt->UserClass == ClassDef ||
  48. Ctxt->VendorClass == ClassDef ) {
  49. return ERROR_DEVICE_IN_USE;
  50. }
  51. return NO_ERROR;
  52. }
  53. DWORD
  54. OptionCheckForOptDef(
  55. IN OUT PMM_ITERATE_CTXT Ctxt
  56. )
  57. {
  58. PMM_ITERATE_CTXT OtherCtxt = Ctxt->ExtraCtxt;
  59. //
  60. // If the current option matches the optdef parameters, then
  61. // we need to save the optdef ..
  62. //
  63. if( Ctxt->VendorClass == OtherCtxt->VendorClass &&
  64. Ctxt->Option->OptId == OtherCtxt->OptDef->OptId ) {
  65. return ERROR_DEVICE_IN_USE;
  66. }
  67. return NO_ERROR;
  68. }
  69. DWORD
  70. ScopeReservationsCheckForClass(
  71. IN OUT PMM_ITERATE_CTXT Ctxt
  72. )
  73. {
  74. return IterateReservationOptions(
  75. Ctxt->Server, Ctxt->Res, Ctxt->ExtraCtxt,
  76. OptionCheckForClass );
  77. }
  78. DWORD
  79. ScopeReservationsCheckForOptDef(
  80. IN OUT PMM_ITERATE_CTXT Ctxt
  81. )
  82. {
  83. return IterateReservationOptions(
  84. Ctxt->Server, Ctxt->Res, Ctxt->ExtraCtxt,
  85. OptionCheckForOptDef );
  86. }
  87. DWORD
  88. ScopeCheckForClass(
  89. IN OUT PMM_ITERATE_CTXT Ctxt
  90. )
  91. {
  92. DWORD Error;
  93. //
  94. // Iterate over each option in the current scope to see if
  95. // any of them use the same class
  96. //
  97. Error = IterateScopeOptions(
  98. Ctxt->Scope, Ctxt->ExtraCtxt, OptionCheckForClass );
  99. if( NO_ERROR != Error ) return Error;
  100. //
  101. // Otherwise iterate for each reservation to see if this is a
  102. // problem.
  103. //
  104. return IterateScopeReservations(
  105. Ctxt->Scope, Ctxt->ExtraCtxt,
  106. ScopeReservationsCheckForClass );
  107. }
  108. DWORD
  109. ScopeCheckForOptDef(
  110. IN OUT PMM_ITERATE_CTXT Ctxt
  111. )
  112. {
  113. DWORD Error;
  114. //
  115. // Iterate over each option in the current scope to see if
  116. // any of them use the same class
  117. //
  118. Error = IterateScopeOptions(
  119. Ctxt->Scope, Ctxt->ExtraCtxt, OptionCheckForOptDef );
  120. if( NO_ERROR != Error ) return Error;
  121. //
  122. // Otherwise iterate for each reservation to see if this is a
  123. // problem.
  124. //
  125. return IterateScopeReservations(
  126. Ctxt->Scope, Ctxt->ExtraCtxt,
  127. ScopeReservationsCheckForOptDef );
  128. }
  129. DWORD
  130. DeleteClassesCallback(
  131. IN OUT PMM_ITERATE_CTXT Ctxt
  132. )
  133. {
  134. DWORD Error;
  135. //
  136. // Go through each subnet to see if there is any option
  137. // configured to use this class
  138. //
  139. Error = IterateScopes(
  140. Ctxt->Server, Ctxt->ClassDef, ScopeCheckForClass );
  141. //
  142. // If the specified class is in use, then don't
  143. // delete. Otherwise delete.
  144. //
  145. if( ERROR_DEVICE_IN_USE == Error ) return NO_ERROR;
  146. if (NO_ERROR == Error ) return ERROR_KEY_DELETED;
  147. return Error;
  148. }
  149. DWORD
  150. DeleteOptDefsCallback(
  151. IN OUT PMM_ITERATE_CTXT Ctxt
  152. )
  153. {
  154. DWORD Error;
  155. //
  156. // Go through each subnet to see if there is any option
  157. // configured to use this optdef
  158. //
  159. Error = IterateScopes(
  160. Ctxt->Server, Ctxt, ScopeCheckForOptDef );
  161. //
  162. // If the specified class is in use, then don't
  163. // delete. Otherwise delete.
  164. //
  165. if( ERROR_DEVICE_IN_USE == Error ) return NO_ERROR;
  166. if (NO_ERROR == Error ) return ERROR_KEY_DELETED;
  167. return Error;
  168. }
  169. DWORD
  170. SelectConfiguration(
  171. IN OUT PM_SERVER Server,
  172. IN ULONG *Subnets,
  173. IN ULONG nSubnets
  174. )
  175. {
  176. SELECT_CTXT Ctxt = { Subnets, nSubnets };
  177. DWORD Error;
  178. ULONG i;
  179. WCHAR SubnetAddress[30];
  180. //
  181. // No selection needed if nSubnets == 0, as this indicates
  182. // that the whole configuration is to be used
  183. //
  184. Tr("SelectConfiguration entered\n");
  185. if( nSubnets == 0 ) return NO_ERROR;
  186. //
  187. // First go through all scopes and check if all the required
  188. // scopes are present
  189. //
  190. for( i = 0; i < nSubnets ; i ++ ) {
  191. PM_SUBNET Subnet;
  192. Error = MemServerGetUAddressInfo(
  193. Server, Subnets[i], &Subnet, NULL, NULL, NULL );
  194. if( NO_ERROR != Error ) {
  195. Tr("Cant find subnet 0x%lx: %ld\n", Subnets[i], Error );
  196. if( ERROR_FILE_NOT_FOUND == Error ) {
  197. IpAddressToStringW(Subnets[i], (LPWSTR)SubnetAddress);
  198. DhcpEximErrorSubnetNotFound( (LPWSTR)SubnetAddress );
  199. Error = ERROR_CAN_NOT_COMPLETE;
  200. }
  201. return Error;
  202. }
  203. }
  204. //
  205. // Global options are never needed.. so we can delete them.
  206. //
  207. MemOptClassFree( &Server->Options );
  208. //
  209. // Go through all the subnets and delete ones that are
  210. // not selected
  211. //
  212. Error = IterateScopes(
  213. Server, &Ctxt, DeleteScopesCallback );
  214. if( NO_ERROR != Error ) {
  215. Tr("IterateScopes: %ld\n", Error );
  216. return Error;
  217. }
  218. //
  219. // Now check if all the option-defs are needed
  220. //
  221. Error = IterateOptDefs(
  222. Server, NULL, DeleteOptDefsCallback );
  223. if( NO_ERROR != Error ) {
  224. Tr("IterateOptDefs: %ld\n", Error );
  225. return Error;
  226. }
  227. //
  228. // Now check if all the user classes are needed
  229. //
  230. Error = IterateClasses(
  231. Server, NULL, DeleteClassesCallback );
  232. if( NO_ERROR != Error ) {
  233. Tr("IterateClasses: %ld\n", Error );
  234. return Error;
  235. }
  236. return NO_ERROR;
  237. }