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.

724 lines
28 KiB

  1. //================================================================================
  2. // Copyright (C) 1997 Microsoft Corporation
  3. // Author: RameshV
  4. // Description: This file has the functions relating to downloading stuff from
  5. // off the DS in a safe way onto the registry. The solution adopted is actually
  6. // to dowload onto the "Config.DS" key rather than to the "Configuration" key
  7. // itself. Then if the full download is successful, backup this key and restore it
  8. // onto the "Configuration" key -- so if anything fails, atleast the old configuration
  9. // would be intact.
  10. //================================================================================
  11. #include <mmregpch.h>
  12. #include <regutil.h>
  13. #include <regsave.h>
  14. #define FreeArray1(X) Error = LoopThruArray((X), DestroyString, NULL, NULL);Require(ERROR_SUCCESS == Error);
  15. #define FreeArray2(X) Error = MemArrayCleanup((X)); Require(ERROR_SUCCESS == Error);
  16. #define FreeArray(X) do{ DWORD Error; FreeArray1(X); FreeArray2(X); }while(0)
  17. typedef DWORD (*ARRAY_FN)(PREG_HANDLE, LPWSTR ArrayString, LPVOID MemObject);
  18. extern
  19. DWORD
  20. DestroyString( // defined in regread.c
  21. IN PREG_HANDLE Unused,
  22. IN LPWSTR StringToFree,
  23. IN LPVOID Unused2
  24. );
  25. extern
  26. DWORD
  27. LoopThruArray( // defined in regread.c
  28. IN PARRAY Array,
  29. IN ARRAY_FN ArrayFn,
  30. IN PREG_HANDLE Hdl,
  31. IN LPVOID MemObject
  32. );
  33. DWORD // need to include headers..
  34. DhcpDsGetEnterpriseServers( // defined in dhcpds\dhcpread.h.
  35. IN DWORD Reserved,
  36. IN LPWSTR ServerName,
  37. IN OUT PARRAY Servers
  38. ) ;
  39. //================================================================================
  40. // module files
  41. //================================================================================
  42. REG_HANDLE DsConfig = { NULL, NULL, NULL }; // DsConfig key is stored here
  43. PM_SERVER CurrentServer;
  44. static const
  45. DWORD ZeroReserved = 0;
  46. DWORD
  47. PrepareRegistryForDsDownload( // make reg changes to download
  48. VOID
  49. )
  50. {
  51. DWORD Err, Disposition;
  52. REG_HANDLE DsConfigParent;
  53. if( NULL != DsConfig.Key ) return ERROR_INVALID_PARAMETER;
  54. memset(&DsConfigParent,0, sizeof(DsConfigParent));
  55. Err = RegOpenKeyEx( // open the parent key for DsConfig.
  56. HKEY_LOCAL_MACHINE,
  57. REG_THIS_SERVER_DS_PARENT,
  58. ZeroReserved,
  59. REG_ACCESS,
  60. &DsConfigParent.Key
  61. );
  62. if( ERROR_SUCCESS != Err ) return Err; // cant do much if server key aint there.
  63. Err = DhcpRegRecurseDelete(&DsConfigParent, REG_THIS_SERVER_DS_VALUE);
  64. RegCloseKey(DsConfigParent.Key); // this is all the parent is needed for
  65. if( ERROR_SUCCESS != Err && ERROR_FILE_NOT_FOUND != Err ) {
  66. return Err; // could not delete the "config_ds" trash?
  67. }
  68. Err = RegCreateKeyEx( // now create a fresh "config_ds" key
  69. HKEY_LOCAL_MACHINE,
  70. REG_THIS_SERVER_DS,
  71. ZeroReserved,
  72. REG_CLASS,
  73. REG_OPTION_NON_VOLATILE,
  74. REG_ACCESS,
  75. NULL,
  76. &DsConfig.Key,
  77. &Disposition
  78. );
  79. if( ERROR_SUCCESS != Err ) return Err; // could not create the key, nowhere to store..
  80. return DhcpRegSetCurrentServer(&DsConfig); // now set this as the default server loc to use..
  81. }
  82. VOID
  83. CleanupAfterDownload( // keep stuff clean for other modules
  84. VOID
  85. )
  86. {
  87. if( NULL != DsConfig.Key ) RegCloseKey(DsConfig.Key);
  88. DsConfig.Key = NULL; // close the config_ds key and,
  89. DhcpRegSetCurrentServer(NULL); // forget abt the config_ds key..
  90. //remote the Ds cache no matter what...
  91. }
  92. DWORD
  93. CopyRegKeys( // copy between reg keys
  94. IN HKEY SrcKey, // copy tree rooted at this key
  95. IN LPWSTR DestKeyLoc, // onto registry key located here
  96. IN LPWSTR FileName // using this as the temp file
  97. )
  98. {
  99. DWORD Err, Disposition;
  100. HKEY DestKey;
  101. BOOLEAN HadBackup;
  102. NTSTATUS NtStatus;
  103. NtStatus = RtlAdjustPrivilege (SE_BACKUP_PRIVILEGE, TRUE, FALSE, &HadBackup);
  104. if( ERROR_SUCCESS != NtStatus ) { // could not request backup priv..
  105. return RtlNtStatusToDosError(NtStatus);
  106. }
  107. NtStatus = RtlAdjustPrivilege (SE_RESTORE_PRIVILEGE, TRUE, FALSE, &HadBackup);
  108. if( ERROR_SUCCESS != NtStatus ) {
  109. return RtlNtStatusToDosError(NtStatus);
  110. }
  111. Err = RegSaveKey(SrcKey, FileName, NULL); // NULL ==> no security on file
  112. if( ERROR_SUCCESS != Err ) return Err; // if key cant be saved, cant restore.
  113. Err = RegCreateKeyEx( // now create a fresh "config_ds" key
  114. HKEY_LOCAL_MACHINE,
  115. DestKeyLoc,
  116. ZeroReserved,
  117. REG_CLASS,
  118. REG_OPTION_NON_VOLATILE,
  119. REG_ACCESS,
  120. NULL,
  121. &DestKey,
  122. &Disposition
  123. );
  124. if( ERROR_SUCCESS != Err ) return Err; // could not create the key, nowhere to store..
  125. Err = RegRestoreKey(DestKey, FileName, 0 ); // 0 ==> no flags, in particular, not volatile.
  126. RegCloseKey(DestKey); // dont need this key anyways.
  127. return Err;
  128. }
  129. DWORD
  130. FixSpecificClusters( // this fixes a specific cluster
  131. IN HKEY NewCfgKey, // root cfg where to copy over
  132. IN LPWSTR Subnet, // the subnet to copy to
  133. IN LPWSTR Range, // the range to copy to
  134. IN LPBYTE InUseClusters, // in use cluster value
  135. IN ULONG InUseSize,
  136. IN LPBYTE UsedClusters, // used clusters value
  137. IN ULONG UsedSize
  138. )
  139. {
  140. return ERROR_CALL_NOT_IMPLEMENTED; // not done yet...
  141. // just concat REG_SUBNETS Subnet REG_RANGES Range and try to open that.
  142. // if it fails, quit, other wise just set the given values over...
  143. }
  144. DWORD
  145. FixAllClusters1( // copy cluster info frm old to new cfg
  146. IN HKEY NewCfgKey,
  147. IN HKEY OldCfgKey
  148. )
  149. {
  150. REG_HANDLE Cfg, Tmp1, Tmp2;
  151. DWORD Err;
  152. ARRAY Subnets, Ranges;
  153. LPWSTR ThisSubnet, ThisRange;
  154. ARRAY_LOCATION Loc1, Loc2;
  155. Cfg.Key = OldCfgKey; // Should not poke inside directly
  156. MemArrayInit(&Subnets);
  157. Err = DhcpRegServerGetList(&Cfg, NULL, NULL, &Subnets, NULL, NULL, NULL);
  158. if( ERROR_SUCCESS != Err ) {
  159. MemArrayCleanup(&Subnets);
  160. return Err;
  161. }
  162. for( Err = MemArrayInitLoc(&Subnets, &Loc1)
  163. ; ERROR_FILE_NOT_FOUND != Err ;
  164. Err = MemArrayNextLoc(&Subnets, &Loc1)
  165. ) { // for each subnet, look for ranges
  166. Err = MemArrayGetElement(&Subnets, &Loc1, &ThisSubnet);
  167. Err = DhcpRegServerGetSubnetHdl(&Cfg, ThisSubnet, &Tmp1);
  168. if( ERROR_SUCCESS != Err ) { // what do we do? just ignore it I think
  169. continue;
  170. }
  171. Err = DhcpRegSubnetGetList(&Tmp1, NULL, &Ranges, NULL, NULL, NULL, NULL );
  172. if( ERROR_SUCCESS != Err ) {
  173. DhcpRegCloseHdl(&Tmp1);
  174. continue;
  175. }
  176. for( Err = MemArrayInitLoc(&Ranges, &Loc2)
  177. ; ERROR_FILE_NOT_FOUND != Err ;
  178. Err = MemArrayNextLoc(&Ranges, &Loc2)
  179. ) { // for each range try to copy it over..
  180. LPBYTE InUseClusters = NULL, UsedClusters = NULL;
  181. ULONG InUseClustersSize = 0, UsedClustersSize = 0;
  182. Err = MemArrayGetElement(&Ranges, &Loc2, &ThisRange);
  183. Err = DhcpRegSubnetGetRangeHdl(&Tmp1, ThisRange, &Tmp2);
  184. if( ERROR_SUCCESS != Err ) continue;
  185. Err = DhcpRegRangeGetAttributes(
  186. &Tmp2,
  187. NULL /* no name */,
  188. NULL /* no comm */,
  189. NULL /* no flags */,
  190. NULL /* no bootp alloc */,
  191. NULL /* no max boop allowed */,
  192. NULL /* no start addr */,
  193. NULL /* no end addr */,
  194. &InUseClusters,
  195. &InUseClustersSize,
  196. &UsedClusters,
  197. &UsedClustersSize
  198. );
  199. if( ERROR_SUCCESS == Err ) {
  200. Err = FixSpecificClusters(
  201. NewCfgKey, ThisSubnet, ThisRange, InUseClusters, InUseClustersSize,
  202. UsedClusters, UsedClustersSize
  203. );
  204. if( InUseClusters ) MemFree(InUseClusters);
  205. if( UsedClusters ) MemFree(UsedClusters);
  206. }
  207. DhcpRegCloseHdl(&Tmp2);
  208. }
  209. FreeArray(&Ranges);
  210. DhcpRegCloseHdl(&Tmp1);
  211. }
  212. FreeArray(&Subnets);
  213. return ERROR_SUCCESS;
  214. }
  215. DWORD
  216. FixAllClusters( // copy the clusters over frm existing to DS_CONFIG
  217. IN HKEY DsKey // so that when it is copied back nothing is lost
  218. )
  219. {
  220. HKEY OldCfgKey;
  221. ULONG Disposition, Err;
  222. return ERROR_SUCCESS; // Need to fix this..
  223. Err = RegCreateKeyEx(
  224. HKEY_LOCAL_MACHINE,
  225. REG_THIS_SERVER,
  226. ZeroReserved,
  227. REG_CLASS,
  228. REG_OPTION_NON_VOLATILE,
  229. REG_ACCESS,
  230. NULL,
  231. &OldCfgKey,
  232. &Disposition
  233. );
  234. if( ERROR_SUCCESS != Err ) {
  235. return Err; // ugh? this should not happen
  236. }
  237. Err = FixAllClusters1(DsKey, OldCfgKey);
  238. RegCloseKey(OldCfgKey);
  239. return Err;
  240. }
  241. VOID
  242. CopyDsConfigToNormalConfig( // copy downloaded config to normal config
  243. VOID
  244. )
  245. {
  246. BOOL Status;
  247. DWORD Err;
  248. Status = DeleteFile(L"TempDhcpFile.Reg" ); // this file will be used for temp. storage
  249. if( !Status ) { // could not delete this file?
  250. Err = GetLastError();
  251. if( ERROR_FILE_NOT_FOUND != Err && // the file does exist?
  252. ERROR_PATH_NOT_FOUND != Err ) { // this could also happen?
  253. return; // the nwe wont be able to do the copy!
  254. }
  255. }
  256. FixAllClusters(DsConfig.Key); // copy the ranges values over from old to new..
  257. CopyRegKeys(DsConfig.Key, REG_THIS_SERVER, L"TempDhcpFile.Reg");
  258. DeleteFile(L"TempDhcpFile.Reg" ); // dont need this file anymore..
  259. }
  260. #if 0
  261. DWORD
  262. SaveServerClasses( // save all class info onto registry
  263. IN PREG_HANDLE Server, // registry handle to server config.
  264. IN PM_CLASSDEFLIST Classes // list of defined classes
  265. )
  266. {
  267. DWORD Err, Err2;
  268. REG_HANDLE Hdl;
  269. ARRAY_LOCATION Loc;
  270. PM_CLASSDEF ThisClass;
  271. for( // save each class definition
  272. Err = MemArrayInitLoc(&Classes->ClassDefArray, &Loc)
  273. ; ERROR_FILE_NOT_FOUND != Err ;
  274. Err = MemArrayNextLoc(&Classes->ClassDefArray, &Loc)
  275. ) {
  276. //= require ERROR_SUCCESS == Err
  277. Err = MemArrayGetElement(&Classes->ClassDefArray, &Loc, &ThisClass);
  278. //= require ERROR_SUCCESS == Err && NULL != ThisClass
  279. Err = DhcpRegServerGetClassDefHdl(Server,ThisClass->Name,&Hdl);
  280. if( ERROR_SUCCESS != Err ) return Err; // registry error?
  281. Err = DhcpRegClassDefSetAttributes // save this class information
  282. (
  283. /* Hdl */ &Hdl,
  284. /* Name */ &ThisClass->Name,
  285. /* Comment */ &ThisClass->Comment,
  286. /* Flags */ &ThisClass->Type,
  287. /* Value */ &ThisClass->ActualBytes,
  288. /* ValueSize */ ThisClass->nBytes
  289. );
  290. Err2 = DhcpRegCloseHdl(&Hdl); //= require ERROR_SUCCESS == Err2
  291. if( ERROR_SUCCESS != Err) return Err; // could not set-attribs in reg.
  292. }
  293. return ERROR_SUCCESS; // everything went fine.
  294. }
  295. DWORD
  296. SaveServerOptDefs1( // save some option definition
  297. IN PREG_HANDLE Server, // registry handle to server config.
  298. IN LPWSTR ClassName, // name of the class of option
  299. IN PM_OPTDEFLIST OptDefList // list of option definitions
  300. )
  301. {
  302. DWORD Err, Err2;
  303. ARRAY_LOCATION Loc;
  304. PM_OPTDEF ThisOptDef;
  305. for( // save each opt definition
  306. Err = MemArrayInitLoc(&OptDefList->OptDefArray, &Loc)
  307. ; ERROR_FILE_NOT_FOUND != Err ;
  308. Err = MemArrayNextLoc(&OptDefList->OptDefArray, &Loc)
  309. ) {
  310. //= require ERROR_SUCCESS == Err
  311. Err = MemArrayGetElement(&OptDefList->OptDefArray, &Loc, &ThisOptDef);
  312. //= require ERROR_SUCCESS == Err && NULL != ThisOptDef
  313. Err = DhcpRegSaveOptDef // save the option def
  314. (
  315. /* OptId */ ThisOptDef->OptId,
  316. /* ClassName */ ClassName,
  317. /* Name */ ThisOptDef->OptName,
  318. /* Comment */ ThisOptDef->OptComment,
  319. /* OptType */ ThisOptDef->Type,
  320. /* OptVal */ ThisOptDef->OptVal,
  321. /* OptLen */ ThisOptDef->OptValLen
  322. );
  323. if( ERROR_SUCCESS != Err ) return Err; // reg. err saving opt def
  324. }
  325. return ERROR_SUCCESS; // everything went fine.
  326. }
  327. DWORD
  328. SaveServerOptdefs( // save all the opt def's onto registry
  329. IN PREG_HANDLE Server, // registry handle to server config.
  330. IN PM_OPTCLASSDEFLIST Optdefs
  331. )
  332. {
  333. DWORD Err, Err2;
  334. ARRAY_LOCATION Loc;
  335. PM_OPTCLASSDEFL_ONE ThisOptClass;
  336. LPWSTR ClassName;
  337. PM_CLASSDEF ClassDef;
  338. for( // save each opt definition
  339. Err = MemArrayInitLoc(&Optdefs->Array, &Loc)
  340. ; ERROR_FILE_NOT_FOUND != Err ;
  341. Err = MemArrayNextLoc(&Optdefs->Array, &Loc)
  342. ) {
  343. //= require ERROR_SUCCESS == Err
  344. Err = MemArrayGetElement(&Optdefs->Array, &Loc, &ThisOptClass);
  345. //= require ERROR_SUCCESS == Err && NULL != ThisClass
  346. if( 0 == ThisOptClass->ClassId ) { // no class for this option
  347. ClassName = NULL;
  348. } else { // lookup class in this server struct
  349. Err = MemServerGetClassDef(
  350. CurrentServer, // need to pass this as param
  351. ThisOptClass->ClassId,
  352. NULL,
  353. 0,
  354. NULL,
  355. &ClassDef
  356. );
  357. if( ERROR_SUCCESS != Err) return Err; // could not find the class? invalid struct
  358. ClassName = ClassDef->Name; // found the class, use this name
  359. }
  360. Err = SaveServerOptDefs1(Server, ClassName, &ThisOptClass->OptDefList);
  361. if( ERROR_SUCCESS != Err) return Err; // could not save some opt definition..
  362. }
  363. return ERROR_SUCCESS; // everything went fine.
  364. }
  365. DWORD
  366. SaveServerOptions1( // save some option
  367. IN PREG_HANDLE Server, // registry handle to server config.
  368. IN LPWSTR ClassName, // name of the class of option
  369. IN PM_OPTLIST OptList // list of options
  370. )
  371. {
  372. DWORD Err, Err2;
  373. ARRAY_LOCATION Loc;
  374. PM_OPTION ThisOpt;
  375. for( // save each option
  376. Err = MemArrayInitLoc(OptList, &Loc)
  377. ; ERROR_FILE_NOT_FOUND != Err ;
  378. Err = MemArrayNextLoc(OptList, &Loc)
  379. ) {
  380. //= require ERROR_SUCCESS == Err
  381. Err = MemArrayGetElement(OptList, &Loc, &ThisOpt);
  382. //= require ERROR_SUCCESS == Err && NULL != ThisOpt
  383. Err = DhcpRegSaveGlobalOption // save the option
  384. (
  385. /* OptId */ ThisOpt->OptId,
  386. /* ClassName */ ClassName,
  387. /* Value */ ThisOpt->Val,
  388. /* ValueSize */ ThisOpt->Len
  389. );
  390. if( ERROR_SUCCESS != Err ) return Err; // reg. err saving option
  391. }
  392. return ERROR_SUCCESS; // everything went fine.
  393. }
  394. DWORD
  395. SaveServerOptions( // save all options onto registry
  396. IN PREG_HANDLE Server, // registry handle to server config.
  397. IN PM_OPTCLASS Options
  398. )
  399. {
  400. DWORD Err, Err2;
  401. ARRAY_LOCATION Loc;
  402. PM_ONECLASS_OPTLIST ThisOptClass;
  403. LPWSTR ClassName;
  404. PM_CLASSDEF ClassDef;
  405. for( // save each class definition
  406. Err = MemArrayInitLoc(&Options->Array, &Loc)
  407. ; ERROR_FILE_NOT_FOUND != Err ;
  408. Err = MemArrayNextLoc(&Options->Array, &Loc)
  409. ) {
  410. //= require ERROR_SUCCESS == Err
  411. Err = MemArrayGetElement(&Options->Array, &Loc, &ThisOptClass);
  412. //= require ERROR_SUCCESS == Err && NULL != ThisOptClass
  413. if( 0 == ThisOptClass->ClassId ) { // no class for this option
  414. ClassName = NULL;
  415. } else { // lookup class in this server struct
  416. Err = MemServerGetClassDef(
  417. CurrentServer, // need to pass this as param
  418. ThisOptClass->ClassId,
  419. NULL,
  420. 0,
  421. NULL,
  422. &ClassDef
  423. );
  424. if( ERROR_SUCCESS != Err) return Err; // could not find the class? invalid struct
  425. ClassName = ClassDef->Name; // found the class, use this name
  426. }
  427. Err = SaveServerOptions1(Server, ClassName, &ThisOptClass->OptList);
  428. if( ERROR_SUCCESS != Err) return Err; // could not save some option..
  429. }
  430. return ERROR_SUCCESS; // everything went fine.
  431. }
  432. DWORD
  433. SaveServerScope( // save unicast-or-mcast scope onto reg.
  434. IN PREG_HANDLE ServerHdl, // registry handle to server config
  435. IN PM_SERVER MemServer, // server object in memory
  436. IN LPVOID Scope, // either PM_SUBNET or PM_MSCOPE object
  437. IN BOOL fSubnet // TRUE ==> Subnet type, FALSE ==> MScope type.
  438. )
  439. {
  440. DWORD Err;
  441. PM_SUBNET Subnet = Scope;
  442. PM_MSCOPE Subnet = MScope;
  443. PM_SSCOPE SScope;
  444. if( fSubnet ) { // if subnet, need to add it to superscope..
  445. if( 0 != Subnet->SuperScopeId ) { // this belongs to superscope?
  446. Err = MemServerFindSScope(MemServer, Subnet->SuperScopeId, NULL, &SScope);
  447. if( ERROR_SUCCESS != Err ) { // wrong superscope? invlaid data
  448. return Err;
  449. }
  450. Err = DhcpRegSScopeSaveSubnet(SScope->Name, Subnet->Address);
  451. if( ERROR_SUCCESS != Err ) return Err;// could not add subnet to superscope?
  452. }
  453. }
  454. if( fSubnet ) {
  455. Err = DhcpRegSaveSubnet // save this subnet
  456. (
  457. /* SubnetAddress */ Subnet->Address,
  458. /* SubnetMask */ Subnet->Mask,
  459. /* SubnetState */ Subnet->State,
  460. /* SubnetName */ Subnet->Name
  461. /* SubnetComment */ Subnet->Description
  462. );
  463. } else {
  464. Err = DhcpRegSaveMScope // save this mcast scope
  465. (
  466. /* MScopeId */ MScope->MScopeId,
  467. /* SubnetState */ MScope->State,
  468. /* AddressPolicy */ MScope->Policy,
  469. /* TTL */ MScope->TTL,
  470. /* pMScopeName */ MScope->Name,
  471. /* pMScopeComment */ MScope->Description,
  472. /* LangTag */ MScope->LangTag,
  473. /* ExpiryTime */ &MScope->ExpiryTime
  474. );
  475. }
  476. if( ERROR_SUCCESS != Err ) return Err; // could not save subnet info?
  477. }
  478. DWORD
  479. SaveServerScopes( // save unicast-or-mcast scopes onto reg.
  480. IN PREG_HANDLE Server, // registry handle to server config.
  481. IN PARRAY Scopes, // array of PM_SUBNET or PM_MSCOPE types
  482. IN BOOL fSubnet // TRUE ==> Subnet type, FALSE ==> MScope type.
  483. )
  484. {
  485. DWORD Err;
  486. ARRAY_LOCATION Loc;
  487. PM_SUBNET Subnet;
  488. for( // save each scope..
  489. Err = MemArrayInitLoc(Scopes, &Loc)
  490. ; ERROR_FILE_NOT_FOUND != Err ;
  491. Err = MemArrayNextLoc(Scopes, &Loc)
  492. ) {
  493. //= require ERROR_SUCCESS == Err
  494. Err = MemArrayGetElement(Scopes, &Loc, &Subnet);
  495. //= require ERROR_SUCCESS == Err && NULL != Subnet
  496. Err = SaveServerScope(Server, CurrentServer, Subnet, fSubnet);
  497. if( ERROR_SUCCESS != Err ) return Err; // could not save the subnet/m-scope..
  498. }
  499. return ERROR_SUCCESS;
  500. }
  501. DWORD
  502. SaveServerSubnets( // save all subnet info onto reg.
  503. IN PREG_HANDLE Server, // registry handle to server config.
  504. IN PARRAY Subnets // array of type PM_SUBNET elements
  505. )
  506. {
  507. return SaveServerScopes(Server, Subnets, TRUE); // call common routine
  508. }
  509. DWORD
  510. SaveServerMScopes( // save all the m-cast scopes onto reg.
  511. IN PREG_HANDLE Server, // registry handle to server config.
  512. IN PARRAY MScopes // array of type PM_MSCOPE elements
  513. )
  514. {
  515. return SaveServerScopes(Server, MScopes, FALSE); // call common routine
  516. }
  517. DWORD
  518. DownloadServerInfoFromDs( // save the server info onto registry
  519. IN PM_SERVER Server // the server to save onto registry
  520. )
  521. {
  522. DWORD Err;
  523. REG_HANDLE Hdl, Hdl2;
  524. ARRAY_LOCATION Loc;
  525. CurrentServer = Server; // this global used by several funcs above..
  526. Err = DhcpRegGetThisServer(&Hdl); // get current server hdl
  527. if( ERROR_SUCCESS != Err ) return Err;
  528. Err = DhcpRegServerSetAttributes // set server attributes
  529. (
  530. /* PREG_HANDLE Hdl */ &Hdl,
  531. /* LPWSTR *Name */ &Server->Name,
  532. /* LPWSTR *Comment */ &Server->Comment,
  533. /* DWORD *Flags */ &Server->State
  534. );
  535. // ignore errors..
  536. Err = SaveServerClasses(&Hdl, &Server->ClassDefs);
  537. if( ERROR_SUCCESS == Err ) { // saved classes? save optdefs..
  538. Err = SaveServerOptdefs(&Hdl, &Server->OptDefs);
  539. }
  540. if( ERROR_SUCCESS == Err ) { // saved optdefs? save options..
  541. Err = SaveServerOptions(&Hdl, &Server->Options);
  542. }
  543. if( ERROR_SUCCESS == Err ) { // saved options? save subnets..
  544. Err = SaveServerSubnets(&Hdl, &Server->Subnets);
  545. }
  546. if( ERROR_SUCCESS == Err ) { // saved subnets? save mcast scopes
  547. Err = SaveServerMScopes(&Hdl, &Server->MScopes);
  548. }
  549. (void)DhcpRegCloseHdl(&Hdl); // free resource
  550. return Err;
  551. }
  552. #endif 0
  553. DWORD
  554. DownloadServerInfoFromDs( // save the server info onto registry
  555. IN PM_SERVER Server // the server to save onto registry
  556. )
  557. {
  558. return DhcpRegServerSave(Server);
  559. }
  560. DWORD
  561. DownloadFromDsForReal( // really try to downlaod from DS
  562. IN LPWSTR ServerName
  563. )
  564. {
  565. DWORD Err, Err2;
  566. ARRAY Servers;
  567. ARRAY_LOCATION Loc;
  568. PM_SERVER ThisServer;
  569. Err = MemArrayInit(&Servers); // initialize array
  570. if( ERROR_SUCCESS != Err ) return Err;
  571. Err = DhcpDsGetEnterpriseServers // fetch the server info from DS
  572. (
  573. /* Reserved */ ZeroReserved,
  574. /* ServerName */ ServerName,
  575. /* Servers */ &Servers
  576. );
  577. Err2 = ERROR_SUCCESS; // init return value
  578. for( // process all the information
  579. Err = MemArrayInitLoc(&Servers, &Loc)
  580. ; ERROR_FILE_NOT_FOUND != Err ;
  581. Err = MemArrayNextLoc(&Servers, &Loc)
  582. ) {
  583. //= require ERROR_SUCCESS == Err
  584. Err = MemArrayGetElement(&Servers, &Loc, &ThisServer);
  585. //= require ERROR_SUCCESS == Err && NULL != ThisServer
  586. Err = DownloadServerInfoFromDs(ThisServer);
  587. if( ERROR_SUCCESS != Err ) { // oops.. could not do it?
  588. Err2 = Err; // store error..
  589. }
  590. MemServerFree(ThisServer); // free all this memory.
  591. }
  592. Err = MemArrayCleanup(&Servers); // free mem allcoated for array
  593. if( ERROR_SUCCESS != Err ) Err2 = Err; // something went wrong?
  594. return Err2;
  595. }
  596. //================================================================================
  597. // the only exported function is this.
  598. //================================================================================
  599. VOID
  600. DhcpRegDownloadDs( // safe download of stuff onto registry
  601. IN LPWSTR ServerName // name of dhcp servre to download for
  602. )
  603. {
  604. DWORD Err;
  605. Err = PrepareRegistryForDsDownload(); // prepare the Config.DS key and stuff..
  606. if( ERROR_SUCCESS != Err ) return; // oops, could not even do this?
  607. Err = DownloadFromDsForReal(ServerName); // actually try to download from DS.
  608. if( ERROR_SUCCESS == Err ) { // could actually download successfully
  609. CopyDsConfigToNormalConfig(); // now copy this configuration to nrml loc.
  610. }
  611. CleanupAfterDownload(); // now cleanup the regsitry handles etc..
  612. DhcpRegUpdateTime(); // fix the time stamp to now..
  613. }
  614. //================================================================================
  615. // end of file
  616. //================================================================================