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.

644 lines
24 KiB

  1. //================================================================================
  2. // Copyright (C) 1997 Microsoft Corporation
  3. // Author: RameshV
  4. // Description: Download and Upload related code.
  5. //================================================================================
  6. //================================================================================
  7. // includes
  8. //================================================================================
  9. #include <hdrmacro.h>
  10. #include <store.h>
  11. #include <dhcpmsg.h>
  12. #include <wchar.h>
  13. #include <dhcpbas.h>
  14. #include <mm\opt.h>
  15. #include <mm\optl.h>
  16. #include <mm\optdefl.h>
  17. #include <mm\optclass.h>
  18. #include <mm\classdefl.h>
  19. #include <mm\bitmask.h>
  20. #include <mm\reserve.h>
  21. #include <mm\range.h>
  22. #include <mm\subnet.h>
  23. #include <mm\sscope.h>
  24. #include <mm\oclassdl.h>
  25. #include <mm\server.h>
  26. #include <mm\address.h>
  27. #include <mm\server2.h>
  28. #include <mm\memfree.h>
  29. #include <mmreg\regutil.h>
  30. #include <mmreg\regread.h>
  31. #include <mmreg\regsave.h>
  32. #include <dhcpapi.h>
  33. #include <delete.h>
  34. #include <st_srvr.h>
  35. #include <rpcapi2.h>
  36. #include <rpcstubs.h>
  37. //================================================================================
  38. // utilities
  39. //================================================================================
  40. //DOC DhcpDsServerGetLastUpdateTime gets the last update time for this server in the DS
  41. DWORD
  42. DhcpDsServerGetLastUpdateTime( // get last update time for server
  43. IN LPSTORE_HANDLE hServer, // server to get last update time of
  44. IN OUT LPFILETIME Time // set this struct appropriately
  45. )
  46. {
  47. HRESULT Err;
  48. DWORD nAttributes;
  49. LPWSTR TimeAttrName; // attribute name for time..
  50. PADS_ATTR_INFO Attributes;
  51. SYSTEMTIME SysTime;
  52. TimeAttrName = DHCP_ATTRIB_WHEN_CHANGED;
  53. Attributes = NULL; nAttributes = 0;
  54. Err = ADSIGetObjectAttributes // now read the last changed time attr
  55. (
  56. hServer->ADSIHandle,
  57. &TimeAttrName,
  58. 1, // only 1 attribute in above array
  59. &Attributes,
  60. &nAttributes
  61. );
  62. if( FAILED(Err) || 0 == nAttributes || 0 == Attributes->dwNumValues ) {
  63. if( Attributes ) {
  64. FreeADsMem(Attributes);
  65. return ERROR_GEN_FAILURE; // blanket error? maybe better err msg..
  66. }
  67. return ConvertHresult(Err);
  68. }
  69. if( Attributes->pADsValues[0].dwType != ADSTYPE_UTC_TIME ) {
  70. FreeADsMem(Attributes);
  71. return ERROR_GEN_FAILURE; // unexpected data format
  72. }
  73. SysTime = Attributes->pADsValues[0].UTCTime; // copy time structs
  74. FreeADsMem(Attributes);
  75. Err = SystemTimeToFileTime(&SysTime, Time); // try to convert to filetime struct
  76. if( FAILED( Err ) ) return GetLastError(); // something went wrong?
  77. return ERROR_SUCCESS;
  78. }
  79. BOOL _inline
  80. AddressFoundInHostent(
  81. IN DHCP_IP_ADDRESS AddrToSearch, // Host-Order addr
  82. IN HOSTENT *ServerEntry // entry to search for..
  83. )
  84. {
  85. ULONG nAddresses, ThisAddress;
  86. if( NULL == ServerEntry ) return FALSE; // no address to search in
  87. nAddresses = 0; // have a host entry to compare for addresses
  88. while( ServerEntry->h_addr_list[nAddresses] ) {
  89. ThisAddress = ntohl(*(DHCP_IP_ADDRESS*)ServerEntry->h_addr_list[nAddresses++] );
  90. if( ThisAddress == AddrToSearch ) {
  91. return TRUE; // yeah address matched.
  92. }
  93. }
  94. return FALSE;
  95. }
  96. //================================================================================
  97. // exports
  98. //================================================================================
  99. //BeginExport(function)
  100. //DOC DhcpDsGetLastUpdateTime gets the last update time for the server
  101. //DOC specified by name. If the server does not exist, or if server object doesnt
  102. //DOC exist, then an error is returned. If the time value
  103. //DOC does not exist on the server object, again, an error is returned.
  104. DWORD
  105. DhcpDsGetLastUpdateTime( // last update time for server
  106. IN LPWSTR ServerName, // this is server of interest
  107. IN OUT LPFILETIME Time // fill in this w./ the time
  108. ) //EndExport(function)
  109. {
  110. DWORD Err,i, LocType ;
  111. LPDHCPDS_SERVERS Servers;
  112. extern STORE_HANDLE hDhcpC, hDhcpRoot; // From rpcstubs.c
  113. LPWSTR Location, LocStr;
  114. BOOL Found;
  115. STORE_HANDLE hServer;
  116. HOSTENT *ServerEntry;
  117. if( NULL == ServerName ) return ERROR_INVALID_PARAMETER;
  118. do { // name to IP lookup
  119. CHAR TmpBuf[300];
  120. wcstombs(TmpBuf, ServerName, sizeof(TmpBuf)-1);
  121. TmpBuf[sizeof(TmpBuf)-1] = '\0';
  122. ServerEntry = gethostbyname(TmpBuf);
  123. } while(0);
  124. Servers = NULL;
  125. Err = DhcpDsEnumServers // first get a list of servers
  126. (
  127. /* hDhcpC */ &hDhcpC, // frm rpcstubs.c, opened in DhcpDsInitDS
  128. /* hDhcpRoot */ &hDhcpRoot, // ditto
  129. /* Reserved */ DDS_RESERVED_DWORD,
  130. /* ServersInfo */ &Servers
  131. );
  132. if( ERROR_SUCCESS != Err ) {
  133. Time->dwLowDateTime = Time->dwHighDateTime = 0;
  134. return Err; // error.. return w/ no time
  135. }
  136. Found = FALSE;
  137. LocStr = Location = NULL; // initialize..
  138. for( i = 0; i < Servers->NumElements ; i ++ ) {
  139. if( 0 != _wcsicmp(ServerName, Servers->Servers[i].ServerName) &&
  140. !AddressFoundInHostent(Servers->Servers[i].ServerAddress, ServerEntry) ) {
  141. continue; // ughm.. not the same server..
  142. } else { // ok got the server
  143. Location = Servers->Servers[i].DsLocation;
  144. LocType = Servers->Servers[i].DsLocType;
  145. Found = TRUE;
  146. if( NULL != Location ) break;
  147. }
  148. }
  149. if( ! Found ) { // could not find server in list..?
  150. MemFree(Servers);
  151. return ERROR_FILE_NOT_FOUND;
  152. }
  153. if( NULL == Location ) { // could not find server location?
  154. MemFree(Servers); // dont need this anymore
  155. Servers = NULL;
  156. Location = MakeColumnName(ServerName); // just presume it is under hDhcpC container
  157. LocType = StoreGetChildType; // child type
  158. if( NULL == Location ) return ERROR_NOT_ENOUGH_MEMORY;
  159. }
  160. Err = StoreGetHandle // now try to open the server object
  161. (
  162. /* hStore */ &hDhcpC,
  163. /* Reserved */ DDS_RESERVED_DWORD,
  164. /* StoreGetType */ LocType,
  165. /* Path */ Location,
  166. /* hStoreOut */ &hServer
  167. );
  168. if( Servers ) { // Location points into this
  169. MemFree(Servers); // freeing this also free Location
  170. } else { // Location is allocated memory
  171. MemFree(Location);
  172. }
  173. if( ERROR_SUCCESS != Err ) return Err; // some DS trouble?
  174. Err = DhcpDsServerGetLastUpdateTime(&hServer, Time);
  175. (void)StoreCleanupHandle(&hServer, 0); // assume this wont fail.
  176. return Err;
  177. }
  178. //DOC ServerUploadClasses does rpc calls to server and copies stuff over to DS.
  179. DWORD
  180. ServerUploadClasses( // upload classes info to DS
  181. IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
  182. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  183. IN LPWSTR ServerAddress // server ip address
  184. )
  185. {
  186. DWORD Err, Resume, PrefMax, i, nRead, nTotal;
  187. LPDHCP_CLASS_INFO_ARRAY ClassesInfo;
  188. Resume = 0; PrefMax = 0xFFFFFFFF; nRead = nTotal = 0;
  189. ClassesInfo = NULL;
  190. Err = DhcpEnumClasses(ServerAddress, 0, &Resume, PrefMax, &ClassesInfo, &nRead, &nTotal);
  191. if( ERROR_NO_MORE_ITEMS == Err ) return ERROR_SUCCESS;
  192. if( ERROR_SUCCESS != Err ) return Err; // could not enumerate classes.
  193. for( i = 0; i < ClassesInfo->NumElements; i ++ ) {
  194. Err = DhcpCreateClassDS(ServerAddress, 0, &ClassesInfo->Classes[i]);
  195. if( ERROR_SUCCESS != Err ) break;
  196. #if 0
  197. Err = ServerUploadOptDefsForClass(
  198. hDhcpC,
  199. hServer,
  200. ServerAddress,
  201. ClassesInfo->Classes[i].ClassName
  202. );
  203. if( ERROR_SUCCESS != Err ) break;
  204. #endif
  205. }
  206. if( ClassesInfo ) MemFree(ClassesInfo);
  207. return Err;
  208. }
  209. //DOC ServerUploadOptdefs does rpc calls to server and copies stuff over to DS
  210. DWORD
  211. ServerUploadOptdefs( // upload opt defs info to DS
  212. IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
  213. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  214. IN LPWSTR ServerAddress // server ip address
  215. )
  216. {
  217. DWORD Err, i;
  218. LPDHCP_ALL_OPTIONS Options;
  219. Options = NULL;
  220. Err = DhcpGetAllOptions(ServerAddress,0, &Options);
  221. if( ERROR_NO_MORE_ITEMS == Err ) return ERROR_SUCCESS;
  222. if( ERROR_SUCCESS != Err ) return Err;
  223. if( Options->NonVendorOptions ) {
  224. for( i = 0; i < Options->NonVendorOptions->NumElements; i ++ ) {
  225. Err = DhcpCreateOptionV5DS(
  226. ServerAddress,
  227. 0,
  228. Options->NonVendorOptions->Options[i].OptionID,
  229. NULL /* no class */,
  230. NULL /* no vendor */,
  231. &Options->NonVendorOptions->Options[i]
  232. );
  233. if( ERROR_SUCCESS != Err ) break;
  234. }
  235. }
  236. if( ERROR_SUCCESS != Err ) {
  237. MemFree(Options);
  238. return Err;
  239. }
  240. for( i = 0; i < Options->NumVendorOptions; i ++ ) {
  241. Err = DhcpCreateOptionV5DS(
  242. ServerAddress,
  243. DHCP_FLAGS_OPTION_IS_VENDOR,
  244. Options->VendorOptions[i].Option.OptionID,
  245. Options->VendorOptions[i].ClassName,
  246. Options->VendorOptions[i].VendorName,
  247. &Options->VendorOptions[i].Option
  248. );
  249. if( ERROR_SUCCESS != Err ) break;
  250. }
  251. if( ERROR_SUCCESS != Err ) {
  252. MemFree(Options);
  253. return Err;
  254. }
  255. if( Options ) MemFree(Options);
  256. return Err;
  257. }
  258. //DOC UploadOptiosn does rpc calls to server and copies stuff over to DS
  259. UploadOptions( // upload options to DS
  260. IN LPWSTR ServerAddress,
  261. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo
  262. )
  263. {
  264. DWORD Err, Resume, PrefMax, i, nRead, nTotal;
  265. LPDHCP_ALL_OPTION_VALUES Options;
  266. Resume = 0; PrefMax = 0xFFFFFFFF; nRead = nTotal = 0;
  267. Options = NULL;
  268. Err = DhcpGetAllOptionValues( // get list of default opt values
  269. ServerAddress,
  270. 0,
  271. ScopeInfo,
  272. &Options
  273. );
  274. if( ERROR_NO_MORE_ITEMS == Err ) return ERROR_SUCCESS;
  275. if( ERROR_SUCCESS != Err ) return Err; // oops could not do this simple task?
  276. for( i = 0; i < Options->NumElements; i ++ ) {// now try to set each list of options..
  277. if( NULL == Options->Options[i].OptionsArray ) {
  278. continue; // uh? another way to say no options..
  279. }
  280. Err = DhcpSetOptionValuesV5DS (
  281. ServerAddress,
  282. Options->Options[i].IsVendor? DHCP_FLAGS_OPTION_IS_VENDOR:0,
  283. Options->Options[i].ClassName,
  284. Options->Options[i].VendorName,
  285. ScopeInfo,
  286. Options->Options[i].OptionsArray
  287. );
  288. if( ERROR_SUCCESS != Err ) {
  289. MemFree(Options);
  290. return Err;
  291. }
  292. }
  293. return ERROR_SUCCESS; // saved it
  294. }
  295. //DOC ServerUploadOptions does rpc calls to server and copies stuff over to DS
  296. DWORD
  297. ServerUploadOptions( // upload options info to DS
  298. IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
  299. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  300. IN LPWSTR ServerAddress // server ip address
  301. )
  302. {
  303. DWORD Err;
  304. DHCP_OPTION_SCOPE_INFO ScopeInfo;
  305. #if 0
  306. ScopeInfo.ScopeInfo.DefaultScopeInfo = NULL;
  307. ScopeInfo.ScopeType = DhcpDefaultOptions;
  308. Err = UploadOptions(ServerAddress, &ScopeInfo);
  309. if( ERROR_SUCCESS != Err ) return Err; // could not save default options..
  310. #endif
  311. ScopeInfo.ScopeType = DhcpGlobalOptions;
  312. ScopeInfo.ScopeInfo.GlobalScopeInfo = NULL;
  313. Err = UploadOptions(ServerAddress, &ScopeInfo);
  314. if( ERROR_SUCCESS != Err ) return Err; // could not save global options..
  315. return ERROR_SUCCESS;
  316. }
  317. //DOC ReservationUploadOptions does rpc calls to server and copies stuff to DS
  318. DWORD
  319. ReservationUploadOptions( // upload reservation options to DS
  320. IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
  321. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  322. IN LPWSTR ServerAddress, // server ip address
  323. IN DWORD SubnetAddress, // add of subnet to add
  324. IN DWORD ReserveAddress // address of reservation
  325. )
  326. {
  327. DHCP_OPTION_SCOPE_INFO ScopeInfo;
  328. ScopeInfo.ScopeType = DhcpReservedOptions;
  329. ScopeInfo.ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress = SubnetAddress;
  330. ScopeInfo.ScopeInfo.ReservedScopeInfo.ReservedIpAddress = ReserveAddress;
  331. return UploadOptions(ServerAddress, &ScopeInfo);
  332. }
  333. //DOC SubnetUploadOptions does rpc calls to server and copies stuff to DS
  334. DWORD
  335. SubnetUploadOptions( // upload subnet options to DS
  336. IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
  337. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  338. IN LPWSTR ServerAddress, // server ip address
  339. IN DWORD SubnetAddress // add of subnet to add
  340. )
  341. {
  342. DHCP_OPTION_SCOPE_INFO ScopeInfo;
  343. ScopeInfo.ScopeType = DhcpSubnetOptions;
  344. ScopeInfo.ScopeInfo.SubnetScopeInfo = SubnetAddress;
  345. return UploadOptions(ServerAddress, &ScopeInfo);
  346. }
  347. //DOC ServerUploadSubnet does rpc calls to server and copies stuff over to DS
  348. DWORD
  349. ServerUploadSubnet( // upload subnet and relevant info to DS
  350. IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
  351. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  352. IN LPWSTR ServerAddress, // server ip address
  353. IN DWORD SubnetAddress // add of subnet to add
  354. )
  355. {
  356. DWORD Err, Resume, PrefMax, i, nRead, nTotal;
  357. LPDHCP_SUBNET_INFO SubnetInfo;
  358. DHCP_SUBNET_ELEMENT_TYPE SubnetEltType;
  359. LPDHCP_SUBNET_ELEMENT_INFO_ARRAY_V4 EltInfo;
  360. LPDHCP_SUPER_SCOPE_TABLE SScopeTbl;
  361. Err = DhcpGetSubnetInfo(ServerAddress, SubnetAddress, &SubnetInfo);
  362. if( ERROR_SUCCESS != Err ) return Err; // could not get subnet info..
  363. Err = DhcpCreateSubnetDS(ServerAddress, SubnetAddress, SubnetInfo);
  364. if( SubnetInfo ) MemFree(SubnetInfo);
  365. if( ERROR_SUCCESS != Err ) return Err; // could not save onto DS
  366. SScopeTbl = NULL;
  367. Err = DhcpGetSuperScopeInfoV4( // get superscope table
  368. ServerAddress,
  369. &SScopeTbl
  370. );
  371. if( ERROR_SUCCESS == Err ) { // could get superscope table
  372. for( i = 0; i < SScopeTbl->cEntries ; i ++ ) {
  373. if( SScopeTbl->pEntries[i].SubnetAddress == SubnetAddress ) {
  374. Err = DhcpSetSuperScopeV4DS(
  375. ServerAddress,
  376. SubnetAddress,
  377. SScopeTbl->pEntries[i].SuperScopeName,
  378. TRUE /* change superscope if it exists..*/
  379. );
  380. break;
  381. }
  382. }
  383. MemFree(SScopeTbl);
  384. if( ERROR_SUCCESS != Err ) return Err; // could not set superscope..
  385. }
  386. Resume = 0; PrefMax = 0xFFFFFFFF;
  387. EltInfo = NULL; nRead = nTotal = 0;
  388. Err = DhcpEnumSubnetElementsV4( // enumerate ranges
  389. ServerAddress,
  390. SubnetAddress,
  391. DhcpIpRanges,
  392. &Resume,
  393. PrefMax,
  394. &EltInfo,
  395. &nRead,
  396. &nTotal
  397. );
  398. if( ERROR_SUCCESS != Err ) return Err; // could not get ranges
  399. for( i = 0; i < EltInfo->NumElements; i ++ ) {// try to add each range
  400. Err = DhcpAddSubnetElementV4DS(
  401. ServerAddress,
  402. SubnetAddress,
  403. &EltInfo->Elements[i]
  404. );
  405. if( ERROR_SUCCESS != Err ) break;
  406. }
  407. if( EltInfo ) MemFree(EltInfo); // free-up memory
  408. if( ERROR_SUCCESS != Err ) return Err; // could not add ranges
  409. Resume = 0; PrefMax = 0xFFFFFFFF;
  410. EltInfo = NULL;
  411. Err = DhcpEnumSubnetElementsV4( // enumerate reservations
  412. ServerAddress,
  413. SubnetAddress,
  414. DhcpReservedIps,
  415. &Resume,
  416. PrefMax,
  417. &EltInfo,
  418. &nRead,
  419. &nTotal
  420. );
  421. if( ERROR_NO_MORE_ITEMS == Err ) goto try_Excl;
  422. if( ERROR_SUCCESS != Err ) return Err; // could not get exclusions
  423. for( i = 0; i < EltInfo->NumElements; i ++ ) {// try to add each reservation
  424. Err = DhcpAddSubnetElementV4DS(
  425. ServerAddress,
  426. SubnetAddress,
  427. &EltInfo->Elements[i]
  428. );
  429. if( ERROR_SUCCESS != Err ) break; // could not add reseration in DS
  430. Err = ReservationUploadOptions(
  431. hDhcpC,
  432. hServer,
  433. ServerAddress,
  434. SubnetAddress,
  435. EltInfo->Elements[i].Element.ReservedIp->ReservedIpAddress
  436. );
  437. if( ERROR_SUCCESS != Err ) break; // could not add reservaation options
  438. }
  439. if( EltInfo ) MemFree(EltInfo); // free-up memory
  440. if( ERROR_SUCCESS != Err ) return Err; // could not add exclusions
  441. try_Excl:
  442. Resume = 0; PrefMax = 0xFFFFFFFF;
  443. EltInfo = NULL;
  444. Err = DhcpEnumSubnetElementsV4( // enumerate exclusions
  445. ServerAddress,
  446. SubnetAddress,
  447. DhcpReservedIps,
  448. &Resume,
  449. PrefMax,
  450. &EltInfo,
  451. &nRead,
  452. &nTotal
  453. );
  454. if( ERROR_NO_MORE_ITEMS == Err ) goto try_Options;
  455. if( ERROR_SUCCESS != Err ) return Err; // could not get exclusions
  456. for( i = 0; i < EltInfo->NumElements; i ++ ) {// try to add each exclusion
  457. Err = DhcpAddSubnetElementV4DS(
  458. ServerAddress,
  459. SubnetAddress,
  460. &EltInfo->Elements[i]
  461. );
  462. if( ERROR_SUCCESS != Err ) break;
  463. }
  464. if( EltInfo ) MemFree(EltInfo); // free-up memory
  465. if( ERROR_SUCCESS != Err ) return Err; // could not add exclusions
  466. try_Options:
  467. return SubnetUploadOptions(hDhcpC,hServer,ServerAddress,SubnetAddress);
  468. }
  469. //DOC ServerUploadSubnets does rpc calls to server and copies stuff over to DS
  470. DWORD
  471. ServerUploadSubnets( // upload subnets info to DS
  472. IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
  473. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  474. IN LPWSTR ServerAddress // server ip address
  475. )
  476. {
  477. DWORD Err, Resume, PrefMax, i, nRead, nTotal;
  478. LPDHCP_IP_ARRAY Subnets;
  479. Resume = 0; PrefMax = 0xFFFFFFFF; nRead = nTotal = 0;
  480. Subnets = NULL;
  481. Err = DhcpEnumSubnets(ServerAddress, &Resume, PrefMax, &Subnets, &nRead, &nTotal);
  482. if( ERROR_NO_MORE_ITEMS == Err ) return ERROR_SUCCESS;
  483. if( ERROR_SUCCESS != Err ) return Err; // could not get list of elements?
  484. for( i = 0; i < Subnets->NumElements ; i ++ ) {
  485. Err = ServerUploadSubnet(hDhcpC, hServer, ServerAddress, Subnets->Elements[i]);
  486. if( ERROR_SUCCESS != Err ) break;
  487. }
  488. if( Subnets ) MemFree(Subnets);
  489. return Err;
  490. }
  491. //DOC UploadServer downloads the server info by making RPC calls..
  492. DWORD
  493. UploadServer( // make rpc calls and pull up info to DS.
  494. IN OUT LPSTORE_HANDLE hDhcpC, // general container where info is stored
  495. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  496. IN LPWSTR ServerName, // name of server
  497. IN DWORD IpAddress // ip address of server
  498. )
  499. {
  500. DWORD Err;
  501. LPSTR IpAddrStr;
  502. WCHAR ServerAddress[sizeof("000.000.000.000")];
  503. IpAddress = htonl(IpAddress); // use n/w order ip address..
  504. IpAddrStr = inet_ntoa(*(struct in_addr *)&IpAddress);
  505. Err = mbstowcs(ServerAddress, IpAddrStr, ( sizeof(ServerAddress)/sizeof( WCHAR ) ) );
  506. if( -1 == Err ) { // could not convert to LPWSTR
  507. return ERROR_GEN_FAILURE;
  508. }
  509. Err = ServerUploadClasses(hDhcpC, hServer, ServerAddress);
  510. if( ERROR_SUCCESS != Err ) { // could not upload server classes info
  511. return Err;
  512. }
  513. Err = ServerUploadOptdefs(hDhcpC, hServer, ServerAddress);
  514. if( ERROR_SUCCESS != Err ) { // could not upload option defs ?
  515. return Err;
  516. }
  517. Err = ServerUploadOptions(hDhcpC, hServer, ServerAddress);
  518. if( ERROR_SUCCESS != Err ) { // could not upload options?
  519. return Err;
  520. }
  521. Err = ServerUploadSubnets(hDhcpC, hServer, ServerAddress);
  522. if( ERROR_SUCCESS != Err ) { // could not upload subnets?
  523. return Err;
  524. }
  525. return ERROR_SUCCESS;
  526. }
  527. //BeginExport(function)
  528. //DOC AddServer should add the new address to the server's attribs
  529. //DOC it should take this opportunity to reconcile the server.
  530. //DOC Currently it does nothing. (at the least it should probably try to
  531. //DOC check if the object exists, and if not create it.)
  532. //DOC
  533. DWORD
  534. AddServer( // add server and do misc work
  535. IN OUT LPSTORE_HANDLE hDhcpC, // container for server obj
  536. IN LPWSTR ServerName, // [DNS?] name of server
  537. IN LPWSTR ADsPath, // ADS path to server object
  538. IN DWORD IpAddress, // IpAddress to add to server
  539. IN DWORD State // state of server
  540. ) //EndExport(function)
  541. {
  542. DWORD Err, Err2;
  543. STORE_HANDLE hServer;
  544. Err = StoreGetHandle( // get the server obj..
  545. hDhcpC,
  546. DDS_RESERVED_DWORD,
  547. StoreGetChildType,
  548. ADsPath,
  549. &hServer
  550. );
  551. if( ERROR_SUCCESS != Err ) return Err; // could be because server obj elsewhere??
  552. if( !CFLAG_DONT_DO_DSWORK ) { // if DS stuff is enabled in the first place
  553. Err = UploadServer(hDhcpC, &hServer, ServerName, IpAddress);
  554. }
  555. StoreCleanupHandle(&hServer, 0); // cleanup this server..
  556. return Err;
  557. }
  558. //================================================================================
  559. // end of file
  560. //================================================================================