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.

1638 lines
46 KiB

  1. //================================================================================
  2. // Copyright (C) 1997 Microsoft Corporation
  3. // Author: RameshV
  4. // Description: This implements the init time reading in of the registry
  5. // (this may/may work even when used to read at any other time.. but is not efficient)
  6. //================================================================================
  7. #include <mmregpch.h>
  8. #include <regutil.h>
  9. #include <regsave.h>
  10. #define InitArray(X) do{DWORD Error = MemArrayInit((X)); Require(ERROR_SUCCESS == Error); }while(0)
  11. #define ERRCHK do{if( ERROR_SUCCESS != Error ) goto Cleanup; }while(0)
  12. #define FreeArray1(X) Error = LoopThruArray((X), DestroyString, NULL, NULL);Require(ERROR_SUCCESS == Error);
  13. #define FreeArray2(X) Error = MemArrayCleanup((X)); Require(ERROR_SUCCESS == Error);
  14. #define FreeArray(X) do{ DWORD Error; FreeArray1(X); FreeArray2(X); }while(0)
  15. #if DBG
  16. #define Report(Who) if(Error) DbgPrint("[DHCPServer] %s: %ld [0x%lx]\n", Who, Error, Error)
  17. #define INVALID_REG DbgPrint
  18. #else
  19. #define Report(Who)
  20. #define INVALID_REG (void)
  21. #endif
  22. typedef DWORD (*ARRAY_FN)(PREG_HANDLE, LPWSTR ArrayString, LPVOID MemObject);
  23. DWORD
  24. LoopThruArray(
  25. IN PARRAY Array,
  26. IN ARRAY_FN ArrayFn,
  27. IN PREG_HANDLE Hdl,
  28. IN LPVOID MemObject
  29. )
  30. {
  31. DWORD Error;
  32. ARRAY_LOCATION Loc;
  33. LPWSTR ArrayString;
  34. Error = MemArrayInitLoc(Array, &Loc);
  35. while(ERROR_FILE_NOT_FOUND != Error) {
  36. Require(ERROR_SUCCESS == Error);
  37. Error = MemArrayGetElement(Array, &Loc, (LPVOID *)&ArrayString);
  38. Require(ERROR_SUCCESS == Error && ArrayString);
  39. Error = ArrayFn(Hdl, ArrayString, MemObject);
  40. if( ERROR_SUCCESS != Error ) {
  41. //
  42. // Operation failed -- but ignore it.
  43. //
  44. // return Error;
  45. }
  46. Error = MemArrayNextLoc(Array, &Loc);
  47. }
  48. return ERROR_SUCCESS;
  49. }
  50. DWORD
  51. DestroyString(
  52. IN PREG_HANDLE Unused,
  53. IN LPWSTR StringToFree,
  54. IN LPVOID Unused2
  55. )
  56. {
  57. MemFree(StringToFree);
  58. return ERROR_SUCCESS;
  59. }
  60. DWORD
  61. WStringToAddress(
  62. IN LPWSTR Str
  63. )
  64. {
  65. CHAR IpString[100];
  66. DWORD Count;
  67. Count = wcstombs(IpString, Str, sizeof(IpString)-1);
  68. if( -1 == Count ) return 0;
  69. return htonl(inet_addr(IpString));
  70. }
  71. DWORD
  72. ConvertWStringToDWORD(
  73. IN LPWSTR Str
  74. )
  75. {
  76. return _wtoi(Str);
  77. }
  78. DWORD
  79. DhcpRegpSubnetAddServer(
  80. IN PREG_HANDLE Hdl,
  81. IN LPWSTR ServerName,
  82. IN PM_SUBNET Subnet
  83. )
  84. {
  85. return ERROR_SUCCESS;
  86. }
  87. DWORD
  88. SetBitForRange(
  89. IN PM_RANGE Range,
  90. IN DWORD Address
  91. )
  92. {
  93. BOOL WasSet;
  94. if( Address > Range->End || Address < Range->Start )
  95. return ERROR_INVALID_PARAMETER;
  96. return MemBitSetOrClear(
  97. Range->BitMask,
  98. Address - Range->Start,
  99. TRUE,
  100. &WasSet
  101. );
  102. }
  103. DWORD GlobalWorkingOnOldStyleSubnet = 0;
  104. DWORD GlobalWorkingOnPreWin2kMScope = 0;
  105. const DWORD One = 0x1;
  106. DWORD
  107. DhcpRegFillClusterAddresses(
  108. IN OUT PM_RANGE Range,
  109. IN LPBYTE InUseClusters,
  110. IN DWORD InUseClustersSize,
  111. IN LPBYTE UsedClusters,
  112. IN DWORD UsedClustersSize
  113. ) {
  114. DWORD Error;
  115. DWORD i;
  116. DWORD Address;
  117. DWORD UNALIGNED* InUseBits;
  118. DWORD UNALIGNED* UsedBits;
  119. DWORD nInUseBits;
  120. DWORD nUsedBits;
  121. if( InUseClusters && InUseClustersSize ) {
  122. nInUseBits = InUseClustersSize/sizeof(DWORD);
  123. InUseBits = (DWORD UNALIGNED*)InUseClusters;
  124. Require(nInUseBits == 2*InUseBits[0] + 1 );
  125. nInUseBits --; InUseBits ++;
  126. while(nInUseBits) {
  127. for(i = 0; i < sizeof(DWORD)*8; i ++ )
  128. if( InUseBits[1] & ( One << i ) )
  129. SetBitForRange(Range, InUseBits[0] + i );
  130. nInUseBits -= 2;
  131. InUseBits += 2;
  132. }
  133. }
  134. if( UsedClusters && UsedClustersSize ) {
  135. nUsedBits = UsedClustersSize/sizeof(DWORD);
  136. UsedBits = (DWORD UNALIGNED*)UsedClusters;
  137. Require(nUsedBits == UsedBits[0] + 1);
  138. nUsedBits --; UsedBits ++;
  139. while(nUsedBits) {
  140. for( i = 0; i < sizeof(DWORD)*8; i ++ )
  141. SetBitForRange(Range, UsedBits[0] + i);
  142. UsedBits ++;
  143. nUsedBits --;
  144. }
  145. }
  146. return ERROR_SUCCESS;
  147. }
  148. static DWORD Masks[] = {
  149. 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80
  150. };
  151. DWORD
  152. DhcpRegpFillBitsForRange(
  153. IN LPBYTE Buffer,
  154. IN ULONG BufSize,
  155. IN OUT PM_RANGE Range,
  156. IN PM_SUBNET Subnet
  157. )
  158. {
  159. ULONG Size, AllocSize, nSet, Offset;
  160. ULONG nBitsSet, Index;
  161. ULONG Error;
  162. Size = ntohl(((UNALIGNED DWORD *)Buffer)[0]);
  163. AllocSize = ntohl(((UNALIGNED DWORD *)Buffer)[1]);
  164. nSet = ntohl(((UNALIGNED DWORD *)Buffer)[2]);
  165. Offset = ntohl(((UNALIGNED DWORD *)Buffer)[3]);
  166. //
  167. // do not check for validity of the offset sizes.
  168. // SetBitForRange does this check anyway.
  169. //
  170. // if( Range->Start + Offset + Size > 1+Range->End )
  171. // return ERROR_INVALID_DATA;
  172. Require(nSet != 0);
  173. if( nSet == 0 ) return ERROR_SUCCESS;
  174. if( nSet == Size ) {
  175. Require( AllocSize == 0 );
  176. for( Index = 0; Index < nSet ; Index ++ ) {
  177. Error = SetBitForRange(Range, Range->Start + Index);
  178. Require( ERROR_SUCCESS == Error );
  179. }
  180. return ERROR_SUCCESS;
  181. }
  182. if( AllocSize + sizeof(DWORD)*4 != BufSize ) return ERROR_INVALID_DATA;
  183. nBitsSet = 0;
  184. Require( Size/8 <= AllocSize );
  185. for( Index = 0; Index < Size ; Index ++ ) {
  186. if( Buffer[ 4*sizeof(DWORD) + (Index/8) ] & Masks[Index%8] ) {
  187. nBitsSet ++;
  188. //
  189. // whistler bug 283457, offset not taken into account
  190. //
  191. Error = SetBitForRange( Range, Range->Start + Index + Offset );
  192. Require( ERROR_SUCCESS == Error );
  193. }
  194. }
  195. Require(nBitsSet == nSet);
  196. return ERROR_SUCCESS;
  197. }
  198. static
  199. BYTE TempBuffer[MAX_BIT1SIZE + sizeof(DWORD)*4];
  200. DWORD
  201. DhcpRegpFillBitmasks(
  202. IN HKEY Key,
  203. IN PM_RANGE Range,
  204. IN PM_SUBNET Subnet
  205. )
  206. {
  207. ULONG Error, nValues, Index;
  208. WCHAR ValueNameBuf[100];
  209. DWORD ValueNameSize, ValueType;
  210. DWORD ValueSize;
  211. WCHAR RangeStartStr[30];
  212. BOOL fPostNt5 = FALSE;
  213. REG_HANDLE Hdl;
  214. if( NULL == Key ) {
  215. ConvertAddressToLPWSTR( Range->Start, RangeStartStr);
  216. fPostNt5 = TRUE;
  217. Error = DhcpRegGetThisServer( &Hdl );
  218. if( NO_ERROR != Error ) return Error;
  219. Key = Hdl.Key;
  220. }
  221. Error = RegQueryInfoKey(
  222. Key, NULL, NULL, NULL, NULL, NULL, NULL, &nValues, NULL, NULL, NULL, NULL
  223. );
  224. if( ERROR_SUCCESS != Error ) goto Cleanup;
  225. Index = nValues -1;
  226. while( nValues ) {
  227. ValueNameSize = sizeof(ValueNameBuf)/sizeof(WCHAR);
  228. ValueSize = sizeof(TempBuffer)/sizeof(WCHAR);
  229. Error = RegEnumValue(
  230. Key,
  231. Index,
  232. ValueNameBuf,
  233. &ValueNameSize,
  234. NULL,
  235. &ValueType,
  236. TempBuffer,
  237. &ValueSize
  238. );
  239. if( ERROR_SUCCESS != Error ) goto Cleanup;
  240. if( fPostNt5 && 0 != wcsncmp(
  241. ValueNameBuf, RangeStartStr, wcslen(RangeStartStr)) ) {
  242. //
  243. // Skip irrelevant bitmaps
  244. //
  245. Index --;
  246. nValues --;
  247. continue;
  248. }
  249. if( REG_BINARY == ValueType && ValueSize >= sizeof(DWORD)*4 ) {
  250. Error = DhcpRegpFillBitsForRange(
  251. TempBuffer,
  252. ValueSize,
  253. Range,
  254. Subnet
  255. );
  256. if( ERROR_SUCCESS != Error ) {
  257. Require(FALSE);
  258. goto Cleanup;
  259. }
  260. }
  261. Index --;
  262. nValues --;
  263. }
  264. Cleanup:
  265. if( fPostNt5 ) {
  266. DhcpRegCloseHdl( &Hdl );
  267. }
  268. return Error;
  269. }
  270. DWORD
  271. DhcpRegpSubnetAddRange(
  272. IN PREG_HANDLE Hdl,
  273. IN LPWSTR RangeName,
  274. IN PM_SUBNET Subnet
  275. )
  276. {
  277. DWORD LocalError;
  278. DWORD Error;
  279. REG_HANDLE Hdl2;
  280. LPWSTR Name = NULL;
  281. LPWSTR Comment = NULL;
  282. DWORD Flags;
  283. DWORD StartAddress;
  284. DWORD EndAddress;
  285. LPBYTE InUseClusters = NULL;
  286. DWORD InUseClustersSize;
  287. LPBYTE UsedClusters = NULL;
  288. DWORD UsedClustersSize;
  289. ULONG Alloc, MaxAlloc;
  290. PM_RANGE OverlappingRange;
  291. PM_RANGE ThisRange = NULL;
  292. BOOL fRangeAdded = FALSE;
  293. Error = DhcpRegSubnetGetRangeHdl(Hdl, RangeName, &Hdl2);
  294. if( ERROR_SUCCESS != Error ) return Error;
  295. Error = DhcpRegRangeGetAttributes(
  296. &Hdl2,
  297. &Name,
  298. &Comment,
  299. &Flags,
  300. &Alloc,
  301. &MaxAlloc,
  302. &StartAddress,
  303. &EndAddress,
  304. &InUseClusters,
  305. &InUseClustersSize,
  306. &UsedClusters,
  307. &UsedClustersSize
  308. );
  309. ERRCHK;
  310. if( 0 == StartAddress || 0 == EndAddress ) {
  311. INVALID_REG("[DHCPServer] Noticed undefined range: %ws (ignored)\n", RangeName);
  312. Error = ERROR_SUCCESS;
  313. goto Cleanup;
  314. }
  315. if( FALSE == Subnet->fSubnet && GlobalWorkingOnPreWin2kMScope ) {
  316. Subnet->MScopeId = StartAddress;
  317. GlobalWorkingOnPreWin2kMScope = FALSE;
  318. }
  319. Error = MemSubnetAddRange(
  320. Subnet,
  321. StartAddress,
  322. EndAddress,
  323. Flags,
  324. Alloc,
  325. MaxAlloc,
  326. &OverlappingRange
  327. );
  328. ERRCHK;
  329. fRangeAdded = TRUE;
  330. Error = MemSubnetGetAddressInfo(
  331. Subnet,
  332. StartAddress,
  333. &ThisRange,
  334. NULL,
  335. NULL
  336. );
  337. ERRCHK;
  338. if( InUseClustersSize || UsedClustersSize ) {
  339. //
  340. // Old style information? Save it as new style
  341. //
  342. GlobalWorkingOnOldStyleSubnet ++;
  343. DhcpRegFillClusterAddresses(
  344. ThisRange,
  345. InUseClusters,
  346. InUseClustersSize,
  347. UsedClusters,
  348. UsedClustersSize
  349. ); // this is always returning ERROR_SUCCESS.
  350. //
  351. // Error = FlushRanges(ThisRange, FLUSH_ANYWAY, Subnet);
  352. // Require( ERROR_SUCCESS == Error );
  353. //
  354. // Do not actually write back the stuff to the registry..
  355. // This read code path is used in dhcpexim at which time
  356. // the registry should not be munged..
  357. //
  358. } else {
  359. //
  360. // Need to read new style bitmasks..
  361. //
  362. Error = DhcpRegpFillBitmasks(
  363. Hdl2.Key,
  364. ThisRange,
  365. Subnet
  366. );
  367. Require( ERROR_SUCCESS == Error );
  368. }
  369. Cleanup:
  370. Report("SubnetAddRange");
  371. if( ERROR_SUCCESS != Error && ThisRange ) {
  372. if( !fRangeAdded ) {
  373. LocalError = MemRangeCleanup(ThisRange);
  374. Require( ERROR_SUCCESS == LocalError );
  375. } else {
  376. LocalError = MemSubnetDelRange(
  377. Subnet, StartAddress );
  378. Require( ERROR_SUCCESS == LocalError );
  379. }
  380. }
  381. if( Name ) MemFree(Name);
  382. if( Comment ) MemFree(Comment);
  383. if( InUseClusters ) MemFree(InUseClusters);
  384. if( UsedClusters ) MemFree(UsedClusters);
  385. LocalError = DhcpRegCloseHdl(&Hdl2);
  386. Require(ERROR_SUCCESS == LocalError);
  387. return Error;
  388. }
  389. DWORD
  390. DhcpRegpReservationAddOption(
  391. IN PREG_HANDLE Hdl,
  392. IN LPWSTR OptionName,
  393. IN PM_RESERVATION Reservation
  394. )
  395. {
  396. DWORD Error;
  397. DWORD LocalError;
  398. REG_HANDLE Hdl2;
  399. DWORD OptionId;
  400. LPWSTR ClassName = NULL;
  401. LPWSTR VendorName = NULL;
  402. DWORD Flags;
  403. LPBYTE Value = NULL;
  404. DWORD ValueSize;
  405. DWORD ClassId;
  406. DWORD VendorId;
  407. PM_OPTION Option = NULL;
  408. PM_OPTION DeletedOption = NULL;
  409. PM_CLASSDEF ThisClasDef;
  410. Error = DhcpRegReservationGetOptHdl(Hdl, OptionName, &Hdl2);
  411. if(ERROR_SUCCESS != Error) return Error;
  412. Error = DhcpRegOptGetAttributes(
  413. &Hdl2,
  414. &OptionId,
  415. &ClassName,
  416. &VendorName,
  417. &Flags,
  418. &Value,
  419. &ValueSize
  420. );
  421. ERRCHK;
  422. if( OptionId == 0 ) // old registry format does not contain "OptionId" value => it can be taken from the key name.
  423. OptionId = _wtol(OptionName);
  424. if( OptionId == 0 || NULL == Value || 0 == ValueSize ) {
  425. INVALID_REG("[DHCPServer] Found invalid option %ws (ignored)\n", OptionName);
  426. Error = ERROR_SUCCESS;
  427. goto Cleanup;
  428. }
  429. if( NULL == ClassName || wcslen(ClassName) == 0) ClassId = 0;
  430. else {
  431. PM_SUBNET Subnet = Reservation->SubnetPtr;
  432. PM_SERVER Server = Subnet->ServerPtr;
  433. Error = MemServerGetClassDef(Server,0, ClassName,0,NULL,&ThisClasDef);
  434. if( ERROR_SUCCESS != Error ) {
  435. if (*(DWORD *)ClassName != OptionId) // some registry entries were corrupted due to an old bug. Load these entries too (see bug #192933)
  436. {
  437. INVALID_REG("ReservationAddOption(%ws): unknown class (ignored)\n", OptionName);
  438. Error = ERROR_SUCCESS;
  439. goto Cleanup;
  440. }
  441. else
  442. {
  443. ClassId = 0;
  444. }
  445. } else {
  446. ClassId = ThisClasDef->ClassId;
  447. Require(ThisClasDef->IsVendor == FALSE);
  448. }
  449. }
  450. if( NULL == VendorName || wcslen(VendorName) == 0 ) VendorId = 0;
  451. else {
  452. PM_SUBNET Subnet = Reservation->SubnetPtr;
  453. PM_SERVER Server = Subnet->ServerPtr;
  454. Error = MemServerGetClassDef(Server,0, VendorName,0,NULL,&ThisClasDef);
  455. if( ERROR_SUCCESS != Error ) {
  456. INVALID_REG("ReservationAddOption(%ws): unknown vendor (ignored)\n", OptionName);
  457. Error = ERROR_SUCCESS;
  458. goto Cleanup;
  459. } else {
  460. VendorId = ThisClasDef->ClassId;
  461. Require(ThisClasDef->IsVendor == TRUE);
  462. }
  463. }
  464. if( 0 == OptionId ) OptionId = ConvertWStringToDWORD(OptionName);
  465. Error = MemOptInit(&Option, OptionId, ValueSize, Value);
  466. ERRCHK;
  467. Error = MemOptClassAddOption(&(Reservation->Options), Option, ClassId, VendorId, &DeletedOption);
  468. ERRCHK;
  469. Cleanup:
  470. Report("ReservationAddOption");
  471. LocalError = DhcpRegCloseHdl(&Hdl2);
  472. Require(ERROR_SUCCESS == LocalError);
  473. if( ClassName ) MemFree(ClassName);
  474. if( VendorName ) MemFree(VendorName);
  475. if( Value ) MemFree(Value);
  476. if( DeletedOption ) {
  477. LocalError = MemOptCleanup(DeletedOption);
  478. Require(ERROR_SUCCESS == LocalError);
  479. }
  480. if( ERROR_SUCCESS != Error && Option ) {
  481. LocalError = MemOptCleanup(Option);
  482. Require(ERROR_SUCCESS == LocalError);
  483. }
  484. return Error;
  485. }
  486. DWORD
  487. DhcpRegpSubnetAddReservation(
  488. IN PREG_HANDLE Hdl,
  489. IN LPWSTR ReservationName,
  490. IN PM_SUBNET Subnet
  491. )
  492. {
  493. DWORD LocalError;
  494. DWORD Error;
  495. REG_HANDLE Hdl2;
  496. LPWSTR Name = NULL;
  497. LPWSTR Comment = NULL;
  498. DWORD Flags;
  499. DWORD Address;
  500. LPBYTE ClientUID = NULL;
  501. DWORD ClientUIDSize;
  502. PM_RESERVATION ThisReservation;
  503. ARRAY Options;
  504. Error = DhcpRegSubnetGetReservationHdl(Hdl, ReservationName, &Hdl2);
  505. if( ERROR_SUCCESS != Error ) return Error;
  506. Error = DhcpRegReservationGetAttributes(
  507. &Hdl2,
  508. &Name,
  509. &Comment,
  510. &Flags,
  511. &Address,
  512. &ClientUID,
  513. &ClientUIDSize
  514. );
  515. ERRCHK;
  516. if( 0 == Address || NULL == ClientUID || 0 == ClientUIDSize ) {
  517. INVALID_REG("[DHCPServer] Found invalid reservation %ws (ignored)\n", ReservationName);
  518. Error = ERROR_SUCCESS;
  519. goto Cleanup;
  520. }
  521. Error = MemReserveAdd(
  522. &(Subnet->Reservations),
  523. Address,
  524. Flags,
  525. ClientUID,
  526. ClientUIDSize
  527. );
  528. // if the reservation is a duplicate ignore the error and do no further processing as the
  529. // reservation structure was already initialized. The duplicate reservation will simply be
  530. // ignored.
  531. if (ERROR_SUCCESS == Error)
  532. {
  533. Error = MemReserveFindByAddress(
  534. &(Subnet->Reservations),
  535. Address,
  536. &ThisReservation
  537. );
  538. ERRCHK;
  539. ThisReservation->SubnetPtr = Subnet;
  540. Error = MemArrayInit(&Options);
  541. ERRCHK;
  542. Error = DhcpRegReservationGetList(
  543. &Hdl2,
  544. &Options
  545. );
  546. ERRCHK;
  547. Error = LoopThruArray(&Options, DhcpRegpReservationAddOption, &Hdl2, ThisReservation);
  548. } else if ( ERROR_OBJECT_ALREADY_EXISTS == Error )
  549. Error = ERROR_SUCCESS;
  550. Cleanup:
  551. Report("SubnetAddReservation");
  552. if( Name ) MemFree(Name);
  553. if( Comment ) MemFree(Comment);
  554. if( ClientUID ) MemFree(ClientUID);
  555. LocalError = DhcpRegCloseHdl(&Hdl2);
  556. Require(ERROR_SUCCESS == LocalError);
  557. FreeArray(&Options);
  558. return Error;
  559. }
  560. DWORD
  561. DhcpRegpSubnetAddOption(
  562. IN PREG_HANDLE Hdl,
  563. IN LPWSTR OptionName,
  564. IN PM_SUBNET Subnet
  565. )
  566. {
  567. DWORD Error;
  568. DWORD LocalError;
  569. REG_HANDLE Hdl2;
  570. DWORD OptionId;
  571. LPWSTR ClassName = NULL;
  572. LPWSTR VendorName = NULL;
  573. DWORD Flags;
  574. LPBYTE Value = NULL;
  575. DWORD ValueSize;
  576. DWORD ClassId;
  577. DWORD VendorId;
  578. PM_OPTION Option = NULL;
  579. PM_OPTION DeletedOption = NULL;
  580. PM_CLASSDEF ThisClasDef;
  581. Error = DhcpRegSubnetGetOptHdl(Hdl, OptionName, &Hdl2);
  582. if(ERROR_SUCCESS != Error) return Error;
  583. Error = DhcpRegOptGetAttributes(
  584. &Hdl2,
  585. &OptionId,
  586. &ClassName,
  587. &VendorName,
  588. &Flags,
  589. &Value,
  590. &ValueSize
  591. );
  592. ERRCHK;
  593. if( OptionId == 0 ) // old registry format does not contain "OptionId" value => it can be taken from the key name.
  594. OptionId = _wtol(OptionName);
  595. if( OptionId == 0 || NULL == Value || 0 == ValueSize ) {
  596. INVALID_REG("[DHCPServer] Found invalid option %ws (ignored)\n", OptionName);
  597. Error = ERROR_SUCCESS;
  598. goto Cleanup;
  599. }
  600. if( NULL == ClassName || wcslen(ClassName) == 0) ClassId = 0;
  601. else {
  602. Error = MemServerGetClassDef((PM_SERVER)(Subnet->ServerPtr),0, ClassName,0,NULL,&ThisClasDef);
  603. if( ERROR_SUCCESS != Error ) {
  604. if (*(DWORD *)ClassName != OptionId) // some registry entries were corrupted due to an old bug. Load these entries too (see bug #192933)
  605. {
  606. INVALID_REG("SubnetAddOption(%ws): unknown class (ignored)\n", OptionName);
  607. Error = ERROR_SUCCESS;
  608. goto Cleanup;
  609. }
  610. else
  611. {
  612. ClassId = 0;
  613. }
  614. } else {
  615. ClassId = ThisClasDef->ClassId;
  616. Require(ThisClasDef->IsVendor == FALSE);
  617. }
  618. }
  619. if( NULL == VendorName || wcslen(VendorName) == 0 ) VendorId = 0;
  620. else {
  621. Error = MemServerGetClassDef((PM_SERVER)(Subnet->ServerPtr),0, VendorName,0,NULL,&ThisClasDef);
  622. if( ERROR_SUCCESS != Error ) {
  623. INVALID_REG("SubnetAddOption(%ws): unknown class (ignored)\n", OptionName);
  624. Error = ERROR_SUCCESS;
  625. goto Cleanup;
  626. } else {
  627. VendorId = ThisClasDef->ClassId;
  628. Require(ThisClasDef->IsVendor == TRUE);
  629. }
  630. }
  631. if( 0 == OptionId ) OptionId = ConvertWStringToDWORD(OptionName);
  632. Error = MemOptInit(&Option, OptionId, ValueSize, Value);
  633. ERRCHK;
  634. Error = MemOptClassAddOption(&(Subnet->Options), Option, ClassId, VendorId, &DeletedOption);
  635. ERRCHK;
  636. Cleanup:
  637. Report("Subnet Add Option");
  638. LocalError = DhcpRegCloseHdl(&Hdl2);
  639. Require(ERROR_SUCCESS == LocalError);
  640. if( ClassName ) MemFree(ClassName);
  641. if( VendorName ) MemFree(VendorName);
  642. if( Value ) MemFree(Value);
  643. if( DeletedOption ) {
  644. LocalError = MemOptCleanup(DeletedOption);
  645. Require(ERROR_SUCCESS == LocalError);
  646. }
  647. if( ERROR_SUCCESS != Error && Option ) {
  648. LocalError = MemOptCleanup(Option);
  649. Require(ERROR_SUCCESS == LocalError);
  650. }
  651. return Error;
  652. }
  653. DWORD
  654. DhcpRegSubnetAddExclusions(
  655. IN PM_SUBNET Subnet,
  656. IN LPBYTE Excl,
  657. IN DWORD ExclSize
  658. )
  659. {
  660. DWORD UNALIGNED* Addr;
  661. DWORD Count, i, j;
  662. DWORD Error;
  663. PM_EXCL OverlappingExcl;
  664. Count = ExclSize / sizeof(DWORD);
  665. Addr = (DWORD UNALIGNED*)Excl;
  666. if( 0 == Count || 0 == Addr[0] || 0 == Addr[1] ) {
  667. INVALID_REG("[DHCPServer] invalid exclusion ignored\n");
  668. return ERROR_SUCCESS;
  669. }
  670. Require(Count == 2*Addr[0] + 1);
  671. Count --; Addr ++;
  672. while(Count) {
  673. Error = MemSubnetAddExcl(
  674. Subnet,
  675. Addr[0],
  676. Addr[1],
  677. &OverlappingExcl
  678. );
  679. if( ERROR_SUCCESS != Error ) {
  680. INVALID_REG("[DHCPServer] DhcpRegSubnetAddExclusions:MemSubnetAddExcl;0x%lx\n", Error);
  681. } else {
  682. if( Subnet->fSubnet && GlobalWorkingOnOldStyleSubnet ) {
  683. //
  684. // For subnets alone (not mscopes), check if
  685. // we are upgrading from pre-win2k -- then make sure
  686. // all address from the excluded range are removed
  687. // from the bitmask
  688. //
  689. for( i = Addr[0]; i <= Addr[1]; i ++ ) {
  690. MemSubnetReleaseAddress(
  691. Subnet, i, FALSE
  692. );
  693. }
  694. }
  695. }
  696. Addr += 2;
  697. Count -= 2;
  698. }
  699. return ERROR_SUCCESS;
  700. }
  701. DWORD
  702. DhcpRegServerAddSubnet(
  703. IN PREG_HANDLE Hdl,
  704. IN PM_SERVER Server,
  705. IN PM_SUBNET Subnet
  706. )
  707. {
  708. DWORD Error;
  709. DWORD Index;
  710. ARRAY Servers;
  711. ARRAY IpRanges;
  712. ARRAY Reservations;
  713. ARRAY Options;
  714. LPBYTE Excl = NULL;
  715. DWORD ExclSize;
  716. struct {
  717. PARRAY Array;
  718. ARRAY_FN Fn;
  719. } Lists[] = {
  720. &Servers, DhcpRegpSubnetAddServer,
  721. &IpRanges, DhcpRegpSubnetAddRange,
  722. &Reservations, DhcpRegpSubnetAddReservation,
  723. &Options, DhcpRegpSubnetAddOption
  724. };
  725. Subnet->ServerPtr = Server;
  726. for( Index = 0; Index < sizeof(Lists)/sizeof(Lists[0]); Index ++ ) {
  727. InitArray(Lists[Index].Array);
  728. }
  729. Error = DhcpRegSubnetGetList(
  730. Hdl, &Servers, &IpRanges, &Reservations, &Options, &Excl, &ExclSize
  731. );
  732. GlobalWorkingOnOldStyleSubnet = 0;
  733. for( Index = 0; Index < sizeof(Lists)/sizeof(Lists[0]); Index ++ ) {
  734. Error = LoopThruArray(Lists[Index].Array, Lists[Index].Fn, Hdl, Subnet);
  735. ERRCHK;
  736. }
  737. if( GlobalWorkingOnOldStyleSubnet ) {
  738. Report("Old style subnet found, careful with exclusions\n");
  739. }
  740. if( Excl ) Error = DhcpRegSubnetAddExclusions(Subnet, Excl, ExclSize);
  741. ERRCHK;
  742. Error = Subnet->fSubnet ? MemServerAddSubnet(Server, Subnet)
  743. : MemServerAddMScope(Server, Subnet);
  744. Cleanup:
  745. GlobalWorkingOnOldStyleSubnet = 0;
  746. GlobalWorkingOnPreWin2kMScope = 0;
  747. Report("ServerAddSubnet");
  748. for( Index = 0; Index < sizeof(Lists)/sizeof(Lists[0]); Index ++ ) {
  749. FreeArray(Lists[Index].Array);
  750. }
  751. return Error;
  752. }
  753. DWORD
  754. DhcpRegServerAddMScope(
  755. IN PREG_HANDLE Hdl,
  756. IN PM_SERVER Server,
  757. IN PM_MSCOPE MScope
  758. )
  759. {
  760. return DhcpRegServerAddSubnet(Hdl, Server, MScope);
  761. }
  762. DWORD
  763. DhcpRegServerAddSScope(
  764. IN PREG_HANDLE Hdl,
  765. IN PM_SERVER Server,
  766. IN PM_SSCOPE SScope
  767. )
  768. {
  769. DWORD Error;
  770. ARRAY Subnets;
  771. ARRAY_LOCATION Loc;
  772. LPWSTR SubnetWString;
  773. DWORD SubnetAddress;
  774. PM_SUBNET Subnet;
  775. InitArray(&Subnets);
  776. Error = DhcpRegSScopeGetList(Hdl, &Subnets);
  777. ERRCHK;
  778. Error = MemArrayInitLoc(&Subnets, &Loc);
  779. while(ERROR_FILE_NOT_FOUND != Error) {
  780. Require(ERROR_SUCCESS == Error);
  781. Error = MemArrayGetElement(&Subnets, &Loc, &SubnetWString);
  782. Require(ERROR_SUCCESS == Error && SubnetWString);
  783. SubnetAddress = WStringToAddress(SubnetWString);
  784. Error = MemServerGetAddressInfo(
  785. Server,
  786. SubnetAddress,
  787. &Subnet,
  788. NULL,
  789. NULL,
  790. NULL
  791. );
  792. if( ERROR_SUCCESS == Error && Subnet ) {
  793. Error = MemSubnetSetSuperScope(Subnet,SScope);
  794. Require(ERROR_SUCCESS == Error);
  795. }
  796. Error = MemArrayNextLoc(&Subnets, &Loc);
  797. }
  798. Error = MemServerAddSScope(Server, SScope);
  799. Cleanup:
  800. Report("ServerAddSScope");
  801. FreeArray(&Subnets);
  802. return Error;
  803. }
  804. DWORD
  805. DhcpRegpServerAddSubnet(
  806. IN PREG_HANDLE Hdl,
  807. IN LPWSTR SubnetName,
  808. IN PM_SERVER Server
  809. )
  810. {
  811. DWORD Error;
  812. DWORD LocalError;
  813. REG_HANDLE Hdl2;
  814. LPWSTR Name = NULL;
  815. LPWSTR Comment = NULL;
  816. DWORD Address;
  817. DWORD Flags;
  818. DWORD Mask;
  819. PM_SUBNET Subnet = NULL;
  820. Error = DhcpRegServerGetSubnetHdl(Hdl, SubnetName, &Hdl2);
  821. if(ERROR_SUCCESS != Error) return Error;
  822. Error = DhcpRegSubnetGetAttributes(
  823. &Hdl2,
  824. &Name,
  825. &Comment,
  826. &Flags,
  827. &Address,
  828. &Mask
  829. );
  830. ERRCHK;
  831. if( NULL == Name || 0 == Address || 0 == Mask ) {
  832. INVALID_REG("[DHCPServer] invalid subnet %ws ignored\n", SubnetName);
  833. Error = ERROR_SUCCESS;
  834. goto Cleanup;
  835. }
  836. Error = MemSubnetInit(
  837. &Subnet,
  838. Address,
  839. Mask,
  840. Flags,
  841. 0,
  842. Name,
  843. Comment
  844. );
  845. ERRCHK;
  846. Error = DhcpRegServerAddSubnet(&Hdl2, Server, Subnet);
  847. Cleanup:
  848. Report("ServerAddSubnet");
  849. LocalError = DhcpRegCloseHdl(&Hdl2);
  850. Require( ERROR_SUCCESS == LocalError);
  851. if( Name ) MemFree(Name);
  852. if( Comment ) MemFree(Comment);
  853. if( ERROR_SUCCESS != Error ) {
  854. if( Subnet ) {
  855. LocalError = MemSubnetCleanup(Subnet);
  856. Require(ERROR_SUCCESS == LocalError);
  857. }
  858. }
  859. return Error;
  860. }
  861. DWORD
  862. DhcpRegpServerAddMScope(
  863. IN PREG_HANDLE Hdl,
  864. IN LPWSTR MScopeName,
  865. IN PM_SERVER Server
  866. ) {
  867. DWORD Error;
  868. DWORD LocalError;
  869. REG_HANDLE Hdl2;
  870. LPWSTR Comment = NULL;
  871. DWORD State;
  872. DWORD ScopeId;
  873. DWORD Policy;
  874. PM_MSCOPE MScope = NULL;
  875. LPWSTR LangTag = NULL;
  876. DWORD TTL = 32;
  877. PDATE_TIME ExpiryTime = NULL;
  878. GlobalWorkingOnPreWin2kMScope = 0;
  879. Error = DhcpRegServerGetMScopeHdl(Hdl, MScopeName, &Hdl2);
  880. if(ERROR_SUCCESS != Error) return Error;
  881. Error = DhcpRegMScopeGetAttributes(
  882. &Hdl2,
  883. &Comment,
  884. &State,
  885. &ScopeId,
  886. &Policy,
  887. &TTL,
  888. &LangTag,
  889. &ExpiryTime
  890. );
  891. if( ERROR_INVALID_DATA == Error ) {
  892. GlobalWorkingOnPreWin2kMScope = TRUE;
  893. //
  894. // hackorama isn't it?
  895. //
  896. Error = NO_ERROR;
  897. }
  898. ERRCHK;
  899. if( 0 == ScopeId || GlobalWorkingOnPreWin2kMScope ) {
  900. INVALID_REG("[DHCPServer] invalid m-scope %ws, id %ld ignored\n", MScopeName, ScopeId);
  901. Error = ERROR_SUCCESS;
  902. //goto Cleanup;
  903. }
  904. Error = MemMScopeInit(
  905. &MScope,
  906. ScopeId,
  907. State,
  908. Policy,
  909. (BYTE)TTL,
  910. MScopeName,
  911. Comment,
  912. LangTag,
  913. *ExpiryTime
  914. );
  915. ERRCHK;
  916. Error = DhcpRegServerAddMScope(&Hdl2, Server, MScope);
  917. Cleanup:
  918. GlobalWorkingOnPreWin2kMScope = 0;
  919. Report("Server Add MScope");
  920. LocalError = DhcpRegCloseHdl(&Hdl2);
  921. Require(ERROR_SUCCESS == LocalError);
  922. if( Comment ) MemFree(Comment);
  923. if( LangTag ) MemFree(LangTag);
  924. if( ExpiryTime ) MemFree(ExpiryTime);
  925. if( ERROR_SUCCESS != Error ) {
  926. if( MScope ) {
  927. LocalError = MemMScopeCleanup(MScope);
  928. Require(ERROR_SUCCESS == Error);
  929. }
  930. }
  931. return Error;
  932. }
  933. DWORD
  934. DhcpRegpServerAddSScope(
  935. IN PREG_HANDLE Hdl,
  936. IN LPWSTR SScopeName,
  937. IN PM_SERVER Server
  938. ) {
  939. DWORD Error;
  940. DWORD LocalError;
  941. REG_HANDLE Hdl2;
  942. LPWSTR Name = NULL;
  943. LPWSTR Comment = NULL;
  944. DWORD Flags;
  945. PM_SSCOPE SScope = NULL;
  946. Error = DhcpRegServerGetSScopeHdl(Hdl, SScopeName, &Hdl2);
  947. if(ERROR_SUCCESS != Error) return Error;
  948. #if 0 // superscope name is given above -- nothing else to be done
  949. Error = DhcpRegSScopeGetAttributes(
  950. &Hdl2,
  951. &Name,
  952. &Description,
  953. &Flags
  954. );
  955. ERRCHK;
  956. #endif
  957. Error = MemSScopeInit(
  958. &SScope,
  959. 0,
  960. SScopeName
  961. );
  962. ERRCHK;
  963. Error = DhcpRegServerAddSScope(&Hdl2, Server, SScope);
  964. Cleanup:
  965. Report("Server Add Scope");
  966. LocalError = DhcpRegCloseHdl(&Hdl2);
  967. Require(ERROR_SUCCESS == LocalError);
  968. if( ERROR_SUCCESS != Error ) {
  969. if( SScope ) {
  970. LocalError = MemSScopeCleanup(SScope);
  971. Require(ERROR_SUCCESS == Error);
  972. }
  973. }
  974. return Error;
  975. }
  976. DWORD
  977. DhcpRegpServerAddOption(
  978. IN PREG_HANDLE Hdl,
  979. IN LPWSTR OptionName,
  980. IN PM_SERVER Server
  981. ) {
  982. DWORD Error;
  983. DWORD LocalError;
  984. REG_HANDLE Hdl2;
  985. DWORD OptionId;
  986. LPWSTR ClassName = NULL;
  987. LPWSTR VendorName = NULL;
  988. DWORD Flags;
  989. LPBYTE Value = NULL;
  990. DWORD ValueSize;
  991. DWORD ClassId;
  992. DWORD VendorId;
  993. PM_OPTION Option = NULL;
  994. PM_OPTION DeletedOption = NULL;
  995. PM_CLASSDEF ThisClasDef;
  996. Error = DhcpRegServerGetOptHdl(Hdl, OptionName, &Hdl2);
  997. if(ERROR_SUCCESS != Error) return Error;
  998. Error = DhcpRegOptGetAttributes(
  999. &Hdl2,
  1000. &OptionId,
  1001. &ClassName,
  1002. &VendorName,
  1003. &Flags,
  1004. &Value,
  1005. &ValueSize
  1006. );
  1007. ERRCHK;
  1008. if( OptionId == 0 ) // old registry format does not contain "OptionId" value => it can be taken from the key name.
  1009. OptionId = _wtol(OptionName);
  1010. if( 0 == OptionId || NULL == Value || 0 == ValueSize ) {
  1011. INVALID_REG("[DHCPServer] found invalid option %ws (ignored)\n", OptionName );
  1012. Error = ERROR_SUCCESS;
  1013. goto Cleanup;
  1014. }
  1015. if( NULL == ClassName || wcslen(ClassName) == 0) ClassId = 0;
  1016. else {
  1017. Error = MemServerGetClassDef(Server,0, ClassName,0,NULL,&ThisClasDef);
  1018. if( ERROR_SUCCESS != Error ) {
  1019. if (*(DWORD *)ClassName != OptionId) // some registry entries were corrupted due to an old bug. Load these entries too (see bug #192933)
  1020. {
  1021. INVALID_REG("ServerAddOption(%ws): unknown class (ignored)\n", OptionName);
  1022. Error = ERROR_SUCCESS;
  1023. goto Cleanup;
  1024. }
  1025. else
  1026. {
  1027. ClassId = 0;
  1028. }
  1029. } else {
  1030. ClassId = ThisClasDef->ClassId;
  1031. Require(ThisClasDef->IsVendor == FALSE);
  1032. }
  1033. }
  1034. if( NULL == VendorName || wcslen(VendorName) == 0) VendorId = 0;
  1035. else {
  1036. Error = MemServerGetClassDef(Server,0, VendorName,0,NULL,&ThisClasDef);
  1037. if( ERROR_SUCCESS != Error ) {
  1038. INVALID_REG("ServerAddOption(%ws): unknown class (ignored)\n", OptionName);
  1039. Error = ERROR_SUCCESS;
  1040. goto Cleanup;
  1041. } else {
  1042. VendorId = ThisClasDef->ClassId;
  1043. Require(ThisClasDef->IsVendor == TRUE);
  1044. }
  1045. }
  1046. Error = MemOptInit(&Option, OptionId, ValueSize, Value);
  1047. ERRCHK;
  1048. Error = MemOptClassAddOption(&(Server->Options), Option, ClassId, VendorId, &DeletedOption);
  1049. ERRCHK;
  1050. Cleanup:
  1051. Report("Server Add Option");
  1052. LocalError = DhcpRegCloseHdl(&Hdl2);
  1053. Require(ERROR_SUCCESS == LocalError);
  1054. if( ClassName ) MemFree(ClassName);
  1055. if( VendorName ) MemFree(VendorName);
  1056. if( Value ) MemFree(Value);
  1057. if( DeletedOption ) {
  1058. LocalError = MemOptCleanup(DeletedOption);
  1059. Require(ERROR_SUCCESS == LocalError);
  1060. }
  1061. if( ERROR_SUCCESS != Error && Option ) {
  1062. LocalError = MemOptCleanup(Option);
  1063. Require(ERROR_SUCCESS == LocalError);
  1064. }
  1065. return Error;
  1066. }
  1067. DWORD
  1068. DhcpRegpServerAddDefList(
  1069. IN PREG_HANDLE Hdl,
  1070. IN LPWSTR DefName,
  1071. IN PM_SERVER Server
  1072. ) {
  1073. DWORD Error;
  1074. DWORD LocalError;
  1075. REG_HANDLE Hdl2;
  1076. LPWSTR Name = NULL;
  1077. LPWSTR Comments = NULL;
  1078. DWORD Flags;
  1079. DWORD OptionId;
  1080. LPWSTR ClassName = NULL;
  1081. LPWSTR VendorName = NULL;
  1082. DWORD ClassId;
  1083. DWORD VendorId;
  1084. LPBYTE Value = NULL;
  1085. DWORD ValueSize;
  1086. PM_CLASSDEF ThisClassDef;
  1087. Error = DhcpRegServerGetOptDefHdl(Hdl, DefName, &Hdl2);
  1088. if(ERROR_SUCCESS != Error) return Error;
  1089. Error = DhcpRegOptDefGetAttributes(
  1090. &Hdl2,
  1091. &Name,
  1092. &Comments,
  1093. &Flags,
  1094. &OptionId,
  1095. &ClassName,
  1096. &VendorName,
  1097. &Value,
  1098. &ValueSize
  1099. );
  1100. ERRCHK;
  1101. if( OptionId == 0)
  1102. OptionId = _wtol(DefName);
  1103. if( NULL == Name || 0 == OptionId ) {
  1104. INVALID_REG("[DHCPServer] invalid option def %ws ignored\n", DefName );
  1105. Error = ERROR_SUCCESS;
  1106. goto Cleanup;
  1107. }
  1108. if( NULL == ClassName || wcslen(ClassName) == 0) ClassId = 0;
  1109. else {
  1110. Error = MemServerGetClassDef(Server,0, ClassName,0,NULL,&ThisClassDef);
  1111. if( ERROR_SUCCESS != Error ) ClassId = 0;
  1112. else {
  1113. ClassId = ThisClassDef->ClassId;
  1114. Require(ThisClassDef->IsVendor == FALSE);
  1115. }
  1116. }
  1117. if( NULL == VendorName || wcslen(VendorName) == 0 ) VendorId = 0;
  1118. else {
  1119. Error = MemServerGetClassDef(Server,0, VendorName,0,NULL,&ThisClassDef);
  1120. if( ERROR_SUCCESS != Error ) VendorId = 0;
  1121. else {
  1122. VendorId = ThisClassDef->ClassId;
  1123. Require(ThisClassDef->IsVendor == TRUE);
  1124. }
  1125. }
  1126. Error = MemOptClassDefListAddOptDef(
  1127. &(Server->OptDefs),
  1128. ClassId,
  1129. VendorId,
  1130. OptionId,
  1131. Flags,
  1132. Name,
  1133. Comments,
  1134. Value,
  1135. ValueSize
  1136. );
  1137. Cleanup:
  1138. Report("Server Add DefList");
  1139. LocalError = DhcpRegCloseHdl(&Hdl2);
  1140. Require(ERROR_SUCCESS == LocalError);
  1141. if( Name ) MemFree(Name);
  1142. if( Comments ) MemFree(Comments);
  1143. if( ClassName ) MemFree(ClassName);
  1144. if( VendorName ) MemFree(VendorName);
  1145. if( Value ) MemFree(Value);
  1146. return Error;
  1147. }
  1148. DWORD
  1149. DhcpRegpServerAddClassDef(
  1150. IN PREG_HANDLE Hdl,
  1151. IN LPWSTR ClassDefName,
  1152. IN PM_SERVER Server
  1153. ) {
  1154. DWORD Error;
  1155. DWORD LocalError;
  1156. REG_HANDLE Hdl2;
  1157. LPWSTR Name = NULL;
  1158. LPWSTR Comment = NULL;
  1159. DWORD Flags;
  1160. LPBYTE Value = NULL;
  1161. DWORD ValueSize;
  1162. Error = DhcpRegServerGetClassDefHdl(Hdl, ClassDefName, &Hdl2);
  1163. if(ERROR_SUCCESS != Error) return Error;
  1164. Error = DhcpRegClassDefGetAttributes(
  1165. &Hdl2,
  1166. &Name,
  1167. &Comment,
  1168. &Flags,
  1169. &Value,
  1170. &ValueSize
  1171. );
  1172. ERRCHK;
  1173. if( NULL == Name || 0 == ValueSize || NULL == Value ) {
  1174. INVALID_REG("[DHCPServer] invalid class def %ws ignored\n", ClassDefName);
  1175. Error = ERROR_SUCCESS;
  1176. goto Cleanup;
  1177. }
  1178. Error = MemClassDefListAddClassDef(
  1179. &(Server->ClassDefs),
  1180. MemNewClassId(),
  1181. Flags,
  1182. 0, /* no Type... */
  1183. Name,
  1184. Comment,
  1185. Value,
  1186. ValueSize
  1187. );
  1188. ERRCHK;
  1189. Cleanup:
  1190. Report("Server Add ClassDef");
  1191. LocalError = DhcpRegCloseHdl(&Hdl2);
  1192. Require(ERROR_SUCCESS == LocalError);
  1193. if( Name ) MemFree(Name);
  1194. if( Comment ) MemFree(Comment);
  1195. if( Value ) MemFree(Value);
  1196. return Error;
  1197. }
  1198. //BeginExport(function)
  1199. DWORD
  1200. DhcpRegReadSubServer( // read all the sub objects of a server and add 'em
  1201. IN PREG_HANDLE Hdl,
  1202. IN OUT PM_SERVER Server
  1203. ) //EndExport(function)
  1204. {
  1205. DWORD Error;
  1206. DWORD Index;
  1207. ARRAY OptList;
  1208. ARRAY DefList;
  1209. ARRAY ClassDefs;
  1210. ARRAY Subnets;
  1211. ARRAY MScopes;
  1212. ARRAY SScopes;
  1213. struct {
  1214. PARRAY Array;
  1215. ARRAY_FN Fn;
  1216. } Lists[] = {
  1217. &ClassDefs, DhcpRegpServerAddClassDef,
  1218. &DefList, DhcpRegpServerAddDefList,
  1219. &OptList, DhcpRegpServerAddOption,
  1220. &Subnets, DhcpRegpServerAddSubnet,
  1221. &MScopes, DhcpRegpServerAddMScope,
  1222. &SScopes, DhcpRegpServerAddSScope
  1223. };
  1224. for( Index = 0; Index < sizeof(Lists)/sizeof(Lists[0]); Index ++ ) {
  1225. InitArray(Lists[Index].Array);
  1226. }
  1227. Error = DhcpRegServerGetList(
  1228. Hdl, &OptList, &DefList, &Subnets, &SScopes, &ClassDefs, &MScopes
  1229. );
  1230. ERRCHK;
  1231. for( Index = 0; Index < sizeof(Lists)/sizeof(Lists[0]); Index ++ ) {
  1232. Error = LoopThruArray(Lists[Index].Array, Lists[Index].Fn, Hdl, Server);
  1233. ERRCHK;
  1234. }
  1235. Cleanup:
  1236. for( Index = 0; Index < sizeof(Lists)/sizeof(Lists[0]); Index ++ ) {
  1237. FreeArray(Lists[Index].Array);
  1238. }
  1239. Report("ServerAddSubServer");
  1240. return Error;
  1241. }
  1242. //BeginExport(function)
  1243. DWORD
  1244. DhcpRegReadServer( // read the server and all its sub objects
  1245. IN PREG_HANDLE Hdl,
  1246. OUT PM_SERVER *Server // return the created object
  1247. ) //EndExport(function)
  1248. {
  1249. DWORD Error;
  1250. LPWSTR Name;
  1251. LPWSTR Comments;
  1252. DWORD Flags;
  1253. PM_SERVER ThisServer;
  1254. Name = NULL; Comments = NULL; Flags = 0; ThisServer = NULL;
  1255. Error = DhcpRegServerGetAttributes(
  1256. Hdl,
  1257. &Name,
  1258. &Comments,
  1259. &Flags
  1260. );
  1261. if( ERROR_SUCCESS != Error ) goto Cleanup;
  1262. Error = MemServerInit(
  1263. &ThisServer,
  1264. 0xFFFFFFFF,
  1265. Flags,
  1266. 0,
  1267. Name,
  1268. Comments
  1269. );
  1270. if( ERROR_SUCCESS != Error ) goto Cleanup;
  1271. Error = DhcpRegReadSubServer(Hdl, ThisServer);
  1272. if( ERROR_SUCCESS != Error ) goto Cleanup;
  1273. *Server = ThisServer;
  1274. Cleanup:
  1275. if( NULL != Name ) MemFree(Name);
  1276. if( NULL != Comments) MemFree(Comments);
  1277. if( ERROR_SUCCESS != Error && NULL != ThisServer) {
  1278. MemServerCleanup(ThisServer);
  1279. }
  1280. return Error;
  1281. }
  1282. //BeginExport(function)
  1283. DWORD
  1284. DhcpRegReadThisServer( // recursively read for the current server
  1285. OUT PM_SERVER *Server
  1286. ) //EndExport(function)
  1287. {
  1288. DWORD Error;
  1289. REG_HANDLE ThisServer;
  1290. LPWSTR Name;
  1291. LPWSTR Comment;
  1292. Error = DhcpRegGetThisServer(&ThisServer);
  1293. if( ERROR_SUCCESS != Error ) return Error;
  1294. Error = DhcpRegReadServer(&ThisServer, Server);
  1295. DhcpRegCloseHdl(&ThisServer);
  1296. return Error;
  1297. }
  1298. DWORD
  1299. DhcpRegReadScopeBitmasks(
  1300. IN OUT PM_SUBNET Scope
  1301. )
  1302. {
  1303. PM_RANGE Range;
  1304. ARRAY_LOCATION Loc;
  1305. DWORD Error;
  1306. WCHAR SubnetStr[sizeof("000.000.000.000")];
  1307. REG_HANDLE Hdl, Hdl1;
  1308. #if 0
  1309. Error = DhcpRegGetThisServer(&Hdl);
  1310. if( NO_ERROR != Error ) return Error;
  1311. if( Scope->fSubnet ) {
  1312. Error = DhcpRegServerGetSubnetHdl(
  1313. &Hdl, ConvertAddressToLPWSTR(
  1314. Scope->Address, SubnetStr), &Hdl1);
  1315. } else {
  1316. Error = DhcpRegServerGetMScopeHdl(
  1317. &Hdl, Scope->Name, &Hdl1 );
  1318. }
  1319. DhcpRegCloseHdl( &Hdl );
  1320. if( NO_ERROR != Error ) return Error;
  1321. #endif
  1322. Error = MemArrayInitLoc( &Scope->Ranges, &Loc);
  1323. while( NO_ERROR == Error ) {
  1324. Error = MemArrayGetElement( &Scope->Ranges, &Loc, &Range );
  1325. Require( NO_ERROR == Error && NULL != Range );
  1326. //
  1327. // Fill in the range
  1328. //
  1329. #if 0
  1330. Error = DhcpRegSubnetGetRangeHdl(
  1331. &Hdl1, ConvertAddressToLPWSTR(
  1332. Range->Start, SubnetStr ), &Hdl );
  1333. if( NO_ERROR != Error ) break;
  1334. Error = DhcpRegpFillBitmasks(
  1335. Hdl.Key, Range, Scope );
  1336. DhcpRegCloseHdl( &Hdl );
  1337. if( NO_ERROR != Error ) break;
  1338. #else
  1339. Error = DhcpRegpFillBitmasks(
  1340. NULL, Range, Scope );
  1341. ASSERT( NO_ERROR == Error );
  1342. #endif
  1343. Error = MemArrayNextLoc( &Scope->Ranges, &Loc );
  1344. }
  1345. #if 0
  1346. DhcpRegCloseHdl( &Hdl1 );
  1347. #endif
  1348. if( ERROR_FILE_NOT_FOUND != Error ) return Error;
  1349. return NO_ERROR;
  1350. }
  1351. //BeginExport(function)
  1352. DWORD
  1353. DhcpRegReadServerBitmasks(
  1354. IN OUT PM_SERVER Server
  1355. ) // EndExport(function)
  1356. {
  1357. PM_SUBNET Scope, MScope;
  1358. ARRAY_LOCATION Loc;
  1359. DWORD Error;
  1360. Error = MemArrayInitLoc(&Server->Subnets, &Loc);
  1361. while( NO_ERROR == Error ) {
  1362. Error = MemArrayGetElement( &Server->Subnets, &Loc, &Scope);
  1363. Require( NO_ERROR == Error && NULL != Scope );
  1364. //
  1365. // get the keys to the scope in question
  1366. //
  1367. Error = DhcpRegReadScopeBitmasks(Scope);
  1368. if( NO_ERROR != Error ) return Error;
  1369. Error = MemArrayNextLoc( &Server->Subnets, &Loc );
  1370. }
  1371. if( ERROR_FILE_NOT_FOUND != Error ) return Error;
  1372. Error = MemArrayInitLoc(&Server->MScopes, &Loc);
  1373. while( NO_ERROR == Error ) {
  1374. Require( ERROR_SUCCESS == Error );
  1375. Error = MemArrayGetElement( &Server->MScopes, &Loc, &MScope);
  1376. Require( NO_ERROR == Error && NULL != MScope );
  1377. //
  1378. // get the keys to the scope in question
  1379. //
  1380. Error = DhcpRegReadScopeBitmasks(MScope);
  1381. if( NO_ERROR != Error ) return Error;
  1382. Error = MemArrayNextLoc( &Server->MScopes, &Loc );
  1383. }
  1384. if( ERROR_FILE_NOT_FOUND != Error ) return Error;
  1385. return NO_ERROR;
  1386. }
  1387. //================================================================================
  1388. // end of file
  1389. //================================================================================