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.

3219 lines
112 KiB

  1. //================================================================================
  2. // Copyright (C) 1997 Microsoft Corporation
  3. // Author: RameshV
  4. // Description: Actual stubs that are the equivalent the rpcapi1.c and rpcapi2.c
  5. // in the server\server directory.. (or more accurately, the implementations are
  6. // the same as for the functions defined in server\client\dhcpsapi.def)
  7. // NOTE: THE FOLLOWING FUNCTIONS ARE NOT RPC, BUT THEY BEHAVE JUST THE SAME AS
  8. // THE DHCP RPC CALLS, EXCEPT THEY ACCESS THE DS DIRECTLY.
  9. //================================================================================
  10. #include <hdrmacro.h>
  11. #include <store.h>
  12. #include <dhcpmsg.h>
  13. #include <wchar.h>
  14. #include <dhcpbas.h>
  15. #include <mm\opt.h>
  16. #include <mm\optl.h>
  17. #include <mm\optdefl.h>
  18. #include <mm\optclass.h>
  19. #include <mm\classdefl.h>
  20. #include <mm\bitmask.h>
  21. #include <mm\reserve.h>
  22. #include <mm\range.h>
  23. #include <mm\subnet.h>
  24. #include <mm\sscope.h>
  25. #include <mm\oclassdl.h>
  26. #include <mm\server.h>
  27. #include <mm\address.h>
  28. #include <mm\server2.h>
  29. #include <mm\memfree.h>
  30. #include <mmreg\regutil.h>
  31. #include <mmreg\regread.h>
  32. #include <mmreg\regsave.h>
  33. #include <dhcpapi.h>
  34. #include <delete.h>
  35. #include <rpcapi1.h>
  36. #include <st_srvr.h>
  37. #include <rpcapi2.h>
  38. //================================================================================
  39. // global variables..
  40. //================================================================================
  41. BOOL
  42. StubInitialized = FALSE;
  43. STORE_HANDLE hDhcpC, hDhcpRoot;
  44. CRITICAL_SECTION DhcpDsDllCriticalSection;
  45. //================================================================================
  46. // THE FOLLOWING FUNCTIONS HAVE BEEN COPIED OVER FROM RPCAPI1.C (IN THE
  47. // DHCP\SERVER\SERVER DIRECTORY).
  48. //================================================================================
  49. #undef DhcpPrint
  50. #define DhcpPrint(X)
  51. #define DhcpAssert(X)
  52. typedef struct _OPTION_BIN {
  53. DWORD DataSize;
  54. DHCP_OPTION_DATA_TYPE OptionType;
  55. DWORD NumElements;
  56. BYTE Data[0];
  57. } OPTION_BIN, *LPOPTION_BIN;
  58. #define IS_SPACE_AVAILABLE(FilledSize, AvailableSize, RequiredSpace ) ((FilledSize) + (RequiredSpace) <= (AvailableSize) )
  59. BOOL _inline
  60. CheckForVendor(
  61. IN DWORD OptId,
  62. IN BOOL IsVendor
  63. )
  64. {
  65. if( IsVendor ) return (256 <= OptId);
  66. return 256 > OptId;
  67. }
  68. DWORD _inline
  69. ConvertOptIdToRPCValue(
  70. IN DWORD OptId,
  71. IN BOOL IsVendorUnused
  72. )
  73. {
  74. return OptId % 256;
  75. }
  76. DWORD _inline
  77. ConvertOptIdToMemValue(
  78. IN DWORD OptId,
  79. IN BOOL IsVendor
  80. )
  81. {
  82. if( IsVendor ) return OptId + 256;
  83. return OptId;
  84. }
  85. extern // defined in rpcapi1.c
  86. DWORD
  87. DhcpConvertOptionRPCToRegFormat(
  88. IN LPDHCP_OPTION_DATA Option,
  89. IN OUT LPBYTE RegBuffer, // OPTIONAL
  90. IN OUT DWORD *BufferSize // input: buffer size, output: filled buffer size
  91. );
  92. DWORD
  93. ConvertOptionInfoRPCToMemFormat(
  94. IN LPDHCP_OPTION OptionInfo,
  95. OUT LPWSTR *Name,
  96. OUT LPWSTR *Comment,
  97. OUT DWORD *OptId,
  98. OUT LPBYTE *Value,
  99. OUT DWORD *ValueSize
  100. )
  101. {
  102. DWORD Error;
  103. if( Name ) *Name = OptionInfo->OptionName;
  104. if( Comment ) *Comment = OptionInfo->OptionComment;
  105. if( OptId ) *OptId = (DWORD)(OptionInfo->OptionID);
  106. if( Value ) {
  107. *Value = NULL;
  108. if( !ValueSize ) return ERROR_INVALID_PARAMETER;
  109. *ValueSize = 0;
  110. Error = DhcpConvertOptionRPCToRegFormat(
  111. &OptionInfo->DefaultValue,
  112. NULL,
  113. ValueSize
  114. );
  115. if( ERROR_MORE_DATA != Error ) return Error;
  116. DhcpAssert(0 != *ValueSize);
  117. *Value = MemAlloc(*ValueSize);
  118. if( NULL == *Value ) {
  119. *ValueSize = 0;
  120. return ERROR_NOT_ENOUGH_MEMORY;
  121. }
  122. Error = DhcpConvertOptionRPCToRegFormat(
  123. &OptionInfo->DefaultValue,
  124. *Value,
  125. ValueSize
  126. );
  127. DhcpAssert(ERROR_MORE_DATA != Error);
  128. DhcpAssert(ERROR_SUCCESS == Error);
  129. if( ERROR_SUCCESS != Error ) {
  130. MemFree(*Value);
  131. *Value = NULL;
  132. *ValueSize = 0;
  133. return Error;
  134. }
  135. }
  136. return ERROR_SUCCESS;
  137. }
  138. //================================================================================
  139. // helper routines
  140. //================================================================================
  141. VOID
  142. MemFreeFunc( // free memory
  143. IN OUT LPVOID Mem
  144. )
  145. {
  146. MemFree(Mem);
  147. }
  148. //
  149. // ErrorNotInitialized used to be ZERO.. but why would we NOT return an error?
  150. // so changed it to return errors..
  151. //
  152. #define ErrorNotInitialized Err
  153. #define STUB_NOT_INITIALIZED(Err) ( !StubInitialized && ((Err) = StubInitialize()))
  154. //DOC StubInitialize initializes all the modules involved in the dhcp ds dll.
  155. //DOC It also sets a global variable StubInitialized to TRUE to indicate that
  156. //DOC initialization went fine. This should be called as part of DllInit so that
  157. //DOC everything can be done at this point..
  158. DWORD
  159. StubInitialize( // initialize all global vars
  160. VOID
  161. )
  162. {
  163. DWORD Err,Err2;
  164. STORE_HANDLE ConfigC;
  165. if( StubInitialized ) return ERROR_SUCCESS; // already initialized
  166. Err = Err2 = ERROR_SUCCESS;
  167. EnterCriticalSection( &DhcpDsDllCriticalSection );
  168. do {
  169. if( StubInitialized ) break;
  170. Err = StoreInitHandle(
  171. /* hStore */ &ConfigC,
  172. /* Reserved */ DDS_RESERVED_DWORD,
  173. /* ThisDomain */ NULL, // current domain
  174. /* UserName */ NULL, // current user
  175. /* Password */ NULL, // current credentials
  176. /* AuthFlags */ ADS_SECURE_AUTHENTICATION
  177. );
  178. if( ERROR_SUCCESS != Err ) {
  179. Err = ERROR_DDS_NO_DS_AVAILABLE; // could not get config hdl
  180. break;
  181. }
  182. Err = DhcpDsGetDhcpC(
  183. DDS_RESERVED_DWORD, &ConfigC, &hDhcpC
  184. );
  185. if( ERROR_SUCCESS == Err ) {
  186. Err2 = DhcpDsGetRoot( // now try to get root handle
  187. DDS_FLAGS_CREATE, &ConfigC, &hDhcpRoot
  188. );
  189. }
  190. StoreCleanupHandle(&ConfigC, DDS_RESERVED_DWORD);
  191. } while (0);
  192. if( ERROR_SUCCESS != Err2 ) { // could not get dhcp root hdl
  193. DhcpAssert(ERROR_SUCCESS == Err);
  194. StoreCleanupHandle(&hDhcpC, DDS_RESERVED_DWORD);
  195. Err = Err2;
  196. }
  197. StubInitialized = (ERROR_SUCCESS == Err );
  198. LeaveCriticalSection( &DhcpDsDllCriticalSection );
  199. return Err;
  200. }
  201. //DOC StubCleanup de-initializes all the modules involved in the dhcp ds dll.
  202. //DOC its effect is to undo everything done by StubInitialize
  203. VOID
  204. StubCleanup( // undo StubInitialize
  205. VOID
  206. )
  207. {
  208. if( ! StubInitialized ) return; // never initialized anyways
  209. EnterCriticalSection(&DhcpDsDllCriticalSection);
  210. if( StubInitialized ) {
  211. StoreCleanupHandle(&hDhcpC, DDS_RESERVED_DWORD);
  212. StoreCleanupHandle(&hDhcpRoot, DDS_RESERVED_DWORD);
  213. StubInitialized = FALSE;
  214. }
  215. LeaveCriticalSection(&DhcpDsDllCriticalSection);
  216. }
  217. //DOC DhcpDsLock is not yet implemented
  218. DWORD
  219. DhcpDsLock( // lock the ds
  220. IN OUT LPSTORE_HANDLE hDhcpRoot // dhcp root object to lock via
  221. )
  222. {
  223. EnterCriticalSection(&DhcpDsDllCriticalSection);
  224. return ERROR_SUCCESS;
  225. }
  226. //DOC DhcpDsUnlock not yet implemented
  227. VOID
  228. DhcpDsUnlock(
  229. IN OUT LPSTORE_HANDLE hDhcpRoot // dhcp root object..
  230. )
  231. {
  232. LeaveCriticalSection(&DhcpDsDllCriticalSection);
  233. }
  234. //DOC GetServerNameFromAddr gets the server name given ip address
  235. DWORD
  236. GetServerNameFromAddr( // get server name from ip addr
  237. IN DWORD IpAddress, // look for server w/ this addr
  238. OUT LPWSTR *ServerName // fill this with matching name
  239. )
  240. {
  241. DWORD Err, Err2;
  242. ARRAY Servers;
  243. ARRAY_LOCATION Loc;
  244. PEATTRIB ThisAttrib;
  245. LPWSTR ThisStr, AllocStr;
  246. MemArrayInit(&Servers);
  247. Err = DhcpDsGetLists // get list of servers
  248. (
  249. /* Reserved */ DDS_RESERVED_DWORD,
  250. /* hStore */ &hDhcpRoot,
  251. /* RecursionDepth */ 0xFFFFFFFF,
  252. /* Servers */ &Servers, // array of PEATTRIB 's
  253. /* Subnets */ NULL,
  254. /* IpAddress */ NULL,
  255. /* Mask */ NULL,
  256. /* Ranges */ NULL,
  257. /* Sites */ NULL,
  258. /* Reservations */ NULL,
  259. /* SuperScopes */ NULL,
  260. /* OptionDescription */ NULL,
  261. /* OptionsLocation */ NULL,
  262. /* Options */ NULL,
  263. /* Classes */ NULL
  264. );
  265. if( ERROR_SUCCESS != Err ) return Err;
  266. ThisStr = NULL;
  267. for( // find name for ip-address
  268. Err = MemArrayInitLoc(&Servers,&Loc)
  269. ; ERROR_FILE_NOT_FOUND != Err ;
  270. Err = MemArrayNextLoc(&Servers, &Loc)
  271. ) {
  272. //= require ERROR_SUCCESS == Err
  273. Err = MemArrayGetElement(&Servers, &Loc, &ThisAttrib);
  274. //= require ERROR_SUCCESS == Err && NULL != ThisAttrib
  275. if( !IS_STRING1_PRESENT(ThisAttrib) || // no name for this server
  276. !IS_ADDRESS1_PRESENT(ThisAttrib) ) { // no address for this server
  277. continue; //= ds inconsistent
  278. }
  279. ThisStr = ThisAttrib->String1;
  280. break;
  281. }
  282. AllocStr = NULL;
  283. if( NULL == ThisStr ) { // didnt find server name
  284. Err = ERROR_FILE_NOT_FOUND;
  285. } else { // found the server name
  286. AllocStr = MemAlloc(sizeof(WCHAR)*(1+wcslen(ThisStr)));
  287. if( NULL == AllocStr ) { // couldnt alloc mem?
  288. Err = ERROR_NOT_ENOUGH_MEMORY;
  289. } else { // now just copy the str over
  290. wcscpy(AllocStr, ThisStr);
  291. Err = ERROR_SUCCESS;
  292. }
  293. }
  294. MemArrayFree(&Servers, MemFreeFunc);
  295. *ServerName = AllocStr;
  296. return Err;
  297. }
  298. //DOC GetServerNameFromStr gets the server name given ip address string
  299. DWORD
  300. GetServerNameFromStr( // get srvr name from ip string
  301. IN LPWSTR Str, // ip address string
  302. OUT LPWSTR *ServerName // output the server name
  303. )
  304. {
  305. DWORD Err, Err2;
  306. DWORD IpAddress;
  307. CHAR IpAddressBuf[sizeof("000.000.000.000")];
  308. Err = wcstombs(IpAddressBuf, Str, sizeof(IpAddressBuf));
  309. if( -1 == Err ) { // could not convert address
  310. return ERROR_INVALID_DATA;
  311. }
  312. IpAddress = ntohl(inet_addr(IpAddressBuf)); // convert to DWORD Address, host order
  313. return GetServerNameFromAddr(IpAddress, ServerName);
  314. }
  315. //DOC TouchServer writes the "instancetype" attrib w/ default value so that the time
  316. //DOC stamp on the server object is brought up to date..
  317. DWORD
  318. TouchServer( // touch server object
  319. IN LPSTORE_HANDLE hServer
  320. )
  321. {
  322. DWORD nAttribs = 1;
  323. return StoreSetAttributesVA(
  324. hServer,0, &nAttribs,
  325. ADSTYPE_INTEGER, ADS_ATTR_UPDATE, ATTRIB_INSTANCE_TYPE, DEFAULT_INSTANCE_TYPE_ATTRIB_VALUE,
  326. ADSTYPE_INVALID
  327. );
  328. }
  329. //DOC GetServer translates the server ip address to a server object in DS.
  330. DWORD
  331. GetServer( // get a server object frm ip-addr
  332. OUT LPSTORE_HANDLE hServer, // fill up this object
  333. IN LPWSTR Address // server ip address
  334. )
  335. {
  336. DWORD Err, Err2;
  337. DWORD IpAddress;
  338. CHAR IpAddressBuf[sizeof("000.000.000.000")];
  339. ARRAY Servers;
  340. ARRAY_LOCATION Loc;
  341. PEATTRIB ThisAttrib;
  342. LPWSTR ServerLocation, ServerName;
  343. DWORD ServerGetType;
  344. if( NULL == Address ) { // if DhcpRoot object requested
  345. return DhcpDsGetRoot( 0, &hDhcpC, hServer );
  346. }
  347. Err = wcstombs(IpAddressBuf, Address, sizeof(IpAddressBuf));
  348. if( -1 == Err ) { // could not convert address
  349. return ERROR_INVALID_DATA;
  350. }
  351. IpAddress = ntohl(inet_addr(IpAddressBuf)); // convert to DWORD Address, host order
  352. MemArrayInit(&Servers);
  353. Err = DhcpDsGetLists // get list of servers
  354. (
  355. /* Reserved */ DDS_RESERVED_DWORD,
  356. /* hStore */ &hDhcpRoot,
  357. /* RecursionDepth */ 0xFFFFFFFF,
  358. /* Servers */ &Servers, // array of PEATTRIB 's
  359. /* Subnets */ NULL,
  360. /* IpAddress */ NULL,
  361. /* Mask */ NULL,
  362. /* Ranges */ NULL,
  363. /* Sites */ NULL,
  364. /* Reservations */ NULL,
  365. /* SuperScopes */ NULL,
  366. /* OptionDescription */ NULL,
  367. /* OptionsLocation */ NULL,
  368. /* Options */ NULL,
  369. /* Classes */ NULL
  370. );
  371. if( ERROR_SUCCESS != Err ) return Err;
  372. ServerLocation = ServerName = NULL; // havent found server yet
  373. for( // find name for ip-address
  374. Err = MemArrayInitLoc(&Servers,&Loc)
  375. ; ERROR_FILE_NOT_FOUND != Err ;
  376. Err = MemArrayNextLoc(&Servers, &Loc)
  377. ) {
  378. //= require ERROR_SUCCESS == Err
  379. Err = MemArrayGetElement(&Servers, &Loc, &ThisAttrib);
  380. //= require ERROR_SUCCESS == Err && NULL != ThisAttrib
  381. if( !IS_STRING1_PRESENT(ThisAttrib) || // no name for this server
  382. !IS_ADDRESS1_PRESENT(ThisAttrib) ) { // no address for this server
  383. continue; //= ds inconsistent
  384. }
  385. if( ThisAttrib->Address1 == IpAddress ) { // matching address?
  386. if( IS_ADSPATH_PRESENT(ThisAttrib) ) {// found location
  387. ServerLocation = ThisAttrib->ADsPath;
  388. ServerGetType = ThisAttrib->StoreGetType;
  389. ServerName = NULL;
  390. break;
  391. } else { // location not found
  392. ServerName = ThisAttrib->String1; // remember server name
  393. }
  394. }
  395. }
  396. if( NULL == ServerLocation ) { // did not find location
  397. if( NULL == ServerName ) { // did not find server name either
  398. MemArrayFree(&Servers, MemFreeFunc);
  399. return ERROR_DDS_DHCP_SERVER_NOT_FOUND;
  400. }
  401. ServerName = MakeColumnName(ServerName); // make this into a "CN=X" types
  402. if( NULL == ServerName ) { // could not allocate mme
  403. MemArrayFree(&Servers, MemFreeFunc);
  404. return ERROR_NOT_ENOUGH_MEMORY;
  405. }
  406. ServerGetType = StoreGetChildType; // search in hDhcpC container
  407. ServerLocation = ServerName;
  408. }
  409. Err = StoreGetHandle // now try to open server object
  410. (
  411. /* hStore */ &hDhcpC,
  412. /* Reserved */ DDS_RESERVED_DWORD,
  413. /* StoreGetType */ ServerGetType,
  414. /* Path */ ServerLocation,
  415. /* hStoreOut */ hServer
  416. );
  417. MemArrayFree(&Servers, MemFreeFunc);
  418. if( ServerName ) MemFree(ServerName);
  419. if( ERROR_SUCCESS == Err ) { // update the last changed time on server
  420. TouchServer(hServer);
  421. }
  422. return Err;
  423. }
  424. //DOC GetSubnet translates an ip-address to a subnet object.
  425. //DOC : if the subnet attrib does not have an ADsPath this does not guess..
  426. DWORD
  427. GetSubnet(
  428. IN OUT LPSTORE_HANDLE hServer, // server object
  429. OUT LPSTORE_HANDLE hSubnet, // fill this subnet object
  430. IN DWORD IpAddress
  431. )
  432. {
  433. DWORD Err, Err2;
  434. ARRAY Subnets;
  435. ARRAY_LOCATION Loc;
  436. PEATTRIB ThisAttrib;
  437. LPWSTR SubnetLocation;
  438. DWORD SubnetGetType;
  439. MemArrayInit(&Subnets);
  440. Err = DhcpDsGetLists // get list of subnets
  441. (
  442. /* Reserved */ DDS_RESERVED_DWORD,
  443. /* hStore */ hServer,
  444. /* RecursionDepth */ 0xFFFFFFFF,
  445. /* Servers */ NULL,
  446. /* Subnets */ &Subnets, // array of PEATTRIB 's
  447. /* IpAddress */ NULL,
  448. /* Mask */ NULL,
  449. /* Ranges */ NULL,
  450. /* Sites */ NULL,
  451. /* Reservations */ NULL,
  452. /* SuperScopes */ NULL,
  453. /* OptionDescription */ NULL,
  454. /* OptionsLocation */ NULL,
  455. /* Options */ NULL,
  456. /* Classes */ NULL
  457. );
  458. if( ERROR_SUCCESS != Err ) return Err;
  459. SubnetLocation = NULL;
  460. for( // find match for ip-address
  461. Err = MemArrayInitLoc(&Subnets,&Loc)
  462. ; ERROR_FILE_NOT_FOUND != Err ;
  463. Err = MemArrayNextLoc(&Subnets, &Loc)
  464. ) {
  465. //= require ERROR_SUCCESS == Err
  466. Err = MemArrayGetElement(&Subnets, &Loc, &ThisAttrib);
  467. //= require ERROR_SUCCESS == Err && NULL != ThisAttrib
  468. if( !IS_ADDRESS1_PRESENT(ThisAttrib) || // no address for this subnet
  469. !IS_ADDRESS2_PRESENT(ThisAttrib) ) { // no mask for this subnet
  470. continue; //= ds inconsistent
  471. }
  472. if( ThisAttrib->Address1 == IpAddress ) { // matching address?
  473. if( IS_ADSPATH_PRESENT(ThisAttrib) ) {// found location
  474. SubnetLocation = ThisAttrib->ADsPath;
  475. SubnetGetType = ThisAttrib->StoreGetType;
  476. break;
  477. } else { // oops.. need to hdl this!
  478. MemArrayFree(&Subnets, MemFreeFunc);
  479. return ERROR_DDS_UNEXPECTED_ERROR;
  480. }
  481. }
  482. }
  483. if( NULL == SubnetLocation ) { // did not find location
  484. MemArrayFree(&Subnets, MemFreeFunc);
  485. return ERROR_DDS_SUBNET_NOT_PRESENT;
  486. }
  487. Err = StoreGetHandle // now try to open server object
  488. (
  489. /* hStore */ &hDhcpC,
  490. /* Reserved */ DDS_RESERVED_DWORD,
  491. /* StoreGetType */ SubnetGetType,
  492. /* Path */ SubnetLocation,
  493. /* hStoreOut */ hSubnet
  494. );
  495. MemArrayFree(&Subnets, MemFreeFunc);
  496. return Err;
  497. }
  498. //DOC GetReservationInternal translates an ip-address to a reservation object.
  499. //DOC : if the Reservation attrib does not have an ADsPath this does not guess..
  500. DWORD
  501. GetReservationInternal(
  502. IN OUT LPSTORE_HANDLE hServer, // server object
  503. IN OUT LPSTORE_HANDLE hSubnet, // subnet object
  504. IN OUT LPSTORE_HANDLE hReservation, // fill this with reservation object
  505. IN DWORD IpAddress // reserved ip address to search for
  506. )
  507. {
  508. DWORD Err, Err2;
  509. ARRAY Res;
  510. ARRAY_LOCATION Loc;
  511. PEATTRIB ThisAttrib;
  512. LPWSTR ResLocation;
  513. DWORD ResGetType;
  514. MemArrayInit(&Res);
  515. Err = DhcpDsGetLists // get list of subnets
  516. (
  517. /* Reserved */ DDS_RESERVED_DWORD,
  518. /* hStore */ hSubnet,
  519. /* RecursionDepth */ 0xFFFFFFFF,
  520. /* Servers */ NULL,
  521. /* Subnets */ NULL,
  522. /* IpAddress */ NULL,
  523. /* Mask */ NULL,
  524. /* Ranges */ NULL,
  525. /* Sites */ NULL,
  526. /* Reservations */ &Res,
  527. /* SuperScopes */ NULL,
  528. /* OptionDescription */ NULL,
  529. /* OptionsLocation */ NULL,
  530. /* Options */ NULL,
  531. /* Classes */ NULL
  532. );
  533. if( ERROR_SUCCESS != Err ) return Err;
  534. ResLocation = NULL;
  535. for( // find match for ip-address
  536. Err = MemArrayInitLoc(&Res,&Loc)
  537. ; ERROR_FILE_NOT_FOUND != Err ;
  538. Err = MemArrayNextLoc(&Res, &Loc)
  539. ) {
  540. //= require ERROR_SUCCESS == Err
  541. Err = MemArrayGetElement(&Res, &Loc, &ThisAttrib);
  542. //= require ERROR_SUCCESS == Err && NULL != ThisAttrib
  543. if( !IS_ADDRESS1_PRESENT(ThisAttrib) || // no address for this reservation
  544. !IS_BINARY1_PRESENT(ThisAttrib) ) { // no client uid for this res.
  545. continue; //= ds inconsistent
  546. }
  547. if( ThisAttrib->Address1 == IpAddress ) { // matching address?
  548. if( IS_ADSPATH_PRESENT(ThisAttrib) ) {// found location
  549. ResLocation = ThisAttrib->ADsPath;
  550. ResGetType = ThisAttrib->StoreGetType;
  551. break;
  552. } else { // oops.. need to hdl this!
  553. MemArrayFree(&Res, MemFreeFunc);
  554. return ERROR_DDS_UNEXPECTED_ERROR;
  555. }
  556. }
  557. }
  558. if( NULL == ResLocation ) { // did not find location
  559. MemArrayFree(&Res, MemFreeFunc);
  560. return ERROR_DDS_RESERVATION_NOT_PRESENT;
  561. }
  562. Err = StoreGetHandle // now try to open server object
  563. (
  564. /* hStore */ &hDhcpC,
  565. /* Reserved */ DDS_RESERVED_DWORD,
  566. /* StoreGetType */ ResGetType,
  567. /* Path */ ResLocation,
  568. /* hStoreOut */ hReservation
  569. );
  570. MemArrayFree(&Res, MemFreeFunc);
  571. return Err;
  572. }
  573. //DOC GetReservation translates an ip-address to a subnet object.
  574. //DOC : if the Reservation attrib does not have an ADsPath this does not guess..
  575. DWORD
  576. GetReservation(
  577. IN OUT LPSTORE_HANDLE hServer, // server object
  578. IN OUT LPSTORE_HANDLE hReservation, // fill this with reservation object
  579. IN DWORD SubnetAddr, // address of subnet
  580. IN DWORD IpAddress
  581. )
  582. {
  583. DWORD Err, Err2;
  584. STORE_HANDLE hSubnet;
  585. Err = GetSubnet(hServer, &hSubnet, SubnetAddr);
  586. if( ERROR_SUCCESS != Err) return Err; // try to get the subnet obj first
  587. Err = GetReservationInternal(hServer, &hSubnet, hReservation, IpAddress);
  588. StoreCleanupHandle(&hSubnet, 0);
  589. return Err;
  590. }
  591. //DOC AddSubnetElementOld adds one of Excl,Ip Range or Reservation to the subnet
  592. //DOC object specified in the DS.
  593. DWORD
  594. AddSubnetElementOld( // add excl/range/res. to subnet
  595. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  596. IN OUT LPSTORE_HANDLE hSubnet, // subnet obj in DS
  597. IN LPWSTR ServerName, // name of dhcp server
  598. IN LPDHCP_SUBNET_ELEMENT_DATA Elt // the element to add
  599. )
  600. {
  601. DWORD Err;
  602. if( DhcpIpRanges == Elt->ElementType ) { // add a new range
  603. Err = DhcpDsSubnetAddRangeOrExcl // add its
  604. (
  605. /* hDhcpC */ &hDhcpC,
  606. /* hServer */ hServer,
  607. /* hSubnet */ hSubnet,
  608. /* Reserved */ DDS_RESERVED_DWORD,
  609. /* ServerName */ ServerName,
  610. /* Start */ Elt->Element.IpRange->StartAddress,
  611. /* End */ Elt->Element.IpRange->EndAddress,
  612. /* RangeOrExcl */ TRUE // range
  613. );
  614. } else if( DhcpExcludedIpRanges == Elt->ElementType ) {
  615. Err = DhcpDsSubnetAddRangeOrExcl // add its
  616. (
  617. /* hDhcpC */ &hDhcpC,
  618. /* hServer */ hServer,
  619. /* hSubnet */ hSubnet,
  620. /* Reserved */ DDS_RESERVED_DWORD,
  621. /* ServerName */ ServerName,
  622. /* Start */ Elt->Element.ExcludeIpRange->StartAddress,
  623. /* End */ Elt->Element.ExcludeIpRange->EndAddress,
  624. /* RangeOrExcl */ FALSE // excl
  625. );
  626. } else if( DhcpReservedIps == Elt->ElementType ) {
  627. Err = DhcpDsSubnetAddReservation // add its
  628. (
  629. /* hDhcpC */ &hDhcpC,
  630. /* hServer */ hServer,
  631. /* hSubnet */ hSubnet,
  632. /* Reserved */ DDS_RESERVED_DWORD,
  633. /* ServerName */ ServerName,
  634. /* ReservedAddddr */ Elt->Element.ReservedIp->ReservedIpAddress,
  635. /* HwAddr */ Elt->Element.ReservedIp->ReservedForClient->Data,
  636. /* HwAddrLen */ Elt->Element.ReservedIp->ReservedForClient->DataLength,
  637. /* ClientType */ CLIENT_TYPE_DHCP
  638. );
  639. } else {
  640. Err = ERROR_CALL_NOT_IMPLEMENTED;
  641. }
  642. return Err;
  643. }
  644. //DOC AddSubnetElement adds one of Excl,Ip Range or Reservation to the subnet
  645. //DOC object specified in the DS.
  646. DWORD
  647. AddSubnetElement( // add excl/range/res. to subnet
  648. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  649. IN OUT LPSTORE_HANDLE hSubnet, // subnet obj in DS
  650. IN LPWSTR ServerName, // name of dhcp server
  651. IN LPDHCP_SUBNET_ELEMENT_DATA_V4 Elt // the element to add
  652. )
  653. {
  654. DWORD Err;
  655. if( DhcpIpRanges == Elt->ElementType ) { // add a new range
  656. Err = DhcpDsSubnetAddRangeOrExcl // add its
  657. (
  658. /* hDhcpC */ &hDhcpC,
  659. /* hServer */ hServer,
  660. /* hSubnet */ hSubnet,
  661. /* Reserved */ DDS_RESERVED_DWORD,
  662. /* ServerName */ ServerName,
  663. /* Start */ Elt->Element.IpRange->StartAddress,
  664. /* End */ Elt->Element.IpRange->EndAddress,
  665. /* RangeOrExcl */ TRUE // range
  666. );
  667. } else if( DhcpExcludedIpRanges == Elt->ElementType ) {
  668. Err = DhcpDsSubnetAddRangeOrExcl // add its
  669. (
  670. /* hDhcpC */ &hDhcpC,
  671. /* hServer */ hServer,
  672. /* hSubnet */ hSubnet,
  673. /* Reserved */ DDS_RESERVED_DWORD,
  674. /* ServerName */ ServerName,
  675. /* Start */ Elt->Element.ExcludeIpRange->StartAddress,
  676. /* End */ Elt->Element.ExcludeIpRange->EndAddress,
  677. /* RangeOrExcl */ FALSE // excl
  678. );
  679. } else if( DhcpReservedIps == Elt->ElementType ) {
  680. Err = DhcpDsSubnetAddReservation // add its
  681. (
  682. /* hDhcpC */ &hDhcpC,
  683. /* hServer */ hServer,
  684. /* hSubnet */ hSubnet,
  685. /* Reserved */ DDS_RESERVED_DWORD,
  686. /* ServerName */ ServerName,
  687. /* ReservedAddddr */ Elt->Element.ReservedIp->ReservedIpAddress,
  688. /* HwAddr */ Elt->Element.ReservedIp->ReservedForClient->Data,
  689. /* HwAddrLen */ Elt->Element.ReservedIp->ReservedForClient->DataLength,
  690. /* ClientType */ Elt->Element.ReservedIp->bAllowedClientTypes
  691. );
  692. } else {
  693. Err = ERROR_CALL_NOT_IMPLEMENTED;
  694. }
  695. return Err;
  696. }
  697. //DOC DelSubnetElementOld deltes one of Excl,Ip Range or Reservation to frm subnet
  698. //DOC object specified in the DS.
  699. DWORD
  700. DelSubnetElementOld( // del excl/range/res. frm subnet
  701. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  702. IN OUT LPSTORE_HANDLE hSubnet, // subnet obj in DS
  703. IN LPWSTR ServerName, // name of dhcp server
  704. IN LPDHCP_SUBNET_ELEMENT_DATA Elt // the element to add
  705. )
  706. {
  707. DWORD Err;
  708. if( DhcpIpRanges == Elt->ElementType ) { // del a new range
  709. Err = DhcpDsSubnetDelRangeOrExcl // del its
  710. (
  711. /* hDhcpC */ &hDhcpC,
  712. /* hServer */ hServer,
  713. /* hSubnet */ hSubnet,
  714. /* Reserved */ DDS_RESERVED_DWORD,
  715. /* ServerName */ ServerName,
  716. /* Start */ Elt->Element.IpRange->StartAddress,
  717. /* End */ Elt->Element.IpRange->EndAddress,
  718. /* RangeOrExcl */ TRUE // range
  719. );
  720. } else if( DhcpExcludedIpRanges == Elt->ElementType ) {
  721. Err = DhcpDsSubnetDelRangeOrExcl // del its
  722. (
  723. /* hDhcpC */ &hDhcpC,
  724. /* hServer */ hServer,
  725. /* hSubnet */ hSubnet,
  726. /* Reserved */ DDS_RESERVED_DWORD,
  727. /* ServerName */ ServerName,
  728. /* Start */ Elt->Element.ExcludeIpRange->StartAddress,
  729. /* End */ Elt->Element.ExcludeIpRange->EndAddress,
  730. /* RangeOrExcl */ FALSE // excl
  731. );
  732. } else if( DhcpReservedIps == Elt->ElementType ) {
  733. Err = DhcpDsSubnetDelReservation // del its
  734. (
  735. /* hDhcpC */ &hDhcpC,
  736. /* hServer */ hServer,
  737. /* hSubnet */ hSubnet,
  738. /* Reserved */ DDS_RESERVED_DWORD,
  739. /* ServerName */ ServerName,
  740. /* ReservedAddddr */ Elt->Element.ReservedIp->ReservedIpAddress
  741. );
  742. } else {
  743. Err = ERROR_CALL_NOT_IMPLEMENTED;
  744. }
  745. return Err;
  746. }
  747. //DOC DelSubnetElement deltes one of Excl,Ip Range or Reservation to frm subnet
  748. //DOC object specified in the DS.
  749. DWORD
  750. DelSubnetElement( // del excl/range/res. frm subnet
  751. IN OUT LPSTORE_HANDLE hServer, // server obj in DS
  752. IN OUT LPSTORE_HANDLE hSubnet, // subnet obj in DS
  753. IN LPWSTR ServerName, // name of dhcp server
  754. IN LPDHCP_SUBNET_ELEMENT_DATA_V4 Elt // the element to add
  755. )
  756. {
  757. DWORD Err;
  758. if( DhcpIpRanges == Elt->ElementType ) { // del a new range
  759. Err = DhcpDsSubnetDelRangeOrExcl // del its
  760. (
  761. /* hDhcpC */ &hDhcpC,
  762. /* hServer */ hServer,
  763. /* hSubnet */ hSubnet,
  764. /* Reserved */ DDS_RESERVED_DWORD,
  765. /* ServerName */ ServerName,
  766. /* Start */ Elt->Element.IpRange->StartAddress,
  767. /* End */ Elt->Element.IpRange->EndAddress,
  768. /* RangeOrExcl */ TRUE // range
  769. );
  770. } else if( DhcpExcludedIpRanges == Elt->ElementType ) {
  771. Err = DhcpDsSubnetDelRangeOrExcl // del its
  772. (
  773. /* hDhcpC */ &hDhcpC,
  774. /* hServer */ hServer,
  775. /* hSubnet */ hSubnet,
  776. /* Reserved */ DDS_RESERVED_DWORD,
  777. /* ServerName */ ServerName,
  778. /* Start */ Elt->Element.ExcludeIpRange->StartAddress,
  779. /* End */ Elt->Element.ExcludeIpRange->EndAddress,
  780. /* RangeOrExcl */ FALSE // excl
  781. );
  782. } else if( DhcpReservedIps == Elt->ElementType ) {
  783. Err = DhcpDsSubnetDelReservation // del its
  784. (
  785. /* hDhcpC */ &hDhcpC,
  786. /* hServer */ hServer,
  787. /* hSubnet */ hSubnet,
  788. /* Reserved */ DDS_RESERVED_DWORD,
  789. /* ServerName */ ServerName,
  790. /* ReservedAddddr */ Elt->Element.ReservedIp->ReservedIpAddress
  791. );
  792. } else {
  793. Err = ERROR_CALL_NOT_IMPLEMENTED;
  794. }
  795. return Err;
  796. }
  797. //================================================================================
  798. // the following functions are NOT based on RPC, but actually direct calls to
  799. // the DS. But, they have the same interface as the RPC stubs in dhcpsapi.dll.
  800. //================================================================================
  801. //================================================================================
  802. // Names for functions here and in dhcpsapi.dll should not be same. So, here is
  803. // a bunch of hash defines to take care fo that problem..
  804. //================================================================================
  805. //BeginExport(defines)
  806. #ifndef CONVERT_NAMES
  807. #define DhcpCreateSubnet DhcpCreateSubnetDS
  808. #define DhcpSetSubnetInfo DhcpSetSubnetInfoDS
  809. #define DhcpGetSubnetInfo DhcpGetSubnetInfoDS
  810. #define DhcpEnumSubnets DhcpEnumSubnetsDS
  811. #define DhcpDeleteSubnet DhcpDeleteSubnetDS
  812. #define DhcpCreateOption DhcpCreateOptionDS
  813. #define DhcpSetOptionInfo DhcpSetOptionInfoDS
  814. #define DhcpGetOptionInfo DhcpGetOptionInfoDS
  815. #define DhcpRemoveOption DhcpRemoveOptionDS
  816. #define DhcpSetOptionValue DhcpSetOptionValueDS
  817. #define DhcpGetOptionValue DhcpGetOptionValueDS
  818. #define DhcpEnumOptionValues DhcpEnumOptionValuesDS
  819. #define DhcpRemoveOptionValue DhcpRemoveOptionValueDS
  820. #define DhcpEnumOptions DhcpEnumOptionsDS
  821. #define DhcpSetOptionValues DhcpSetOptionValuesDS
  822. #define DhcpAddSubnetElement DhcpAddSubnetElementDS
  823. #define DhcpEnumSubnetElements DhcpEnumSubnetElementsDS
  824. #define DhcpRemoveSubnetElement DhcpRemoveSubnetElementDS
  825. #define DhcpAddSubnetElementV4 DhcpAddSubnetElementV4DS
  826. #define DhcpEnumSubnetElementsV4 DhcpEnumSubnetElementsV4DS
  827. #define DhcpRemoveSubnetElementV4 DhcpRemoveSubnetElementV4DS
  828. #define DhcpSetSuperScopeV4 DhcpSetSuperScopeV4DS
  829. #define DhcpGetSuperScopeInfoV4 DhcpGetSuperScopeInfoV4DS
  830. #define DhcpDeleteSuperScopeV4 DhcpDeleteSuperScopeV4DS
  831. #define DhcpSetClientInfo DhcpSetClientInfoDS
  832. #define DhcpGetClientInfo DhcpGetClientInfoDS
  833. #define DhcpSetClientInfoV4 DhcpSetClientInfoV4DS
  834. #define DhcpGetClientInfoV4 DhcpGetClientInfoV4DS
  835. #define DhcpCreateOptionV5 DhcpCreateOptionV5DS
  836. #define DhcpSetOptionInfoV5 DhcpSetOptionInfoV5DS
  837. #define DhcpGetOptionInfoV5 DhcpGetOptionInfoV5DS
  838. #define DhcpEnumOptionsV5 DhcpEnumOptionsV5DS
  839. #define DhcpRemoveOptionV5 DhcpRemoveOptionV5DS
  840. #define DhcpSetOptionValueV5 DhcpSetOptionValueV5DS
  841. #define DhcpSetOptionValuesV5 DhcpSetOptionValuesV5DS
  842. #define DhcpGetOptionValueV5 DhcpGetOptionValueV5DS
  843. #define DhcpEnumOptionValuesV5 DhcpEnumOptionValuesV5DS
  844. #define DhcpRemoveOptionValueV5 DhcpRemoveOptionValueV5DS
  845. #define DhcpCreateClass DhcpCreateClassDS
  846. #define DhcpModifyClass DhcpModifyClassDS
  847. #define DhcpDeleteClass DhcpDeleteClassDS
  848. #define DhcpGetClassInfo DhcpGetClassInfoDS
  849. #define DhcpEnumClasses DhcpEnumClassesDS
  850. #define DhcpGetAllOptions DhcpGetAllOptionsDS
  851. #define DhcpGetAllOptionValues DhcpGetAllOptionValuesDS
  852. #endif CONVERT_NAMES
  853. //EndExport(defines)
  854. BOOLEAN
  855. DhcpDsDllInit(
  856. IN HINSTANCE DllHandle,
  857. IN ULONG Reason,
  858. IN PCONTEXT Context OPTIONAL
  859. )
  860. /*++
  861. Routine Description:
  862. This routine is the standard DLL initialization
  863. routine and all it does is intiialize a critical section
  864. for actual initialization to be done at startup elsewhere.
  865. Arguments:
  866. DllHandle -- handle to current module
  867. Reason -- reason for DLL_PROCESS_ATTACH.. DLL_PROCESS_DETACH
  868. Return Value:
  869. TRUE -- success, FALSE -- failure
  870. --*/
  871. {
  872. if( DLL_PROCESS_ATTACH == Reason ) {
  873. //
  874. // First disable further calls to DllInit
  875. //
  876. if( !DisableThreadLibraryCalls( DllHandle ) ) return FALSE;
  877. //
  878. // Now try to create critical section
  879. //
  880. try {
  881. InitializeCriticalSection(&DhcpDsDllCriticalSection);
  882. } except ( EXCEPTION_EXECUTE_HANDLER ) {
  883. // shouldnt happen but you never know.
  884. return FALSE;
  885. }
  886. } else if( DLL_PROCESS_DETACH == Reason ) {
  887. //
  888. // Cleanup the initialization critical section
  889. //
  890. DeleteCriticalSection(&DhcpDsDllCriticalSection);
  891. }
  892. //
  893. // InitializeCriticalSection does not fail, just throws exception..
  894. // so we always return success.
  895. //
  896. return TRUE;
  897. }
  898. //================================================================================
  899. //================================================================================
  900. // OPTIONS STUFF. Several of the "get" api's are not yet implemneted here.. but
  901. // it is a straigthforward thing to call the DhcpDs versions... they will get
  902. // filled here someday soon.
  903. //================================================================================
  904. //================================================================================
  905. //BeginExport(function)
  906. //DOC Create an option in DS. Checkout DhcpDsCreateOptionDef for more info...
  907. DWORD
  908. DhcpCreateOptionV5( // create a new option (must not exist)
  909. IN LPWSTR ServerIpAddress,
  910. IN DWORD Flags,
  911. IN DHCP_OPTION_ID OptionId, // must be between 0-255 or 256-511 (for vendor stuff)
  912. IN LPWSTR ClassName,
  913. IN LPWSTR VendorName,
  914. IN LPDHCP_OPTION OptionInfo
  915. ) //EndExport(function)
  916. {
  917. DWORD Err, Err2;
  918. STORE_HANDLE hServer,hSubnet;
  919. LPBYTE OptVal;
  920. DWORD OptLen, OptId;
  921. BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
  922. if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
  923. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  924. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  925. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  926. OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
  927. Err = ConvertOptionInfoRPCToMemFormat(OptionInfo, NULL, NULL, NULL, &OptVal, &OptLen);
  928. if( ERROR_SUCCESS != Err ) { // could not convert to easy format
  929. DhcpDsUnlock(&hDhcpRoot);
  930. return Err;
  931. }
  932. Err = GetServer(&hServer, ServerIpAddress );
  933. if( ERROR_SUCCESS != Err ) { // get the server object
  934. DhcpDsUnlock(&hDhcpRoot);
  935. if( OptVal ) MemFree(OptVal);
  936. return Err;
  937. }
  938. Err = DhcpDsCreateOptionDef // create the required option
  939. (
  940. /* hDhcpC */ &hDhcpC,
  941. /* hServer */ &hServer,
  942. /* Reserved */ DDS_RESERVED_DWORD,
  943. /* Name */ OptionInfo->OptionName,
  944. /* Comment */ OptionInfo->OptionComment,
  945. /* ClassName */ VendorName,
  946. /* OptId */ OptId,
  947. /* OptType */ OptionInfo->OptionType,
  948. /* OptVal */ OptVal,
  949. /* OptLen */ OptLen
  950. );
  951. if( OptVal ) MemFree(OptVal);
  952. StoreCleanupHandle(&hServer, 0);
  953. DhcpDsUnlock(&hDhcpRoot);
  954. return Err;
  955. }
  956. //BeginExport(function)
  957. //DOC Modify existing option's fields in the DS. See DhcpDsModifyOptionDef for more
  958. //DOC details
  959. DWORD
  960. DhcpSetOptionInfoV5( // Modify existing option's fields
  961. IN LPWSTR ServerIpAddress,
  962. IN DWORD Flags,
  963. IN DHCP_OPTION_ID OptionId,
  964. IN LPWSTR ClassName,
  965. IN LPWSTR VendorName,
  966. IN LPDHCP_OPTION OptionInfo
  967. ) //EndExport(function)
  968. {
  969. DWORD Err, Err2;
  970. STORE_HANDLE hServer,hSubnet;
  971. LPBYTE OptVal;
  972. DWORD OptLen, OptId;
  973. BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
  974. if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
  975. if( STUB_NOT_INITIALIZED(Err)) return ErrorNotInitialized;
  976. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  977. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  978. OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
  979. Err = ConvertOptionInfoRPCToMemFormat(OptionInfo, NULL, NULL, NULL, &OptVal, &OptLen);
  980. if( ERROR_SUCCESS != Err ) { // could not convert to easy format
  981. DhcpDsUnlock(&hDhcpRoot);
  982. return Err;
  983. }
  984. Err = GetServer(&hServer, ServerIpAddress );
  985. if( ERROR_SUCCESS != Err ) { // get the server object
  986. DhcpDsUnlock(&hDhcpRoot);
  987. if( OptVal ) MemFree(OptVal);
  988. return Err;
  989. }
  990. Err = DhcpDsModifyOptionDef // modify the required option
  991. (
  992. /* hDhcpC */ &hDhcpC,
  993. /* hServer */ &hServer,
  994. /* Reserved */ DDS_RESERVED_DWORD,
  995. /* Name */ OptionInfo->OptionName,
  996. /* Comment */ OptionInfo->OptionComment,
  997. /* ClassName */ VendorName,
  998. /* OptId */ OptId,
  999. /* OptType */ OptionInfo->OptionType,
  1000. /* OptVal */ OptVal,
  1001. /* OptLen */ OptLen
  1002. );
  1003. if( OptVal ) MemFree(OptVal);
  1004. StoreCleanupHandle(&hServer, 0);
  1005. DhcpDsUnlock(&hDhcpRoot);
  1006. return Err;
  1007. }
  1008. //BeginExport(function)
  1009. //DOC not yet supported at this level... (this is supported in a
  1010. //DOC DhcpDs function, no wrapper yet)
  1011. DWORD
  1012. DhcpGetOptionInfoV5( // retrieve option info from off ds structures
  1013. IN LPWSTR ServerIpAddress,
  1014. IN DWORD Flags,
  1015. IN DHCP_OPTION_ID OptionId,
  1016. IN LPWSTR ClassName,
  1017. IN LPWSTR VendorName,
  1018. OUT LPDHCP_OPTION *OptionInfo // allocate memory
  1019. ) //EndExport(function)
  1020. {
  1021. DWORD Err, Err2;
  1022. STORE_HANDLE hServer,hSubnet;
  1023. LPBYTE OptVal;
  1024. DWORD OptLen, OptId;
  1025. BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
  1026. if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
  1027. OptionId = ConvertOptIdToMemValue(OptionId, IsVendor);
  1028. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1029. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1030. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1031. Err = GetServer(&hServer, ServerIpAddress );
  1032. if( ERROR_SUCCESS != Err ) { // get the server object
  1033. DhcpDsUnlock(&hDhcpRoot);
  1034. return Err;
  1035. }
  1036. Err = DhcpDsGetOptionDef // get the option info from DS
  1037. (
  1038. /* hDhcpC */ &hDhcpC,
  1039. /* hServer */ &hServer,
  1040. /* Reserved */ DDS_RESERVED_DWORD,
  1041. /* ClassName */ VendorName,
  1042. /* OptId */ OptionId,
  1043. /* OptInfo */ OptionInfo
  1044. );
  1045. StoreCleanupHandle(&hServer, 0);
  1046. DhcpDsUnlock(&hDhcpRoot);
  1047. return Err;
  1048. }
  1049. //BeginExport(function)
  1050. //DOC See DhcpDsEnumOptionDefs for more info on this function.. but essentially, all this
  1051. //DOC does is to read thru the options and create a list of options..
  1052. DWORD
  1053. DhcpEnumOptionsV5( // create list of all options in ds
  1054. IN LPWSTR ServerIpAddress,
  1055. IN DWORD Flags,
  1056. IN LPWSTR ClassName,
  1057. IN LPWSTR VendorName,
  1058. IN OUT DHCP_RESUME_HANDLE *ResumeHandle,
  1059. IN DWORD PreferredMaximum,
  1060. OUT LPDHCP_OPTION_ARRAY *Options,
  1061. OUT DWORD *OptionsRead,
  1062. OUT DWORD *OptionsTotal
  1063. ) //EndExport(function)
  1064. {
  1065. DWORD Err, Err2;
  1066. STORE_HANDLE hServer,hSubnet;
  1067. BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
  1068. if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
  1069. if( NULL == OptionsRead || NULL == OptionsTotal
  1070. || NULL == Options || NULL == ResumeHandle ) {
  1071. return ERROR_INVALID_PARAMETER;
  1072. }
  1073. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1074. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1075. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1076. Err = GetServer(&hServer, ServerIpAddress );
  1077. if( ERROR_SUCCESS != Err ) { // get the server object
  1078. DhcpDsUnlock(&hDhcpRoot);
  1079. return Err;
  1080. }
  1081. Err = DhcpDsEnumOptionDefs // get opt list from ds
  1082. (
  1083. /* hDhcpC */ &hDhcpC,
  1084. /* hServer */ &hServer,
  1085. /* Reserved */ DDS_RESERVED_DWORD,
  1086. /* ClassName */ VendorName,
  1087. /* IsVendor */ IsVendor,
  1088. /* RetOptArray */ Options
  1089. );
  1090. if( ERROR_SUCCESS == Err ) {
  1091. *OptionsRead = (*Options)->NumElements;
  1092. *OptionsTotal = *OptionsRead;
  1093. }
  1094. StoreCleanupHandle(&hServer, 0);
  1095. DhcpDsUnlock(&hDhcpRoot);
  1096. return Err;
  1097. }
  1098. //BeginExport(function)
  1099. //DOC Delete an option from off the DS. See DhcpDsDeleteOptionDef for
  1100. //DOC more details.
  1101. DWORD
  1102. DhcpRemoveOptionV5( // remove an option from off DS
  1103. IN LPWSTR ServerIpAddress,
  1104. IN DWORD Flags,
  1105. IN DHCP_OPTION_ID OptionId,
  1106. IN LPWSTR ClassName,
  1107. IN LPWSTR VendorName
  1108. ) //EndExport(function)
  1109. {
  1110. DWORD Err, Err2;
  1111. STORE_HANDLE hServer,hSubnet;
  1112. DWORD OptId;
  1113. BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
  1114. if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
  1115. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1116. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1117. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1118. OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
  1119. Err = GetServer(&hServer, ServerIpAddress );
  1120. if( ERROR_SUCCESS != Err ) { // get the server object
  1121. DhcpDsUnlock(&hDhcpRoot);
  1122. return Err;
  1123. }
  1124. Err = DhcpDsDeleteOptionDef // delete the required option
  1125. (
  1126. /* hDhcpC */ &hDhcpC,
  1127. /* hServer */ &hServer,
  1128. /* Reserved */ DDS_RESERVED_DWORD,
  1129. /* ClassName */ VendorName,
  1130. /* OptId */ OptId
  1131. );
  1132. StoreCleanupHandle(&hServer, 0);
  1133. DhcpDsUnlock(&hDhcpRoot);
  1134. return Err;
  1135. }
  1136. //BeginExport(function)
  1137. //DOC Set the specified option value in the DS. For more information,
  1138. //DOC see DhcpDsSetOptionValue.
  1139. DWORD
  1140. DhcpSetOptionValueV5( // set the option value in ds
  1141. IN LPWSTR ServerIpAddress,
  1142. IN DWORD Flags,
  1143. IN DHCP_OPTION_ID OptionId,
  1144. IN LPWSTR ClassName,
  1145. IN LPWSTR VendorName,
  1146. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
  1147. IN LPDHCP_OPTION_DATA OptionValue
  1148. ) //EndExport(function)
  1149. {
  1150. DWORD Err, Err2;
  1151. STORE_HANDLE hServer,hSubnet,hReservation;
  1152. LPSTORE_HANDLE hObject;
  1153. DWORD OptId;
  1154. BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
  1155. if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
  1156. if( NULL == ScopeInfo ) {
  1157. return ERROR_INVALID_PARAMETER;
  1158. }
  1159. if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
  1160. return ERROR_CALL_NOT_IMPLEMENTED;
  1161. #if 0
  1162. return DhcpSetOptionInfoV5( // setting default options?
  1163. ServerIpAddress,
  1164. OptionId,
  1165. ClassName,
  1166. IsVendor,
  1167. OptionInfo
  1168. );
  1169. #endif
  1170. }
  1171. if( NULL == OptionValue ) {
  1172. return ERROR_INVALID_PARAMETER;
  1173. }
  1174. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1175. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1176. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1177. Err = GetServer(&hServer, ServerIpAddress );
  1178. if( ERROR_SUCCESS != Err ) { // get the server object
  1179. DhcpDsUnlock(&hDhcpRoot);
  1180. return Err;
  1181. }
  1182. if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
  1183. hObject = &hServer; // server level options
  1184. Err = ERROR_SUCCESS;
  1185. } else {
  1186. if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
  1187. Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
  1188. hObject = &hSubnet; // subnet level options
  1189. } else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
  1190. Err = ERROR_INVALID_PARAMETER;
  1191. } else { // reservation level options
  1192. Err = GetReservation(
  1193. &hServer,
  1194. &hReservation,
  1195. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
  1196. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
  1197. );
  1198. hObject = &hReservation;
  1199. }
  1200. }
  1201. if( ERROR_SUCCESS != Err ) {
  1202. DhcpDsUnlock(&hDhcpRoot);
  1203. StoreCleanupHandle(&hServer, 0);
  1204. return Err;
  1205. }
  1206. OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
  1207. Err = DhcpDsSetOptionValue // set the option value in DS now
  1208. (
  1209. /* hDhcpC */ &hDhcpC,
  1210. /* hObject */ hObject,
  1211. /* Reserved */ DDS_RESERVED_DWORD,
  1212. /* ClassName */ VendorName,
  1213. /* UserClass */ ClassName,
  1214. /* OptId */ OptId,
  1215. /* OptData */ OptionValue
  1216. );
  1217. StoreCleanupHandle(&hServer, 0);
  1218. if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
  1219. DhcpDsUnlock(&hDhcpRoot);
  1220. return Err;
  1221. }
  1222. //BeginExport(function)
  1223. //DOC This function just calls the SetOptionValue function N times.. this is not
  1224. //DOC atomic (), but even worse, it is highly inefficient, as it creates the
  1225. //DOC required objects over and over again!!!!!
  1226. //DOC This has to be fixed..
  1227. DWORD
  1228. DhcpSetOptionValuesV5( // set a series of option values
  1229. IN LPWSTR ServerIpAddress,
  1230. IN DWORD Flags,
  1231. IN LPWSTR ClassName,
  1232. IN LPWSTR VendorName,
  1233. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
  1234. IN LPDHCP_OPTION_VALUE_ARRAY OptionValues
  1235. ) //EndExport(function)
  1236. {
  1237. DWORD Err, Err2;
  1238. STORE_HANDLE hServer,hSubnet,hReservation;
  1239. LPSTORE_HANDLE hObject;
  1240. DWORD OptId, i, OptionId;
  1241. BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
  1242. if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
  1243. if( NULL == ScopeInfo ) {
  1244. return ERROR_INVALID_PARAMETER;
  1245. }
  1246. if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
  1247. return ERROR_CALL_NOT_IMPLEMENTED;
  1248. #if 0
  1249. for( i = 0; i < OptionValues->NumElements; i ++ ) {
  1250. Err = DhcpSetOptionInfoV5( // setting default options?
  1251. ServerIpAddress,
  1252. OptionValues->Values[i].OptionID,
  1253. ClassName,
  1254. IsVendor,
  1255. &OptionValues->Values[i].Value
  1256. );
  1257. if( ERROR_SUCCESS != Err ) break;
  1258. }
  1259. return Err;
  1260. #endif
  1261. }
  1262. if( NULL == OptionValues ) {
  1263. return ERROR_INVALID_PARAMETER;
  1264. }
  1265. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1266. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1267. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1268. Err = GetServer(&hServer, ServerIpAddress );
  1269. if( ERROR_SUCCESS != Err ) { // get the server object
  1270. DhcpDsUnlock(&hDhcpRoot);
  1271. return Err;
  1272. }
  1273. if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
  1274. hObject = &hServer; // server level options
  1275. Err = ERROR_SUCCESS;
  1276. } else {
  1277. if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
  1278. Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
  1279. hObject = &hSubnet; // subnet level options
  1280. } else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
  1281. Err = ERROR_INVALID_PARAMETER;
  1282. } else { // reservation level options
  1283. Err = GetReservation(
  1284. &hServer,
  1285. &hReservation,
  1286. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
  1287. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
  1288. );
  1289. hObject = &hReservation;
  1290. }
  1291. }
  1292. if( ERROR_SUCCESS != Err ) {
  1293. DhcpDsUnlock(&hDhcpRoot);
  1294. StoreCleanupHandle(&hServer, 0);
  1295. return Err;
  1296. }
  1297. for( i = 0; i < OptionValues->NumElements; i ++ ) {
  1298. OptionId = OptionValues->Values[i].OptionID;
  1299. OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
  1300. Err = DhcpDsSetOptionValue // set the option value in DS now
  1301. (
  1302. /* hDhcpC */ &hDhcpC,
  1303. /* hObject */ hObject,
  1304. /* Reserved */ DDS_RESERVED_DWORD,
  1305. /* ClassName */ VendorName,
  1306. /* UserClass */ ClassName,
  1307. /* OptId */ OptId,
  1308. /* OptData */ &OptionValues->Values[i].Value
  1309. );
  1310. if( ERROR_SUCCESS != Err ) break; // not atomic, so break whenever err
  1311. }
  1312. StoreCleanupHandle(&hServer, 0);
  1313. if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
  1314. DhcpDsUnlock(&hDhcpRoot);
  1315. return Err;
  1316. }
  1317. //BeginExport(function)
  1318. //DOC This function retrives the value of an option from the DS. For more info,
  1319. //DOC pl check DhcpDsGetOptionValue.
  1320. DWORD
  1321. DhcpGetOptionValueV5(
  1322. IN LPWSTR ServerIpAddress,
  1323. IN DWORD Flags,
  1324. IN DHCP_OPTION_ID OptionId,
  1325. IN LPWSTR ClassName,
  1326. IN LPWSTR VendorName,
  1327. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
  1328. OUT LPDHCP_OPTION_VALUE *OptionValue
  1329. ) //EndExport(function)
  1330. {
  1331. DWORD Err, Err2;
  1332. STORE_HANDLE hServer,hSubnet,hReservation;
  1333. LPSTORE_HANDLE hObject;
  1334. DWORD OptId;
  1335. BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
  1336. if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
  1337. if( NULL == ScopeInfo ) {
  1338. return ERROR_INVALID_PARAMETER;
  1339. }
  1340. if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
  1341. return ERROR_CALL_NOT_IMPLEMENTED;
  1342. #if 0
  1343. return DhcpGetOptionInfoV5( // getting default options?
  1344. ServerIpAddress,
  1345. OptionId,
  1346. ClassName,
  1347. IsVendor,
  1348. OptionValue
  1349. );
  1350. #endif 0
  1351. }
  1352. if( NULL == OptionValue ) {
  1353. return ERROR_INVALID_PARAMETER;
  1354. }
  1355. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1356. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1357. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1358. OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
  1359. Err = GetServer(&hServer, ServerIpAddress );
  1360. if( ERROR_SUCCESS != Err ) { // get the server object
  1361. DhcpDsUnlock(&hDhcpRoot);
  1362. return Err;
  1363. }
  1364. if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
  1365. hObject = &hServer; // server level options
  1366. Err = ERROR_SUCCESS;
  1367. } else {
  1368. if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
  1369. Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
  1370. hObject = &hSubnet; // subnet level options
  1371. } else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
  1372. Err = ERROR_INVALID_PARAMETER;
  1373. } else { // reservation level options
  1374. Err = GetReservation(
  1375. &hServer,
  1376. &hReservation,
  1377. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
  1378. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
  1379. );
  1380. hObject = &hReservation;
  1381. }
  1382. }
  1383. if( ERROR_SUCCESS != Err ) {
  1384. DhcpDsUnlock(&hDhcpRoot);
  1385. StoreCleanupHandle(&hServer, 0);
  1386. return Err;
  1387. }
  1388. Err = DhcpDsGetOptionValue // get the option value in DS now
  1389. (
  1390. /* hDhcpC */ &hDhcpC,
  1391. /* hObject */ hObject,
  1392. /* Reserved */ DDS_RESERVED_DWORD,
  1393. /* ClassName */ VendorName,
  1394. /* UserClass */ ClassName,
  1395. /* OptId */ OptId,
  1396. /* OptData */ OptionValue
  1397. );
  1398. StoreCleanupHandle(&hServer, 0);
  1399. if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
  1400. DhcpDsUnlock(&hDhcpRoot);
  1401. return Err;
  1402. }
  1403. //BeginExport(function)
  1404. //DOC Get the list of option values defined in DS. For more information,
  1405. //DOC check DhcpDsEnumOptionValues.
  1406. DWORD
  1407. DhcpEnumOptionValuesV5( // get list of options defined in DS
  1408. IN LPWSTR ServerIpAddress,
  1409. IN DWORD Flags,
  1410. IN LPWSTR ClassName,
  1411. IN LPWSTR VendorName,
  1412. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
  1413. IN DHCP_RESUME_HANDLE *ResumeHandle,
  1414. IN DWORD PreferredMaximum,
  1415. OUT LPDHCP_OPTION_VALUE_ARRAY *OptionValues,
  1416. OUT DWORD *OptionsRead,
  1417. OUT DWORD *OptionsTotal
  1418. ) //EndExport(function)
  1419. {
  1420. DWORD Err, Err2;
  1421. STORE_HANDLE hServer,hSubnet,hReservation;
  1422. LPSTORE_HANDLE hObject;
  1423. DWORD OptId;
  1424. BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
  1425. if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
  1426. if( NULL == ScopeInfo ) {
  1427. return ERROR_INVALID_PARAMETER;
  1428. }
  1429. if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
  1430. return ERROR_INVALID_PARAMETER; // : totally suspcicious..
  1431. }
  1432. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1433. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1434. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1435. Err = GetServer(&hServer, ServerIpAddress );
  1436. if( ERROR_SUCCESS != Err ) { // get the server object
  1437. DhcpDsUnlock(&hDhcpRoot);
  1438. return Err;
  1439. }
  1440. if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
  1441. hObject = &hServer; // server level options
  1442. Err = ERROR_SUCCESS;
  1443. } else {
  1444. if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
  1445. Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
  1446. hObject = &hSubnet; // subnet level options
  1447. } else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
  1448. Err = ERROR_INVALID_PARAMETER;
  1449. } else { // reservation level options
  1450. Err = GetReservation(
  1451. &hServer,
  1452. &hReservation,
  1453. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
  1454. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
  1455. );
  1456. hObject = &hReservation;
  1457. }
  1458. }
  1459. if( ERROR_SUCCESS != Err ) {
  1460. DhcpDsUnlock(&hDhcpRoot);
  1461. StoreCleanupHandle(&hServer, 0);
  1462. return Err;
  1463. }
  1464. Err = DhcpDsEnumOptionValues // remove opt val frm DS now
  1465. (
  1466. /* hDhcpC */ &hDhcpC,
  1467. /* hObject */ hObject,
  1468. /* Reserved */ DDS_RESERVED_DWORD,
  1469. /* ClassName */ VendorName,
  1470. /* UserClass */ ClassName,
  1471. /* IsVendor */ IsVendor,
  1472. /* OptionValues */ OptionValues
  1473. );
  1474. if( ERROR_SUCCESS == Err ) { // set the read etc params
  1475. *OptionsRead = *OptionsTotal = (*OptionValues)->NumElements;
  1476. }
  1477. StoreCleanupHandle(&hServer, 0);
  1478. if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
  1479. DhcpDsUnlock(&hDhcpRoot);
  1480. return Err;
  1481. }
  1482. //BeginExport(function)
  1483. //DOC Remove the option value from off the DS. See DhcpDsRemoveOptionValue
  1484. //DOC for further information.
  1485. DWORD
  1486. DhcpRemoveOptionValueV5( // remove option value from DS
  1487. IN LPWSTR ServerIpAddress,
  1488. IN DWORD Flags,
  1489. IN DHCP_OPTION_ID OptionId,
  1490. IN LPWSTR ClassName,
  1491. IN LPWSTR VendorName,
  1492. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo
  1493. ) //EndExport(function)
  1494. {
  1495. DWORD Err, Err2;
  1496. STORE_HANDLE hServer,hSubnet,hReservation;
  1497. LPSTORE_HANDLE hObject;
  1498. DWORD OptId;
  1499. BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
  1500. if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
  1501. if( NULL == ScopeInfo ) {
  1502. return ERROR_INVALID_PARAMETER;
  1503. }
  1504. if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
  1505. return ERROR_INVALID_PARAMETER; // : totally suspcicious..
  1506. }
  1507. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1508. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1509. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1510. OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
  1511. Err = GetServer(&hServer, ServerIpAddress );
  1512. if( ERROR_SUCCESS != Err ) { // get the server object
  1513. DhcpDsUnlock(&hDhcpRoot);
  1514. return Err;
  1515. }
  1516. if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
  1517. hObject = &hServer; // server level options
  1518. Err = ERROR_SUCCESS;
  1519. } else {
  1520. if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
  1521. Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
  1522. hObject = &hSubnet; // subnet level options
  1523. } else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
  1524. Err = ERROR_INVALID_PARAMETER;
  1525. } else { // reservation level options
  1526. Err = GetReservation(
  1527. &hServer,
  1528. &hReservation,
  1529. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
  1530. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
  1531. );
  1532. hObject = &hReservation;
  1533. }
  1534. }
  1535. if( ERROR_SUCCESS != Err ) {
  1536. DhcpDsUnlock(&hDhcpRoot);
  1537. StoreCleanupHandle(&hServer, 0);
  1538. return Err;
  1539. }
  1540. Err = DhcpDsRemoveOptionValue // remove opt val frm DS now
  1541. (
  1542. /* hDhcpC */ &hDhcpC,
  1543. /* hObject */ hObject,
  1544. /* Reserved */ DDS_RESERVED_DWORD,
  1545. /* ClassName */ VendorName,
  1546. /* UserClass */ ClassName,
  1547. /* OptId */ OptId
  1548. );
  1549. StoreCleanupHandle(&hServer, 0);
  1550. if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
  1551. DhcpDsUnlock(&hDhcpRoot);
  1552. return Err;
  1553. }
  1554. //BeginExport(function)
  1555. //DOC Create a class in the DS. Please see DhcpDsCreateClass for more
  1556. //DOC details on this function.
  1557. DWORD
  1558. DhcpCreateClass( // create a class in DS
  1559. IN LPWSTR ServerIpAddress,
  1560. IN DWORD ReservedMustBeZero,
  1561. IN LPDHCP_CLASS_INFO ClassInfo
  1562. ) //EndExport(function)
  1563. {
  1564. DWORD Err, Err2;
  1565. STORE_HANDLE hServer,hSubnet;
  1566. if( NULL == ClassInfo || 0 != ReservedMustBeZero ) {
  1567. return ERROR_INVALID_PARAMETER;
  1568. }
  1569. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1570. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1571. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1572. Err = GetServer(&hServer, ServerIpAddress );
  1573. if( ERROR_SUCCESS != Err ) { // get the server object
  1574. DhcpDsUnlock(&hDhcpRoot);
  1575. return Err;
  1576. }
  1577. Err = DhcpDsCreateClass // create the class
  1578. (
  1579. /* hDhcpC */ &hDhcpC,
  1580. /* hServer */ &hServer,
  1581. /* Reserved */ DDS_RESERVED_DWORD,
  1582. /* ClassName */ ClassInfo->ClassName,
  1583. /* ClassComment */ ClassInfo->ClassComment,
  1584. /* ClassData */ ClassInfo->ClassData,
  1585. /* ClassDataLength */ ClassInfo->ClassDataLength,
  1586. /* IsVendor */ ClassInfo->IsVendor
  1587. );
  1588. StoreCleanupHandle(&hServer, 0);
  1589. DhcpDsUnlock(&hDhcpRoot);
  1590. return Err;
  1591. }
  1592. //BeginExport(function)
  1593. //DOC Modify an existing class in DS. Please see DhcpDsModifyClass for more
  1594. //DOC details on this function (this is just a wrapper).
  1595. DWORD
  1596. DhcpModifyClass( // modify existing class
  1597. IN LPWSTR ServerIpAddress,
  1598. IN DWORD ReservedMustBeZero,
  1599. IN LPDHCP_CLASS_INFO ClassInfo
  1600. ) //EndExport(function)
  1601. {
  1602. DWORD Err, Err2;
  1603. STORE_HANDLE hServer,hSubnet;
  1604. if( NULL == ClassInfo || 0 != ReservedMustBeZero ) {
  1605. return ERROR_INVALID_PARAMETER;
  1606. }
  1607. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1608. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1609. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1610. Err = GetServer(&hServer, ServerIpAddress );
  1611. if( ERROR_SUCCESS != Err ) { // get the server object
  1612. DhcpDsUnlock(&hDhcpRoot);
  1613. return Err;
  1614. }
  1615. Err = DhcpDsModifyClass // modify the class
  1616. (
  1617. /* hDhcpC */ &hDhcpC,
  1618. /* hServer */ &hServer,
  1619. /* Reserved */ DDS_RESERVED_DWORD,
  1620. /* ClassName */ ClassInfo->ClassName,
  1621. /* ClassComment */ ClassInfo->ClassComment,
  1622. /* ClassData */ ClassInfo->ClassData,
  1623. /* ClassDataLength */ ClassInfo->ClassDataLength
  1624. );
  1625. StoreCleanupHandle(&hServer, 0);
  1626. DhcpDsUnlock(&hDhcpRoot);
  1627. return Err;
  1628. }
  1629. //BeginExport(function)
  1630. //DOC Delete an existing class in DS. Please see DhcpDsModifyClass for more
  1631. //DOC details on this function (this is just a wrapper).
  1632. DWORD
  1633. DhcpDeleteClass( // delete a class from off DS
  1634. IN LPWSTR ServerIpAddress,
  1635. IN DWORD ReservedMustBeZero,
  1636. IN LPWSTR ClassName
  1637. ) //EndExport(function)
  1638. {
  1639. DWORD Err, Err2;
  1640. STORE_HANDLE hServer,hSubnet;
  1641. if( NULL == ClassName || 0 != ReservedMustBeZero ) {
  1642. return ERROR_INVALID_PARAMETER;
  1643. }
  1644. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1645. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1646. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1647. Err = GetServer(&hServer, ServerIpAddress );
  1648. if( ERROR_SUCCESS != Err ) { // get the server object
  1649. DhcpDsUnlock(&hDhcpRoot);
  1650. return Err;
  1651. }
  1652. Err = DhcpDsDeleteClass // delete the class
  1653. (
  1654. /* hDhcpC */ &hDhcpC,
  1655. /* hServer */ &hServer,
  1656. /* Reserved */ DDS_RESERVED_DWORD,
  1657. /* ClassName */ ClassName
  1658. );
  1659. StoreCleanupHandle(&hServer, 0);
  1660. DhcpDsUnlock(&hDhcpRoot);
  1661. return Err;
  1662. }
  1663. //BeginExport(function)
  1664. //DOC DhcpGetClassInfo completes the information provided for a class in struct
  1665. //DOC PartialClassInfo. For more details pl see DhcpDsGetClassInfo.
  1666. DWORD
  1667. DhcpGetClassInfo( // fetch complete info frm DS
  1668. IN LPWSTR ServerIpAddress,
  1669. IN DWORD ReservedMustBeZero,
  1670. IN LPDHCP_CLASS_INFO PartialClassInfo,
  1671. OUT LPDHCP_CLASS_INFO *FilledClassInfo
  1672. ) //EndExport(function)
  1673. {
  1674. DWORD Err, Err2;
  1675. STORE_HANDLE hServer,hSubnet;
  1676. if( NULL == PartialClassInfo || 0 != ReservedMustBeZero ) {
  1677. return ERROR_INVALID_PARAMETER;
  1678. }
  1679. if( NULL == FilledClassInfo ) {
  1680. return ERROR_INVALID_PARAMETER;
  1681. }
  1682. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1683. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1684. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1685. Err = GetServer(&hServer, ServerIpAddress );
  1686. if( ERROR_SUCCESS != Err ) { // get the server object
  1687. DhcpDsUnlock(&hDhcpRoot);
  1688. return Err;
  1689. }
  1690. Err = DhcpDsGetClassInfo // get class info from DS
  1691. (
  1692. /* hDhcpC */ &hDhcpC,
  1693. /* hServer */ &hServer,
  1694. /* Reserved */ DDS_RESERVED_DWORD,
  1695. /* ClassName */ PartialClassInfo->ClassName,
  1696. /* ClassData */ PartialClassInfo->ClassData,
  1697. /* ClassDataLen */ PartialClassInfo->ClassDataLength,
  1698. /* ClassInfo */ FilledClassInfo
  1699. );
  1700. StoreCleanupHandle(&hServer, 0);
  1701. DhcpDsUnlock(&hDhcpRoot);
  1702. return Err;
  1703. }
  1704. //BeginExport(function)
  1705. //DOC This is implemented in the DHCPDS module, but not exported here yet..
  1706. DWORD
  1707. DhcpEnumClasses(
  1708. IN LPWSTR ServerIpAddress,
  1709. IN DWORD ReservedMustBeZero,
  1710. IN OUT DHCP_RESUME_HANDLE *ResumeHandle,
  1711. IN DWORD PreferredMaximum,
  1712. OUT LPDHCP_CLASS_INFO_ARRAY *ClassInfoArray,
  1713. OUT DWORD *nRead,
  1714. OUT DWORD *nTotal
  1715. ) //EndExport(function)
  1716. {
  1717. DWORD Err, Err2;
  1718. STORE_HANDLE hServer,hSubnet;
  1719. if( NULL == ClassInfoArray ) return ERROR_INVALID_PARAMETER;
  1720. *nRead = *nTotal = 0;
  1721. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1722. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1723. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1724. Err = GetServer(&hServer, ServerIpAddress );
  1725. if( ERROR_SUCCESS != Err ) { // get the server object
  1726. DhcpDsUnlock(&hDhcpRoot);
  1727. return Err;
  1728. }
  1729. Err = DhcpDsEnumClasses // get list of classes
  1730. (
  1731. /* hDhcpC */ &hDhcpC,
  1732. /* hServer */ &hServer,
  1733. /* Reserved */ DDS_RESERVED_DWORD,
  1734. /* Classes */ ClassInfoArray
  1735. );
  1736. if( ERROR_SUCCESS == Err ) { // filled nRead&nTotal
  1737. *nRead = *nTotal = (*ClassInfoArray)->NumElements;
  1738. }
  1739. StoreCleanupHandle(&hServer, 0);
  1740. DhcpDsUnlock(&hDhcpRoot);
  1741. return Err;
  1742. }
  1743. //BeginExport(function)
  1744. //DOC This is implemented in the DHCPDS module, but not exported here yet..
  1745. DWORD
  1746. DhcpGetAllOptionValues(
  1747. IN LPWSTR ServerIpAddress,
  1748. IN DWORD Flags,
  1749. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
  1750. OUT LPDHCP_ALL_OPTION_VALUES *Values
  1751. ) //EndExport(function)
  1752. {
  1753. DWORD Err, Err2;
  1754. STORE_HANDLE hServer,hSubnet,hReservation;
  1755. LPSTORE_HANDLE hObject;
  1756. DWORD OptId;
  1757. if( 0 != Flags ) return ERROR_INVALID_PARAMETER;
  1758. if( NULL == ScopeInfo ) {
  1759. return ERROR_INVALID_PARAMETER;
  1760. }
  1761. if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
  1762. return ERROR_CALL_NOT_IMPLEMENTED;
  1763. }
  1764. if( NULL == Values ) {
  1765. return ERROR_INVALID_PARAMETER;
  1766. }
  1767. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1768. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1769. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1770. Err = GetServer(&hServer, ServerIpAddress );
  1771. if( ERROR_SUCCESS != Err ) { // get the server object
  1772. DhcpDsUnlock(&hDhcpRoot);
  1773. return Err;
  1774. }
  1775. if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
  1776. hObject = &hServer; // server level options
  1777. Err = ERROR_SUCCESS;
  1778. } else {
  1779. if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
  1780. Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
  1781. hObject = &hSubnet; // subnet level options
  1782. } else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
  1783. Err = ERROR_INVALID_PARAMETER;
  1784. } else { // reservation level options
  1785. Err = GetReservation(
  1786. &hServer,
  1787. &hReservation,
  1788. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
  1789. ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
  1790. );
  1791. hObject = &hReservation;
  1792. }
  1793. }
  1794. if( ERROR_SUCCESS != Err ) {
  1795. DhcpDsUnlock(&hDhcpRoot);
  1796. StoreCleanupHandle(&hServer, 0);
  1797. return Err;
  1798. }
  1799. Err = DhcpDsGetAllOptionValues // get all the option values from DS
  1800. (
  1801. /* hDhcpC */ &hDhcpC,
  1802. /* hObject */ hObject,
  1803. /* Reserved */ DDS_RESERVED_DWORD,
  1804. /* Values */ Values
  1805. );
  1806. StoreCleanupHandle(&hServer, 0);
  1807. if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
  1808. DhcpDsUnlock(&hDhcpRoot);
  1809. return Err;
  1810. }
  1811. //BeginExport(function)
  1812. //DOC This is implememented in the DHCPDS module, but not exported here yet..
  1813. DWORD
  1814. DhcpGetAllOptions(
  1815. IN LPWSTR ServerIpAddress,
  1816. IN DWORD Flags,
  1817. OUT LPDHCP_ALL_OPTIONS *Options
  1818. ) //EndExport(function)
  1819. {
  1820. DWORD Err, Err2;
  1821. STORE_HANDLE hServer,hSubnet;
  1822. if( NULL == Options || 0 != Flags ) {
  1823. return ERROR_INVALID_PARAMETER;
  1824. }
  1825. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  1826. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  1827. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  1828. Err = GetServer(&hServer, ServerIpAddress );
  1829. if( ERROR_SUCCESS != Err ) { // get the server object
  1830. DhcpDsUnlock(&hDhcpRoot);
  1831. return Err;
  1832. }
  1833. Err = DhcpDsGetAllOptions // get opt list from ds
  1834. (
  1835. /* hDhcpC */ &hDhcpC,
  1836. /* hServer */ &hServer,
  1837. /* Reserved */ DDS_RESERVED_DWORD,
  1838. /* Options */ Options
  1839. );
  1840. StoreCleanupHandle(&hServer, 0);
  1841. DhcpDsUnlock(&hDhcpRoot);
  1842. return Err;
  1843. }
  1844. //================================================================================
  1845. // NT 5 beta1 and before -- the stubs for those are here...
  1846. //================================================================================
  1847. //BeginExport(function)
  1848. DWORD // ERROR_DHCP_OPTION_EXITS if option is already there
  1849. DhcpCreateOption( // create a new option (must not exist)
  1850. IN LPWSTR ServerIpAddress,
  1851. IN DHCP_OPTION_ID OptionId, // must be between 0-255 or 256-511 (for vendor stuff)
  1852. IN LPDHCP_OPTION OptionInfo
  1853. ) //EndExport(function)
  1854. {
  1855. return DhcpCreateOptionV5(
  1856. ServerIpAddress,
  1857. 0,
  1858. OptionId,
  1859. NULL,
  1860. NULL,
  1861. OptionInfo
  1862. );
  1863. }
  1864. //BeginExport(function)
  1865. DWORD // ERROR_DHCP_OPTION_NOT_PRESENT if option does not exist
  1866. DhcpSetOptionInfo( // Modify existing option's fields
  1867. IN LPWSTR ServerIpAddress,
  1868. IN DHCP_OPTION_ID OptionID,
  1869. IN LPDHCP_OPTION OptionInfo
  1870. ) //EndExport(function)
  1871. {
  1872. return DhcpSetOptionInfoV5(
  1873. ServerIpAddress,
  1874. 0,
  1875. OptionID,
  1876. NULL,
  1877. NULL,
  1878. OptionInfo
  1879. );
  1880. }
  1881. //BeginExport(function)
  1882. DWORD // ERROR_DHCP_OPTION_NOT_PRESENT
  1883. DhcpGetOptionInfo( // retrieve the information from off the mem structures
  1884. IN LPWSTR ServerIpAddress,
  1885. IN DHCP_OPTION_ID OptionID,
  1886. OUT LPDHCP_OPTION *OptionInfo // allocate memory using MIDL functions
  1887. ) //EndExport(function)
  1888. {
  1889. return DhcpGetOptionInfoV5(
  1890. ServerIpAddress,
  1891. 0,
  1892. OptionID,
  1893. NULL,
  1894. NULL,
  1895. OptionInfo
  1896. );
  1897. }
  1898. //BeginExport(function)
  1899. DWORD // ERROR_DHCP_OPTION_NOT_PRESENT if option does not exist
  1900. DhcpEnumOptions( // enumerate the options defined
  1901. IN LPWSTR ServerIpAddress,
  1902. IN OUT DHCP_RESUME_HANDLE *ResumeHandle, // must be zero intially and then never touched
  1903. IN DWORD PreferredMaximum, // max # of bytes of info to pass along
  1904. OUT LPDHCP_OPTION_ARRAY *Options, // fill this option array
  1905. OUT DWORD *OptionsRead, // fill in the # of options read
  1906. OUT DWORD *OptionsTotal // fill in the total # here
  1907. ) //EndExport(function)
  1908. {
  1909. return DhcpEnumOptionsV5(
  1910. ServerIpAddress,
  1911. 0,
  1912. NULL,
  1913. NULL,
  1914. ResumeHandle,
  1915. PreferredMaximum,
  1916. Options,
  1917. OptionsRead,
  1918. OptionsTotal
  1919. );
  1920. }
  1921. //BeginExport(function)
  1922. DWORD // ERROR_DHCP_OPTION_NOT_PRESENT if option not existent
  1923. DhcpRemoveOption( // remove the option definition from the registry
  1924. IN LPWSTR ServerIpAddress,
  1925. IN DHCP_OPTION_ID OptionID
  1926. ) //EndExport(function)
  1927. {
  1928. return DhcpRemoveOptionV5(
  1929. ServerIpAddress,
  1930. 0,
  1931. OptionID,
  1932. NULL,
  1933. NULL
  1934. );
  1935. }
  1936. //BeginExport(function)
  1937. DWORD // OPTION_NOT_PRESENT if option is not defined
  1938. DhcpSetOptionValue( // replace or add a new option value
  1939. IN LPWSTR ServerIpAddress,
  1940. IN DHCP_OPTION_ID OptionID,
  1941. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
  1942. IN LPDHCP_OPTION_DATA OptionValue
  1943. ) //EndExport(function)
  1944. {
  1945. return DhcpSetOptionValueV5(
  1946. ServerIpAddress,
  1947. 0,
  1948. OptionID,
  1949. NULL,
  1950. NULL,
  1951. ScopeInfo,
  1952. OptionValue
  1953. );
  1954. }
  1955. //BeginExport(function)
  1956. DWORD // not atomic!!!!
  1957. DhcpSetOptionValues( // set a bunch of options
  1958. IN LPWSTR ServerIpAddress,
  1959. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
  1960. IN LPDHCP_OPTION_VALUE_ARRAY OptionValues
  1961. ) //EndExport(function)
  1962. {
  1963. return DhcpSetOptionValuesV5(
  1964. ServerIpAddress,
  1965. 0,
  1966. NULL,
  1967. NULL,
  1968. ScopeInfo,
  1969. OptionValues
  1970. );
  1971. }
  1972. //BeginExport(function)
  1973. DWORD
  1974. DhcpGetOptionValue( // fetch the required option at required level
  1975. IN LPWSTR ServerIpAddress,
  1976. IN DHCP_OPTION_ID OptionID,
  1977. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
  1978. OUT LPDHCP_OPTION_VALUE *OptionValue // allocate memory using MIDL_user_allocate
  1979. ) //EndExport(function)
  1980. {
  1981. return DhcpGetOptionValueV5(
  1982. ServerIpAddress,
  1983. 0,
  1984. OptionID,
  1985. NULL,
  1986. NULL,
  1987. ScopeInfo,
  1988. OptionValue
  1989. );
  1990. }
  1991. //BeginExport(function)
  1992. DWORD
  1993. DhcpEnumOptionValues(
  1994. IN LPWSTR ServerIpAddress,
  1995. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
  1996. IN DHCP_RESUME_HANDLE *ResumeHandle,
  1997. IN DWORD PreferredMaximum,
  1998. OUT LPDHCP_OPTION_VALUE_ARRAY *OptionValues,
  1999. OUT DWORD *OptionsRead,
  2000. OUT DWORD *OptionsTotal
  2001. ) //EndExport(function)
  2002. {
  2003. return DhcpEnumOptionValuesV5(
  2004. ServerIpAddress,
  2005. 0,
  2006. NULL,
  2007. NULL,
  2008. ScopeInfo,
  2009. ResumeHandle,
  2010. PreferredMaximum,
  2011. OptionValues,
  2012. OptionsRead,
  2013. OptionsTotal
  2014. );
  2015. }
  2016. //BeginExport(function)
  2017. DWORD
  2018. DhcpRemoveOptionValue(
  2019. IN LPWSTR ServerIpAddress,
  2020. IN DHCP_OPTION_ID OptionID,
  2021. IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo
  2022. ) //EndExport(function)
  2023. {
  2024. return DhcpRemoveOptionValueV5(
  2025. ServerIpAddress,
  2026. 0,
  2027. OptionID,
  2028. NULL,
  2029. NULL,
  2030. ScopeInfo
  2031. );
  2032. }
  2033. //================================================================================
  2034. //================================================================================
  2035. // The following are the miscellaneous APIs found in rpcapi2.c. Most of the
  2036. // following APIs are not really implementable with the DS alone, and so they
  2037. // just return error. They are provided here so that the dhcpds.dll can be linked
  2038. // to the dhcpcmd.exe program instead of the other dll.
  2039. //================================================================================
  2040. //================================================================================
  2041. //BeginExport(function)
  2042. //DOC This function sets the superscope of a subnet, thereby creating the superscope
  2043. //DOC if required. Please see DhcpDsSetSScope for more details.
  2044. DWORD
  2045. DhcpSetSuperScopeV4( // set superscope in DS.
  2046. IN LPWSTR ServerIpAddress,
  2047. IN DHCP_IP_ADDRESS SubnetAddress,
  2048. IN LPWSTR SuperScopeName,
  2049. IN BOOL ChangeExisting
  2050. ) //EndExport(function)
  2051. {
  2052. DWORD Err, Err2;
  2053. STORE_HANDLE hServer,hSubnet;
  2054. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2055. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2056. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2057. Err = GetServer(&hServer, ServerIpAddress );
  2058. if( ERROR_SUCCESS != Err ) { // get the server object
  2059. DhcpDsUnlock(&hDhcpRoot);
  2060. return Err;
  2061. }
  2062. Err = DhcpDsSetSScope // set the sscope in DS
  2063. (
  2064. /* hDhcpC */ &hDhcpC,
  2065. /* hServer */ &hServer,
  2066. /* Reserved */ DDS_RESERVED_DWORD,
  2067. /* IpAddress */ SubnetAddress,
  2068. /* SScopeName */ SuperScopeName,
  2069. /* ChangeSScope */ ChangeExisting
  2070. );
  2071. DhcpDsUnlock(&hDhcpRoot);
  2072. return Err;
  2073. }
  2074. //BeginExport(function)
  2075. //DOC This function removes the superscope, and resets any subnet with this
  2076. //DOC superscope.. so that all those subnets end up with no superscopes..
  2077. //DOC Please see DhcpDsDelSScope for more details.
  2078. DWORD
  2079. DhcpDeleteSuperScopeV4( // delete subnet sscope from DS
  2080. IN LPWSTR ServerIpAddress,
  2081. IN LPWSTR SuperScopeName
  2082. ) //EndExport(function)
  2083. {
  2084. DWORD Err, Err2;
  2085. STORE_HANDLE hServer,hSubnet;
  2086. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2087. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2088. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2089. Err = GetServer(&hServer, ServerIpAddress );
  2090. if( ERROR_SUCCESS != Err ) { // get the server object
  2091. DhcpDsUnlock(&hDhcpRoot);
  2092. return Err;
  2093. }
  2094. Err = DhcpDsDelSScope // delete the sscope in DS
  2095. (
  2096. /* hDhcpC */ &hDhcpC,
  2097. /* hServer */ &hServer,
  2098. /* Reserved */ DDS_RESERVED_DWORD,
  2099. /* SScopeName */ SuperScopeName
  2100. );
  2101. DhcpDsUnlock(&hDhcpRoot);
  2102. return Err;
  2103. }
  2104. //BeginExport(function)
  2105. //DOC This function retrievs the supercsope info for each subnet that is
  2106. //DOC present for the given server. Please see DhcpDsGetSScopeInfo for more
  2107. //DOC details on this..
  2108. DWORD
  2109. DhcpGetSuperScopeInfoV4( // get sscope tbl from DS
  2110. IN LPWSTR ServerIpAddress,
  2111. OUT LPDHCP_SUPER_SCOPE_TABLE *SuperScopeTable
  2112. ) //EndExport(function)
  2113. {
  2114. DWORD Err, Err2;
  2115. STORE_HANDLE hServer,hSubnet;
  2116. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2117. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2118. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2119. Err = GetServer(&hServer, ServerIpAddress );
  2120. if( ERROR_SUCCESS != Err ) { // get the server object
  2121. DhcpDsUnlock(&hDhcpRoot);
  2122. return Err;
  2123. }
  2124. Err = DhcpDsGetSScopeInfo // get sscope tbl frm DS
  2125. (
  2126. /* hDhcpC */ &hDhcpC,
  2127. /* hServer */ &hServer,
  2128. /* Reserved */ DDS_RESERVED_DWORD,
  2129. /* SScopeTbl */ SuperScopeTable
  2130. );
  2131. DhcpDsUnlock(&hDhcpRoot);
  2132. return Err;
  2133. }
  2134. //BeginExport(function)
  2135. //DOC This function creates a subnet in the DS with the specified params.
  2136. //DOC Please see DhcpDsServerAddSubnet for more details on this function.
  2137. DWORD
  2138. DhcpCreateSubnet( // add subnet 2 DS for this srvr
  2139. IN LPWSTR ServerIpAddress,
  2140. IN DHCP_IP_ADDRESS SubnetAddress,
  2141. IN LPDHCP_SUBNET_INFO SubnetInfo
  2142. ) //EndExport(function)
  2143. {
  2144. DWORD Err, Err2;
  2145. STORE_HANDLE hServer,hSubnet;
  2146. LPWSTR ServerName;
  2147. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2148. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2149. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2150. Err = GetServer(&hServer, ServerIpAddress );
  2151. if( ERROR_SUCCESS != Err ) { // get the server object
  2152. DhcpDsUnlock(&hDhcpRoot);
  2153. return Err;
  2154. }
  2155. Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
  2156. if( ERROR_SUCCESS == Err ) {
  2157. Err = DhcpDsServerAddSubnet // add a new subnet to this srvr
  2158. (
  2159. /* hDhcpC */ &hDhcpC,
  2160. /* hServer */ &hServer,
  2161. /* Reserved */ DDS_RESERVED_DWORD,
  2162. /* ServerName */ ServerName,
  2163. /* Info */ SubnetInfo
  2164. );
  2165. MemFree(ServerName);
  2166. }
  2167. DhcpDsUnlock(&hDhcpRoot);
  2168. return Err;
  2169. }
  2170. //BeginExport(function)
  2171. //DOC Modify existing subnet with new parameters... some restrictions apply.
  2172. //DOC Please see DhcpDsServerModifySubnet for further details.
  2173. DWORD
  2174. DhcpSetSubnetInfo( // modify existing subnet params
  2175. IN LPWSTR ServerIpAddress,
  2176. IN DHCP_IP_ADDRESS SubnetAddress,
  2177. IN LPDHCP_SUBNET_INFO SubnetInfo
  2178. ) //EndExport(function)
  2179. {
  2180. DWORD Err, Err2;
  2181. STORE_HANDLE hServer,hSubnet;
  2182. LPWSTR ServerName;
  2183. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2184. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2185. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2186. Err = GetServer(&hServer, ServerIpAddress );
  2187. if( ERROR_SUCCESS != Err ) { // get the server object
  2188. DhcpDsUnlock(&hDhcpRoot);
  2189. return Err;
  2190. }
  2191. Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
  2192. if( ERROR_SUCCESS == Err ) {
  2193. Err = DhcpDsServerModifySubnet // modify subnet for this srvr
  2194. (
  2195. /* hDhcpC */ &hDhcpC,
  2196. /* hServer */ &hServer,
  2197. /* Reserved */ DDS_RESERVED_DWORD,
  2198. /* ServerName */ ServerName,
  2199. /* Info */ SubnetInfo
  2200. );
  2201. MemFree(ServerName);
  2202. }
  2203. DhcpDsUnlock(&hDhcpRoot);
  2204. return Err;
  2205. }
  2206. //BeginExport(function)
  2207. //DOC Implemented in the DHCPDS module but not exported thru here
  2208. DWORD
  2209. DhcpGetSubnetInfo(
  2210. IN LPWSTR ServerIpAddress,
  2211. IN DHCP_IP_ADDRESS SubnetAddress,
  2212. OUT LPDHCP_SUBNET_INFO *SubnetInfo
  2213. ) //EndExport(function)
  2214. {
  2215. DWORD Err, Err2;
  2216. STORE_HANDLE hServer,hSubnet;
  2217. LPWSTR ServerName;
  2218. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2219. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2220. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2221. Err = GetServer(&hServer, ServerIpAddress );
  2222. if( ERROR_SUCCESS != Err ) { // get the server object
  2223. DhcpDsUnlock(&hDhcpRoot);
  2224. return Err;
  2225. }
  2226. Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
  2227. if( ERROR_SUCCESS == Err ) {
  2228. Err = DhcpDsServerGetSubnetInfo // get subnet info for server
  2229. (
  2230. /* hDhcpC */ &hDhcpC,
  2231. /* hServer */ &hServer,
  2232. /* Reserved */ DDS_RESERVED_DWORD,
  2233. /* ServerName */ ServerName,
  2234. /* SubnetAddress */ SubnetAddress,
  2235. /* Info */ SubnetInfo
  2236. );
  2237. MemFree(ServerName);
  2238. }
  2239. DhcpDsUnlock(&hDhcpRoot);
  2240. return Err;
  2241. }
  2242. //BeginExport(function)
  2243. //DOC Implemented in the DHCPDS module but not exported thru here
  2244. DWORD
  2245. DhcpEnumSubnets(
  2246. IN LPWSTR ServerIpAddress,
  2247. IN DHCP_RESUME_HANDLE *ResumeHandle,
  2248. IN DWORD PreferredMaximum,
  2249. IN LPDHCP_IP_ARRAY *EnumInfo,
  2250. IN DWORD *ElementsRead,
  2251. IN DWORD *ElementsTotal
  2252. ) //EndExport(function)
  2253. {
  2254. DWORD Err, Err2;
  2255. STORE_HANDLE hServer,hSubnet;
  2256. LPWSTR ServerName;
  2257. *EnumInfo = NULL;
  2258. *ElementsRead = *ElementsTotal = 0;
  2259. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2260. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2261. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2262. Err = GetServer(&hServer, ServerIpAddress );
  2263. if( ERROR_SUCCESS != Err ) { // get the server object
  2264. DhcpDsUnlock(&hDhcpRoot);
  2265. return Err;
  2266. }
  2267. Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
  2268. if( ERROR_SUCCESS == Err ) {
  2269. Err = DhcpDsServerEnumSubnets // enum subnets for this srvr
  2270. (
  2271. /* hDhcpC */ &hDhcpC,
  2272. /* hServer */ &hServer,
  2273. /* Reserved */ DDS_RESERVED_DWORD,
  2274. /* ServerName */ ServerName,
  2275. /* SubnetsArray */ EnumInfo
  2276. );
  2277. MemFree(ServerName);
  2278. if( ERROR_SUCCESS == Err ) {
  2279. *ElementsTotal = (*EnumInfo)->NumElements;
  2280. *ElementsRead = *ElementsTotal;
  2281. }
  2282. }
  2283. DhcpDsUnlock(&hDhcpRoot);
  2284. return Err;
  2285. }
  2286. //BeginExport(function)
  2287. //DOC This function deletes the subnet from the DS. For further information, pl
  2288. //DOC see DhcpDsServerDelSubnet..
  2289. DWORD
  2290. DhcpDeleteSubnet( // Del subnet from off DS
  2291. IN LPWSTR ServerIpAddress,
  2292. IN DHCP_IP_ADDRESS SubnetAddress,
  2293. IN DHCP_FORCE_FLAG ForceFlag
  2294. ) //EndExport(function)
  2295. {
  2296. DWORD Err, Err2;
  2297. STORE_HANDLE hServer,hSubnet;
  2298. LPWSTR ServerName;
  2299. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2300. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2301. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2302. Err = GetServer(&hServer, ServerIpAddress );
  2303. if( ERROR_SUCCESS != Err ) { // get the server object
  2304. DhcpDsUnlock(&hDhcpRoot);
  2305. return Err;
  2306. }
  2307. Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
  2308. if( ERROR_SUCCESS == Err ) {
  2309. Err = DhcpDsServerDelSubnet // Del subnet for this srvr
  2310. (
  2311. /* hDhcpC */ &hDhcpC,
  2312. /* hServer */ &hServer,
  2313. /* Reserved */ DDS_RESERVED_DWORD,
  2314. /* ServerName */ ServerName,
  2315. /* IpAddress */ SubnetAddress
  2316. );
  2317. MemFree(ServerName);
  2318. }
  2319. DhcpDsUnlock(&hDhcpRoot);
  2320. return Err;
  2321. }
  2322. //BeginExport(function)
  2323. //DOC This function sets some particular information for RESERVATIONS only
  2324. //DOC all other stuff it just ignores and returns success..
  2325. DWORD
  2326. DhcpSetClientInfo(
  2327. IN LPWSTR ServerIpAddresess,
  2328. IN LPDHCP_CLIENT_INFO ClientInfo
  2329. ) //EndExport(function)
  2330. {
  2331. return ERROR_SUCCESS;
  2332. }
  2333. //BeginExport(function)
  2334. //DOC This function retrieves some particular client's information
  2335. //DOC for RESERVATIONS only.. For all other stuff it returns CALL_NOT_IMPLEMENTED
  2336. DWORD
  2337. DhcpGetClientInfo(
  2338. IN LPWSTR ServerIpAddress,
  2339. IN LPDHCP_SEARCH_INFO SearchInfo,
  2340. OUT LPDHCP_CLIENT_INFO *ClientInfo
  2341. ) //EndExport(function)
  2342. {
  2343. return ERROR_CALL_NOT_IMPLEMENTED;
  2344. }
  2345. //BeginExport(function)
  2346. //DOC This function sets the client informatoin for RESERVATIONS only in DS
  2347. //DOC For all toher clients it returns ERROR_SUCCESS w/o doing anything
  2348. DWORD
  2349. DhcpSetClientInfoV4(
  2350. IN LPWSTR ServerIpAddress,
  2351. IN LPDHCP_CLIENT_INFO_V4 ClientInfo
  2352. ) //EndExport(function)
  2353. {
  2354. return ERROR_SUCCESS;
  2355. }
  2356. //BeginExport(function)
  2357. //DOC Thsi function sets the client information for RESERVATIONS only
  2358. //DOC For all others it returns ERROR_CALL_NOT_IMPLEMENTED
  2359. DWORD
  2360. DhcpGetClientInfoV4(
  2361. IN LPWSTR ServerIpAddress,
  2362. IN LPDHCP_SEARCH_INFO SearchInfo,
  2363. OUT LPDHCP_CLIENT_INFO_V4 *ClientInfo
  2364. ) //EndExport(function)
  2365. {
  2366. return ERROR_CALL_NOT_IMPLEMENTED;
  2367. }
  2368. //BeginExport(function)
  2369. //DOC This function adds a subnet element to a subnet in the DS.
  2370. DWORD
  2371. DhcpAddSubnetElement(
  2372. IN LPWSTR ServerIpAddress,
  2373. IN DHCP_IP_ADDRESS SubnetAddress,
  2374. IN LPDHCP_SUBNET_ELEMENT_DATA AddElementInfo
  2375. ) //EndExport(function)
  2376. {
  2377. DWORD Err, Err2;
  2378. STORE_HANDLE hServer,hSubnet;
  2379. LPWSTR ServerName;
  2380. if( NULL == AddElementInfo ) {
  2381. return ERROR_INVALID_PARAMETER;
  2382. }
  2383. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2384. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2385. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2386. Err = GetServer(&hServer, ServerIpAddress );
  2387. if( ERROR_SUCCESS != Err ) { // get the server object
  2388. DhcpDsUnlock(&hDhcpRoot);
  2389. return Err;
  2390. }
  2391. Err = GetSubnet(&hServer, &hSubnet, SubnetAddress);
  2392. if( ERROR_SUCCESS != Err ) {
  2393. DhcpDsUnlock(&hDhcpRoot);
  2394. StoreCleanupHandle(&hServer, 0);
  2395. return Err;
  2396. }
  2397. Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
  2398. if( ERROR_SUCCESS == Err ) {
  2399. Err = AddSubnetElementOld( // now add subnet to DS
  2400. &hServer,
  2401. &hSubnet,
  2402. ServerName,
  2403. AddElementInfo
  2404. );
  2405. MemFree(ServerName);
  2406. }
  2407. StoreCleanupHandle(&hServer, 0);
  2408. StoreCleanupHandle(&hSubnet, 0);
  2409. DhcpDsUnlock(&hDhcpRoot);
  2410. return Err;
  2411. }
  2412. //BeginExport(function)
  2413. //DOC This function adds a subnet element to a subnet in the DS.
  2414. DWORD
  2415. DhcpAddSubnetElementV4(
  2416. IN LPWSTR ServerIpAddress,
  2417. IN DHCP_IP_ADDRESS SubnetAddress,
  2418. IN LPDHCP_SUBNET_ELEMENT_DATA_V4 AddElementInfo
  2419. ) //EndExport(function)
  2420. {
  2421. DWORD Err, Err2;
  2422. STORE_HANDLE hServer,hSubnet;
  2423. LPWSTR ServerName;
  2424. if( NULL == AddElementInfo ) {
  2425. return ERROR_INVALID_PARAMETER;
  2426. }
  2427. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2428. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2429. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2430. Err = GetServer(&hServer, ServerIpAddress );
  2431. if( ERROR_SUCCESS != Err ) { // get the server object
  2432. DhcpDsUnlock(&hDhcpRoot);
  2433. return Err;
  2434. }
  2435. Err = GetSubnet(&hServer, &hSubnet, SubnetAddress);
  2436. if( ERROR_SUCCESS != Err ) {
  2437. DhcpDsUnlock(&hDhcpRoot);
  2438. StoreCleanupHandle(&hServer, 0);
  2439. return Err;
  2440. }
  2441. Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
  2442. if( ERROR_SUCCESS == Err ) {
  2443. Err = AddSubnetElement( // now add subnet to DS
  2444. &hServer,
  2445. &hSubnet,
  2446. ServerName,
  2447. AddElementInfo
  2448. );
  2449. MemFree(ServerName);
  2450. }
  2451. StoreCleanupHandle(&hServer, 0);
  2452. StoreCleanupHandle(&hSubnet, 0);
  2453. DhcpDsUnlock(&hDhcpRoot);
  2454. return Err;
  2455. }
  2456. //BeginExport(function)
  2457. //DOC This is not yet implemented here..
  2458. DWORD
  2459. DhcpEnumSubnetElementsV4(
  2460. IN LPWSTR ServerIpAddress,
  2461. IN DHCP_IP_ADDRESS SubnetAddress,
  2462. IN DHCP_SUBNET_ELEMENT_TYPE EnumElementType,
  2463. IN OUT DHCP_RESUME_HANDLE *ResumeHandle,
  2464. IN DWORD PreferredMaximum,
  2465. OUT LPDHCP_SUBNET_ELEMENT_INFO_ARRAY_V4 *EnumElementInfo,
  2466. OUT DWORD *ElementsRead,
  2467. OUT DWORD *ElementsTotal
  2468. ) //EndExport(function)
  2469. {
  2470. DWORD Err, Err2;
  2471. STORE_HANDLE hServer,hSubnet;
  2472. LPWSTR ServerName;
  2473. *ElementsRead = *ElementsTotal = 0;
  2474. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2475. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2476. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2477. Err = GetServer(&hServer, ServerIpAddress );
  2478. if( ERROR_SUCCESS != Err ) { // get the server object
  2479. DhcpDsUnlock(&hDhcpRoot);
  2480. return Err;
  2481. }
  2482. Err = GetSubnet(&hServer, &hSubnet, SubnetAddress);
  2483. if( ERROR_SUCCESS != Err ) {
  2484. DhcpDsUnlock(&hDhcpRoot);
  2485. StoreCleanupHandle(&hServer, 0);
  2486. return Err;
  2487. }
  2488. Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
  2489. if( ERROR_SUCCESS == Err ) {
  2490. Err = DhcpDsEnumSubnetElements // enumerate subnet elements..
  2491. (
  2492. /* hDhcpC */ &hDhcpC,
  2493. /* hServer */ &hServer,
  2494. /* hSubnet */ &hSubnet,
  2495. /* Reserved */ DDS_RESERVED_DWORD,
  2496. /* ServerName */ ServerName,
  2497. /* ElementType */ EnumElementType,
  2498. /* EnumElementInfo */ EnumElementInfo
  2499. );
  2500. if( ERROR_SUCCESS == Err ) {
  2501. *ElementsRead = *ElementsTotal = (*EnumElementInfo)->NumElements;
  2502. }
  2503. MemFree(ServerName);
  2504. }
  2505. StoreCleanupHandle(&hServer, 0);
  2506. StoreCleanupHandle(&hSubnet, 0);
  2507. DhcpDsUnlock(&hDhcpRoot);
  2508. return Err;
  2509. }
  2510. //BeginExport(function)
  2511. //DOC This is not yet implemented here..
  2512. DWORD
  2513. DhcpEnumSubnetElements(
  2514. IN LPWSTR ServerIpAddress,
  2515. IN DHCP_IP_ADDRESS SubnetAddress,
  2516. IN DHCP_SUBNET_ELEMENT_TYPE EnumElementType,
  2517. IN OUT DHCP_RESUME_HANDLE *ResumeHandle,
  2518. IN DWORD PreferredMaximum,
  2519. OUT LPDHCP_SUBNET_ELEMENT_INFO_ARRAY *EnumElementInfo,
  2520. OUT DWORD *ElementsRead,
  2521. OUT DWORD *ElementsTotal
  2522. ) //EndExport(function)
  2523. {
  2524. DHCP_SUBNET_ELEMENT_INFO_ARRAY_V4 *pEnumElementInfoV4;
  2525. DWORD Result;
  2526. pEnumElementInfoV4 = NULL;
  2527. Result = DhcpEnumSubnetElementsV4(
  2528. ServerIpAddress,
  2529. SubnetAddress,
  2530. EnumElementType,
  2531. ResumeHandle,
  2532. PreferredMaximum,
  2533. &pEnumElementInfoV4,
  2534. ElementsRead,
  2535. ElementsTotal
  2536. );
  2537. if( ERROR_SUCCESS == Result || ERROR_MORE_DATA == Result ) {
  2538. // since the only difference between DHCP_SUBNET_ELEMENT_INFO_ARRAY_V4 and
  2539. // DHCP_SUBNET_ELEMENT_INFO_ARRAY are a couple of fields at the end of the
  2540. // embedded DHCP_IP_RESERVATION_V4 struct, it is safe to simply return the
  2541. // V4 struct.
  2542. *EnumElementInfo = ( DHCP_SUBNET_ELEMENT_INFO_ARRAY *) pEnumElementInfoV4;
  2543. } else {
  2544. DhcpAssert( !pEnumElementInfoV4 );
  2545. }
  2546. return Result;
  2547. }
  2548. //BeginExport(function)
  2549. //DOC This function removes either an exclusion, ip range or reservation
  2550. //DOC from the subnet... in the DS.
  2551. DWORD
  2552. DhcpRemoveSubnetElement( // remove subnet element
  2553. IN LPWSTR ServerIpAddress,
  2554. IN DHCP_IP_ADDRESS SubnetAddress,
  2555. IN LPDHCP_SUBNET_ELEMENT_DATA RemoveElementInfo,
  2556. IN DHCP_FORCE_FLAG ForceFlag
  2557. ) //EndExport(function)
  2558. {
  2559. DWORD Err, Err2;
  2560. STORE_HANDLE hServer,hSubnet;
  2561. LPWSTR ServerName;
  2562. if( NULL == RemoveElementInfo ) {
  2563. return ERROR_INVALID_PARAMETER;
  2564. }
  2565. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2566. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2567. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2568. Err = GetServer(&hServer, ServerIpAddress );
  2569. if( ERROR_SUCCESS != Err ) { // get the server object
  2570. DhcpDsUnlock(&hDhcpRoot);
  2571. return Err;
  2572. }
  2573. Err = GetSubnet(&hServer, &hSubnet, SubnetAddress);
  2574. if( ERROR_SUCCESS != Err ) {
  2575. DhcpDsUnlock(&hDhcpRoot);
  2576. StoreCleanupHandle(&hServer, 0);
  2577. return Err;
  2578. }
  2579. Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
  2580. if( ERROR_SUCCESS == Err ) {
  2581. Err = DelSubnetElementOld( // now del subnt elt frm DS
  2582. &hServer,
  2583. &hSubnet,
  2584. ServerName,
  2585. RemoveElementInfo
  2586. );
  2587. MemFree(ServerName);
  2588. }
  2589. StoreCleanupHandle(&hServer, 0);
  2590. StoreCleanupHandle(&hSubnet, 0);
  2591. DhcpDsUnlock(&hDhcpRoot);
  2592. return Err;
  2593. }
  2594. //BeginExport(function)
  2595. //DOC This function removes either an exclusion, ip range or reservation
  2596. //DOC from the subnet... in the DS.
  2597. DWORD
  2598. DhcpRemoveSubnetElementV4( // remove subnet element
  2599. IN LPWSTR ServerIpAddress,
  2600. IN DHCP_IP_ADDRESS SubnetAddress,
  2601. IN LPDHCP_SUBNET_ELEMENT_DATA_V4 RemoveElementInfo,
  2602. IN DHCP_FORCE_FLAG ForceFlag
  2603. ) //EndExport(function)
  2604. {
  2605. DWORD Err, Err2;
  2606. STORE_HANDLE hServer,hSubnet;
  2607. LPWSTR ServerName;
  2608. if( NULL == RemoveElementInfo ) {
  2609. return ERROR_INVALID_PARAMETER;
  2610. }
  2611. if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
  2612. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2613. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2614. Err = GetServer(&hServer, ServerIpAddress );
  2615. if( ERROR_SUCCESS != Err ) { // get the server object
  2616. DhcpDsUnlock(&hDhcpRoot);
  2617. return Err;
  2618. }
  2619. Err = GetSubnet(&hServer, &hSubnet, SubnetAddress);
  2620. if( ERROR_SUCCESS != Err ) {
  2621. DhcpDsUnlock(&hDhcpRoot);
  2622. StoreCleanupHandle(&hServer, 0);
  2623. return Err;
  2624. }
  2625. Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
  2626. if( ERROR_SUCCESS == Err ) {
  2627. Err = DelSubnetElement( // now del subnt elt frm DS
  2628. &hServer,
  2629. &hSubnet,
  2630. ServerName,
  2631. RemoveElementInfo
  2632. );
  2633. MemFree(ServerName);
  2634. }
  2635. StoreCleanupHandle(&hServer, 0);
  2636. StoreCleanupHandle(&hSubnet, 0);
  2637. DhcpDsUnlock(&hDhcpRoot);
  2638. return Err;
  2639. }
  2640. //================================================================================
  2641. // get rid of the defines so far as exports are concerned. (rpcstubs.h)
  2642. //================================================================================
  2643. //BeginExport(defines)
  2644. #ifndef CONVERT_NAMES
  2645. #undef DhcpCreateSubnet
  2646. #undef DhcpSetSubnetInfo
  2647. #undef DhcpGetSubnetInfo
  2648. #undef DhcpEnumSubnets
  2649. #undef DhcpDeleteSubnet
  2650. #undef DhcpCreateOption
  2651. #undef DhcpSetOptionInfo
  2652. #undef DhcpGetOptionInfo
  2653. #undef DhcpRemoveOption
  2654. #undef DhcpSetOptionValue
  2655. #undef DhcpGetOptionValue
  2656. #undef DhcpEnumOptionValues
  2657. #undef DhcpRemoveOptionValue
  2658. #undef DhcpEnumOptions
  2659. #undef DhcpSetOptionValues
  2660. #undef DhcpAddSubnetElementV4
  2661. #undef DhcpEnumSubnetElementsV4
  2662. #undef DhcpRemoveSubnetElementV4
  2663. #undef DhcpAddSubnetElement
  2664. #undef DhcpEnumSubnetElements
  2665. #undef DhcpRemoveSubnetElement
  2666. #undef DhcpSetSuperScopeV4
  2667. #undef DhcpGetSuperScopeInfoV4
  2668. #undef DhcpDeleteSuperScopeV4
  2669. #undef DhcpSetClientInfo
  2670. #undef DhcpGetClientInfo
  2671. #undef DhcpSetClientInfoV4
  2672. #undef DhcpGetClientInfoV4
  2673. #undef DhcpCreateOptionV5
  2674. #undef DhcpSetOptionInfoV5
  2675. #undef DhcpGetOptionInfoV5
  2676. #undef DhcpEnumOptionsV5
  2677. #undef DhcpRemoveOptionV5
  2678. #undef DhcpSetOptionValueV5
  2679. #undef DhcpSetOptionValuesV5
  2680. #undef DhcpGetOptionValueV5
  2681. #undef DhcpEnumOptionValuesV5
  2682. #undef DhcpRemoveOptionValueV5
  2683. #undef DhcpCreateClass
  2684. #undef DhcpModifyClass
  2685. #undef DhcpDeleteClass
  2686. #undef DhcpGetClassInfo
  2687. #undef DhcpEnumClasses
  2688. #undef DhcpGetAllOptions
  2689. #undef DhcpGetAllOptionValues
  2690. #endif CONVERT_NAMES
  2691. //EndExport(defines)
  2692. //BeginExport(typedef)
  2693. #define DHCP_SERVER_ANOTHER_ENTERPRISE 0x01
  2694. typedef DHCPDS_SERVER DHCP_SERVER_INFO;
  2695. typedef PDHCPDS_SERVER PDHCP_SERVER_INFO;
  2696. typedef LPDHCPDS_SERVER LPDHCP_SERVER_INFO;
  2697. typedef DHCPDS_SERVERS DHCP_SERVER_INFO_ARRAY;
  2698. typedef PDHCPDS_SERVERS PDHCP_SERVER_INFO_ARRAY;
  2699. typedef LPDHCPDS_SERVERS LPDHCP_SERVER_INFO_ARRAY;
  2700. //EndExport(typedef)
  2701. //================================================================================
  2702. // DS only NON-rpc stubs
  2703. //================================================================================
  2704. //BeginExport(function)
  2705. //DOC DhcpEnumServersDS lists the servers found in the DS along with the
  2706. //DOC addresses and other information. The whole server is allocated as a blob,
  2707. //DOC and should be freed in one shot. No parameters are currently used, other
  2708. //DOC than Servers which will be an OUT parameter only.
  2709. DWORD
  2710. DhcpEnumServersDS(
  2711. IN DWORD Flags,
  2712. IN LPVOID IdInfo,
  2713. OUT LPDHCP_SERVER_INFO_ARRAY *Servers,
  2714. IN LPVOID CallbackFn,
  2715. IN LPVOID CallbackData
  2716. ) //EndExport(function)
  2717. {
  2718. DWORD Err, Err2, Size,i;
  2719. LPDHCPDS_SERVERS DhcpDsServers;
  2720. AssertRet(Servers, ERROR_INVALID_PARAMETER);
  2721. AssertRet(!Flags, ERROR_INVALID_PARAMETER);
  2722. *Servers = NULL;
  2723. if( STUB_NOT_INITIALIZED(Err) ) return ERROR_DDS_NO_DS_AVAILABLE;
  2724. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2725. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2726. DhcpDsServers = NULL;
  2727. Err = DhcpDsEnumServers // get the list of servers
  2728. (
  2729. /* hDhcpC */ &hDhcpC,
  2730. /* hDhcpRoot */ &hDhcpRoot,
  2731. /* Reserved */ DDS_RESERVED_DWORD,
  2732. /* ServersInfo */ &DhcpDsServers
  2733. );
  2734. DhcpDsUnlock(&hDhcpRoot);
  2735. if( ERROR_SUCCESS != Err ) return Err; // return err..
  2736. *Servers = DhcpDsServers;
  2737. return ERROR_SUCCESS;
  2738. }
  2739. //BeginExport(function)
  2740. //DOC DhcpAddServerDS adds a particular server to the DS. If the server exists,
  2741. //DOC then, this returns error. If the server does not exist, then this function
  2742. //DOC adds the server in DS, and also uploads the configuration from the server
  2743. //DOC to the ds.
  2744. DWORD
  2745. DhcpAddServerDS(
  2746. IN DWORD Flags,
  2747. IN LPVOID IdInfo,
  2748. IN LPDHCP_SERVER_INFO NewServer,
  2749. IN LPVOID CallbackFn,
  2750. IN LPVOID CallbackData
  2751. ) //EndExport(function)
  2752. {
  2753. DWORD Err, Err2;
  2754. WCHAR TmpBuf[sizeof(L"000.000.000.000")];
  2755. AssertRet(NewServer, ERROR_INVALID_PARAMETER);
  2756. AssertRet(!Flags, ERROR_INVALID_PARAMETER);
  2757. if( STUB_NOT_INITIALIZED(Err) ) return ERROR_DDS_NO_DS_AVAILABLE;
  2758. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2759. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2760. Err = DhcpDsAddServer // add the new server
  2761. (
  2762. /* hDhcpC */ &hDhcpC,
  2763. /* hDhcpRoot */ &hDhcpRoot,
  2764. /* Reserved */ DDS_RESERVED_DWORD,
  2765. /* ServerName */ NewServer->ServerName,
  2766. /* ReservedPtr */ DDS_RESERVED_PTR,
  2767. /* IpAddress */ NewServer->ServerAddress,
  2768. /* State */ Flags
  2769. );
  2770. DhcpDsUnlock(&hDhcpRoot);
  2771. return Err;
  2772. }
  2773. //BeginExport(function)
  2774. //DOC DhcpDeleteServerDS deletes the servers from off the DS and recursively
  2775. //DOC deletes the server object..(i.e everything belonging to the server is deleted).
  2776. //DOC If the server does not exist, it returns an error.
  2777. DWORD
  2778. DhcpDeleteServerDS(
  2779. IN DWORD Flags,
  2780. IN LPVOID IdInfo,
  2781. IN LPDHCP_SERVER_INFO NewServer,
  2782. IN LPVOID CallbackFn,
  2783. IN LPVOID CallbackData
  2784. ) //EndExport(function)
  2785. {
  2786. DWORD Err, Err2;
  2787. AssertRet(NewServer, ERROR_INVALID_PARAMETER);
  2788. AssertRet(!Flags, ERROR_INVALID_PARAMETER);
  2789. if( STUB_NOT_INITIALIZED(Err) ) return ERROR_DDS_NO_DS_AVAILABLE;
  2790. Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
  2791. if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
  2792. Err = DhcpDsDelServer // del this server
  2793. (
  2794. /* hDhcpC */ &hDhcpC,
  2795. /* hDhcpRoot */ &hDhcpRoot,
  2796. /* Reserved */ DDS_RESERVED_DWORD,
  2797. /* ServerName */ NewServer->ServerName,
  2798. /* ReservedPtr */ DDS_RESERVED_PTR,
  2799. /* IpAddress */ NewServer->ServerAddress
  2800. );
  2801. DhcpDsUnlock(&hDhcpRoot);
  2802. return Err;
  2803. }
  2804. //BeginExport(function)
  2805. //DOC DhcpDsInitDS initializes everything in this module.
  2806. DWORD
  2807. DhcpDsInitDS(
  2808. DWORD Flags,
  2809. LPVOID IdInfo
  2810. ) //EndExport(function)
  2811. {
  2812. return StubInitialize();
  2813. }
  2814. //BeginExport(function)
  2815. //DOC DhcpDsCleanupDS uninitiailzes everything in this module.
  2816. VOID
  2817. DhcpDsCleanupDS(
  2818. VOID
  2819. ) //EndExport(function)
  2820. {
  2821. StubCleanup();
  2822. }
  2823. //BeginExport(header)
  2824. //DOC This function is defined in validate.c
  2825. //DOC Only the stub is here.
  2826. DWORD
  2827. DhcpDsValidateService( // check to validate for dhcp
  2828. IN LPWSTR Domain,
  2829. IN DWORD *Addresses OPTIONAL,
  2830. IN ULONG nAddresses,
  2831. IN LPWSTR UserName,
  2832. IN LPWSTR Password,
  2833. IN DWORD AuthFlags,
  2834. OUT LPBOOL Found,
  2835. OUT LPBOOL IsStandAlone
  2836. );
  2837. //DOC DhcpDsGetLastUpdateTime is defined in upndown.c --> see there for more details.
  2838. DWORD
  2839. DhcpDsGetLastUpdateTime( // last update time for server
  2840. IN LPWSTR ServerName, // this is server of interest
  2841. IN OUT LPFILETIME Time // fill in this w./ the time
  2842. );
  2843. //EndExport(header)
  2844. //================================================================================
  2845. // end of file
  2846. //================================================================================