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.

873 lines
38 KiB

  1. //================================================================================
  2. // Copyright (C) 1997 Microsoft Corporation
  3. // Author: RameshV
  4. // Description: This is some functionality essential for the dhcp-ds
  5. // implementation.
  6. //================================================================================
  7. //================================================================================
  8. // headers
  9. //================================================================================
  10. #include <hdrmacro.h>
  11. #include <store.h>
  12. #include <dhcpmsg.h>
  13. #include <wchar.h>
  14. //================================================================================
  15. // Constants
  16. //================================================================================
  17. //BeginExport(defines)
  18. #define DDS_RESERVED_DWORD 0
  19. #define DDS_RESERVED_PTR ((LPVOID)0)
  20. //DOC The following constants are Flag values that maybe passed to different
  21. //DOC functions.
  22. #define DDS_FLAGS_CREATE 0x01
  23. //DOC Some standard names and locations in the DS
  24. #define DHCP_ROOT_OBJECT_LOC L"CN=DhcpRoot, CN=NetServices, CN=Services"
  25. #define DHCP_ROOT_OBJECT_PARENT_LOC L"CN=NetServices, CN=Services"
  26. #define DHCP_ROOT_OBJECT_CN_NAME L"CN=DhcpRoot"
  27. #define DHCP_ROOT_OBJECT_NAME L"DhcpRoot"
  28. #define DHCP_ATTRIB_WHEN_CHANGED L"whenChanged"
  29. //DOC The attributes that are defined for the dhcp class follows.
  30. #define DHCP_ATTRIB_UNIQUE_KEY L"dhcpUniqueKey" // reqd,single,integer8
  31. #define DHCP_ATTRIB_IDENTIFICATION L"dhcpIdentification" // reqd,single,directorystring
  32. #define DHCP_ATTRIB_TYPE L"dhcpType" // reqd,single,integer
  33. #define DHCP_ATTRIB_FLAGS L"dhcpFlags" // reqd,single,integer8
  34. #define DHCP_ATTRIB_DESCRIPTION L"description" // -,mv,directorystring
  35. #define DHCP_ATTRIB_CLASSES L"dhcpClasses" // -,mv,octetstring
  36. #define DHCP_ATTRIB_MASK L"dhcpMask" // -,mv,printablestring
  37. #define DHCP_ATTRIB_OBJ_DESCRIPTION L"dhcpObjDescription" // -,single,directorystring
  38. #define DHCP_ATTRIB_OBJ_NAME L"dhcpObjName" // -,single,direcotrystring
  39. #define DHCP_ATTRIB_OPTIONS L"dhcpOptions" // -,single,octetstring
  40. #define DHCP_ATTRIB_RANGES L"dhcpRanges" // -,mv,printablestring
  41. #define DHCP_ATTRIB_RESERVATIONS L"dhcpReservations" // -,mv,printablestring
  42. #define DHCP_ATTRIB_SERVERS L"dhcpServers" // -,mv,printablestring
  43. #define DHCP_ATTRIB_STATE L"dhcpState" // -,mv,printablestring
  44. #define DHCP_ATTRIB_SUBNETS L"dhcpSubnets" // -,mv,printablestring
  45. #define DHCP_ATTRIB_LOCATION_DN L"locationDN" // -,single,dn
  46. #define DHCP_ATTRIB_MSCOPEID L"mscopeid" // -,single,printablestring
  47. #define DHCP_ATTRIB_ADDRESS L"networkAddress" // -,mv,CaseIgnoreString
  48. #define DHCP_ATTRIB_OPTIONS_LOC L"optionsLocation" // -,mv,printablestring
  49. #define DHCP_ATTRIB_OPTION_DESCRIPTION L"optionDescription" // -,mv,directorystring
  50. #define DHCP_ATTRIB_SUPERSCOPES L"superScopes" // -,mv,printablestring
  51. //DOC The following are the various types of objects recognized by the dhcp server
  52. #define DHCP_OBJ_TYPE_ROOT 0 // dhcp root object
  53. #define DHCP_OBJ_TYPE_SERVER 1 // dhcp server object
  54. #define DHCP_OBJ_TYPE_SUBNET 2 // subnet object
  55. #define DHCP_OBJ_TYPE_RANGE 3 // range object
  56. #define DHCP_OBJ_TYPE_RESERVATION 4 // reservation object
  57. #define DHCP_OBJ_TYPE_OPTION 5 // options object
  58. #define DHCP_OBJ_TYPE_CLASS 6 // class object
  59. #define DHCP_OBJ_TYPE_ROOT_DESC L"DHCP Root object"
  60. #define DHCP_OBJ_TYPE_SERVER_DESC L"DHCP Server object"
  61. #define DHCP_OBJ_TYPE_SUBNET_DESC L"Dhcp Subnet object"
  62. #define DHCP_OBJ_TYPE_RANGE_DESC L"Dhcp Range object"
  63. #define DHCP_OBJ_TYPE_RESERVATION_DESC L"Dhcp Reservation object"
  64. #define DHCP_OBJ_TYPE_OPTION_DESC L"Dhcp Option object"
  65. #define DHCP_OBJ_TYPE_CLASS_DESC L"Dhcp Class object"
  66. //DOC The following defines are bitmasks and bits in various flags..
  67. //DOC The flag2 portion of Ranges key is used for differntiating between exclusions and ranges
  68. #define RANGE_TYPE_RANGE 0
  69. #define RANGE_TYPE_EXCL 1
  70. #define RANGE_TYPE_MASK (0x1)
  71. //EndExport(defines)
  72. //================================================================================
  73. // functions
  74. //================================================================================
  75. //BeginExport(function)
  76. //DOC DhcpDsGetDhcpC gets the dhcp container in the DS.. This is usually the
  77. //DOC container CN=Netservices,CN=Services,CN=Configuration etc..
  78. //DOC This is used in many functions, so it is useful to have a central function..
  79. //DOC
  80. DWORD
  81. DhcpDsGetDhcpC( // get dhcp container
  82. IN DWORD Reserved, // future use
  83. IN OUT LPSTORE_HANDLE hStoreCC, // config container handle
  84. OUT LPSTORE_HANDLE hDhcpC // output dhcp container handle
  85. ) //EndExport(function)
  86. {
  87. DWORD Result, Result2;
  88. STORE_HANDLE TmpHandle;
  89. if( NULL == hStoreCC || NULL == hDhcpC )
  90. return ERROR_INVALID_PARAMETER;
  91. if( 0 != Reserved )
  92. return ERROR_INVALID_PARAMETER;
  93. Result = StoreGetHandle(
  94. /* hStore */ hStoreCC,
  95. /* Reserved */ DDS_RESERVED_DWORD,
  96. /* StoreGetType */ StoreGetChildType,
  97. /* Path */ DHCP_ROOT_OBJECT_PARENT_LOC,
  98. /* hStoreOut */ hDhcpC
  99. );
  100. return Result;
  101. }
  102. //BeginExport(function)
  103. //DOC DhcpDsGetRoot gets the dhcp root object given to the configuration container
  104. //DOC This is usually CN=DhcpRoot,CN=NetServices,CN=Services,CN=Configuration...
  105. //DOC If Flags has the DDS_FLAGS_CREATE bit set, then the root object is created.
  106. //DOC Return Values:
  107. //DOC Store any returns returned by the Store module
  108. //DOC ERROR_DDS_NO_DHCP_ROOT no DhcpRoot object found
  109. //DOC ERROR_DDS_UNEXPECTED_ERROR the DhcpRoot's parent container not found..
  110. // in this case GetLastError returns ADS error
  111. DWORD
  112. DhcpDsGetRoot(
  113. IN DWORD Flags, // 0 or DDS_FLAGS_CREATE
  114. IN OUT LPSTORE_HANDLE hStoreCC, // configuration container handle
  115. OUT LPSTORE_HANDLE hStoreDhcpRoot // dhcp root object handle
  116. ) //EndExport(function)
  117. {
  118. DWORD Result, Result2;
  119. STORE_HANDLE TmpHandle;
  120. SetLastError(NO_ERROR);
  121. if( NULL == hStoreCC || NULL == hStoreDhcpRoot )
  122. return ERROR_INVALID_PARAMETER;
  123. if( 0 != Flags && DDS_FLAGS_CREATE != Flags )
  124. return ERROR_INVALID_PARAMETER;
  125. Result = StoreGetHandle(
  126. /* hStore */ hStoreCC,
  127. /* Reserved */ DDS_RESERVED_DWORD,
  128. /* StoreGetType */ StoreGetChildType,
  129. /* Path */ DHCP_ROOT_OBJECT_LOC,
  130. /* hStoreOut */ hStoreDhcpRoot
  131. );
  132. if( ERROR_SUCCESS == Result ) return ERROR_SUCCESS;
  133. if( DDS_FLAGS_CREATE != Flags && ERROR_DS_NO_SUCH_OBJECT != Result ) {
  134. //- MajorFunctionFailure(StoreGetHandle, Result, DHCP_ROOT_OBJECT_LOC);
  135. SetLastError(Result);
  136. return Result;
  137. }
  138. //= DDS_FLAGS_CREATE == Flags && ERROR_DS_NO_SUCH_OBJECT == Result
  139. Result = StoreGetHandle(
  140. /* hStore */ hStoreCC,
  141. /* Reserved */ DDS_RESERVED_DWORD,
  142. /* StoreGetType */ StoreGetChildType,
  143. /* Path */ DHCP_ROOT_OBJECT_PARENT_LOC,
  144. /* hStoreOut */ &TmpHandle
  145. );
  146. if( ERROR_SUCCESS != Result ) {
  147. SetLastError(Result);
  148. return ERROR_DDS_UNEXPECTED_ERROR;
  149. }
  150. if( DDS_FLAGS_CREATE != Flags ) {
  151. //
  152. // Could open the config\services\netservices container, but
  153. // can't open the dhcproot object. Most likely the dhcproot
  154. // object ain't there.
  155. //
  156. Result2 = StoreCleanupHandle( &TmpHandle, DDS_RESERVED_DWORD );
  157. //= ERROR_SUCCESS == Result2
  158. SetLastError(ERROR_DS_NO_SUCH_OBJECT);
  159. return ERROR_DDS_NO_DHCP_ROOT;
  160. }
  161. Result = StoreCreateObject(
  162. /* hStore */ &TmpHandle,
  163. /* Reserved */ DDS_RESERVED_DWORD,
  164. /* NewObjName */ DHCP_ROOT_OBJECT_CN_NAME,
  165. /* ... */
  166. /* Identification */
  167. ADSTYPE_DN_STRING, ATTRIB_DN_NAME, DHCP_ROOT_OBJECT_NAME,
  168. ADSTYPE_DN_STRING, ATTRIB_OBJECT_CLASS, DEFAULT_DHCP_CLASS_ATTRIB_VALUE,
  169. /* systemMustContain */
  170. ADSTYPE_INTEGER, ATTRIB_DHCP_UNIQUE_KEY, 0,
  171. ADSTYPE_INTEGER, ATTRIB_DHCP_TYPE, 0,
  172. ADSTYPE_DN_STRING, ATTRIB_DHCP_IDENTIFICATION, L"This is a server",
  173. ADSTYPE_INTEGER, ATTRIB_DHCP_FLAGS, 0,
  174. ADSTYPE_INTEGER, ATTRIB_INSTANCE_TYPE, DEFAULT_INSTANCE_TYPE_ATTRIB_VALUE,
  175. /* terminator */
  176. ADSTYPE_INVALID
  177. );
  178. Result2 = StoreCleanupHandle( &TmpHandle, DDS_RESERVED_DWORD );
  179. //= ERROR_SUCCESS == Result2
  180. if( ERROR_SUCCESS != Result ) {
  181. //- MinorFunctionFailure(StoreCleanupHandle, Result)
  182. return Result;
  183. }
  184. return DhcpDsGetRoot( Flags & ~DDS_FLAGS_CREATE, hStoreCC, hStoreDhcpRoot);
  185. }
  186. //BeginExport(function)
  187. //DOC DhcpDsGetLists function retrives a list of attributes and adds it the given array
  188. //DOC allocating each element separateley, and traversing any pointers indicated by
  189. //DOC the value of the attribute.
  190. //DOC Note that even in case of error, the array may still contain some elements.
  191. //DOC This is a best effort even in case of failure.
  192. //DOC Each element of the array must be freed via MemFree, and the array itself
  193. //DOC must be cleaned up via MemArrayCleanup.
  194. //DOC Note that any of the PARRAY type parameters may be NULL, as they are optional.
  195. //DOC but reading these separately is highly inefficient...
  196. //DOC Return Values:
  197. //DOC ERROR_DDS_UNEXPECTED_ERROR some entirely unexpected error
  198. //DOC ERROR_DDS_TOO_MANY_ERRORS multiple errors occured, and was caught
  199. //DOC Store any errors returned by the store apis
  200. DWORD
  201. DhcpDsGetLists( // get list of different objects
  202. IN DWORD Reserved, // must be zero -- for future use
  203. IN OUT LPSTORE_HANDLE hStore, // the object to get the lists for
  204. IN DWORD RecursionDepth,// how much nesting allowed? 0 ==> one level only
  205. IN OUT PARRAY Servers, // <Name,Description,IpAddress,State,Location>
  206. IN OUT PARRAY Subnets, // <Name,Description,IpAddress,Mask,State,Location>
  207. IN OUT PARRAY IpAddress, // <Name,Description,IpAddress,State,Location>
  208. IN OUT PARRAY Mask, // <Name,Description,IpAddress,State,Location>
  209. IN OUT PARRAY Ranges, // <Name,Description,IpAddress1,IpAddress2,State,Location>
  210. IN OUT PARRAY Sites, // dont know what this looks like now
  211. IN OUT PARRAY Reservations, // <Name,Description,IpAddress,State,Location>
  212. IN OUT PARRAY SuperScopes, // <Name,Description,State,DWORD, Location>
  213. //IN PARRAY SuperScopesDescription, // UNUSED
  214. IN OUT PARRAY OptionDescription, // <options definition>
  215. IN OUT PARRAY OptionsLocation, // <Location>
  216. IN OUT PARRAY Options, // xxx <Name, Description, String1=HexStream>
  217. IN OUT PARRAY Classes // xxx <Name, Description, String1=HexStream>
  218. ) //EndExport(function)
  219. {
  220. DWORD Result;
  221. DWORD LastError;
  222. if( 0 != Reserved ) return ERROR_INVALID_PARAMETER;
  223. if( NULL == hStore || NULL == hStore->ADSIHandle ) return ERROR_INVALID_PARAMETER;
  224. LastError = ERROR_SUCCESS;
  225. if( NULL != Servers ) {
  226. Result = StoreCollectAttributes(
  227. /* hStore */ hStore,
  228. /* Reserved */ DDS_RESERVED_DWORD,
  229. /* AttribName */ DHCP_ATTRIB_SERVERS,
  230. /* ArrayToAddTo */ Servers,
  231. /* RecursionDepth */ RecursionDepth
  232. );
  233. if( ERROR_SUCCESS != Result ) LastError = Result;
  234. }
  235. if( NULL != Subnets ) {
  236. Result = StoreCollectAttributes(
  237. /* hStore */ hStore,
  238. /* Reserved */ DDS_RESERVED_DWORD,
  239. /* AttribName */ DHCP_ATTRIB_SUBNETS,
  240. /* ArrayToAddTo */ Subnets,
  241. /* RecursionDepth */ RecursionDepth
  242. );
  243. if( ERROR_SUCCESS != Result ) LastError = Result;
  244. }
  245. if( NULL != IpAddress ) {
  246. Result = StoreCollectAttributes(
  247. /* hStore */ hStore,
  248. /* Reserved */ DDS_RESERVED_DWORD,
  249. /* AttribName */ DHCP_ATTRIB_ADDRESS,
  250. /* ArrayToAddTo */ IpAddress,
  251. /* RecursionDepth */ RecursionDepth
  252. );
  253. if( ERROR_SUCCESS != Result ) LastError = Result;
  254. }
  255. if( NULL != Mask ) {
  256. Result = StoreCollectAttributes(
  257. /* hStore */ hStore,
  258. /* Reserved */ DDS_RESERVED_DWORD,
  259. /* AttribName */ DHCP_ATTRIB_MASK,
  260. /* ArrayToAddTo */ Mask,
  261. /* RecursionDepth */ RecursionDepth
  262. );
  263. if( ERROR_SUCCESS != Result ) LastError = Result;
  264. }
  265. if( NULL != Ranges ) {
  266. Result = StoreCollectAttributes(
  267. /* hStore */ hStore,
  268. /* Reserved */ DDS_RESERVED_DWORD,
  269. /* AttribName */ DHCP_ATTRIB_RANGES,
  270. /* ArrayToAddTo */ Ranges,
  271. /* RecursionDepth */ RecursionDepth
  272. );
  273. if( ERROR_SUCCESS != Result ) LastError = Result;
  274. }
  275. if( NULL != Sites ) {
  276. // ignored for now
  277. }
  278. if( NULL != Reservations ) {
  279. Result = StoreCollectAttributes(
  280. /* hStore */ hStore,
  281. /* Reserved */ DDS_RESERVED_DWORD,
  282. /* AttribName */ DHCP_ATTRIB_RESERVATIONS,
  283. /* ArrayToAddTo */ Reservations,
  284. /* RecursionDepth */ RecursionDepth
  285. );
  286. if( ERROR_SUCCESS != Result ) LastError = Result;
  287. }
  288. if( NULL != SuperScopes ) {
  289. Result = StoreCollectAttributes(
  290. /* hStore */ hStore,
  291. /* Reserved */ DDS_RESERVED_DWORD,
  292. /* AttribName */ DHCP_ATTRIB_SUPERSCOPES,
  293. /* ArrayToAddTo */ SuperScopes,
  294. /* RecursionDepth */ RecursionDepth
  295. );
  296. if( ERROR_SUCCESS != Result ) LastError = Result;
  297. }
  298. if( NULL != OptionsLocation ) {
  299. Result = StoreCollectAttributes(
  300. /* hStore */ hStore,
  301. /* Reserved */ DDS_RESERVED_DWORD,
  302. /* AttribName */ DHCP_ATTRIB_OPTIONS_LOC,
  303. /* ArrayToAddTo */ OptionsLocation,
  304. /* RecursionDepth */ RecursionDepth
  305. );
  306. if( ERROR_SUCCESS != Result ) LastError = Result;
  307. }
  308. if( NULL != OptionDescription ) {
  309. Result = StoreCollectAttributes(
  310. /* hStore */ hStore,
  311. /* Reserved */ DDS_RESERVED_DWORD,
  312. /* AttribName */ DHCP_ATTRIB_OPTION_DESCRIPTION,
  313. /* ArrayToAddTo */ OptionDescription,
  314. /* RecursionDepth */ RecursionDepth
  315. );
  316. if( ERROR_SUCCESS != Result ) LastError = Result;
  317. }
  318. if( NULL != Options ) {
  319. Result = StoreCollectBinaryAttributes(
  320. /* hStore */ hStore,
  321. /* Reserved */ DDS_RESERVED_DWORD,
  322. /* AttribName */ DHCP_ATTRIB_OPTIONS,
  323. /* ArrayToAddTo */ Options,
  324. /* RecursionDepth */ RecursionDepth
  325. );
  326. if( ERROR_SUCCESS != Result ) LastError = Result;
  327. }
  328. if( NULL != Classes ) {
  329. Result = StoreCollectBinaryAttributes(
  330. /* hStore */ hStore,
  331. /* Reserved */ DDS_RESERVED_DWORD,
  332. /* AttribName */ DHCP_ATTRIB_CLASSES,
  333. /* ArrayToAddTo */ Classes,
  334. /* RecursionDepth */ RecursionDepth
  335. );
  336. if( ERROR_SUCCESS != Result ) LastError = Result;
  337. }
  338. return LastError;
  339. }
  340. //DOC Clonestring just allocates memory for the string and copies it over and returns
  341. //DOC that.
  342. LPWSTR
  343. CloneString(
  344. IN LPWSTR Str
  345. )
  346. {
  347. LPWSTR RetVal;
  348. if( NULL == Str ) return NULL;
  349. RetVal = MemAlloc( sizeof(WCHAR)*(1+wcslen(Str)));
  350. if( NULL != RetVal ) wcscpy(RetVal, Str);
  351. return RetVal;
  352. }
  353. //DOC MarkFoundParam marks the given argno as found (converse of DhcpCheckParams )
  354. VOID _inline
  355. MarkFoundParam(
  356. IN OUT DWORD *FoundParams,
  357. IN DWORD ArgNo
  358. )
  359. {
  360. (*FoundParams) |= (1 << ArgNo);
  361. }
  362. //BeginExport(function)
  363. //DOC DhcpDsGetAttribs retreives all the miscellaneous attributes (whichever is requested) and
  364. //DOC returns it as XXX_TYPE parameter. These parameters are allocated within this function
  365. //DOC using MemAlloc and must be freed via MemFree. Any of the parameters maybe NULL indicating
  366. //DOC lack of interest in that attribute. (Note that the following parameters are NOT allocated:
  367. //DOC they are just filled in: UniqueKey, Type, Flags, MScopeId, FoundParams)
  368. //DOC Note that some of the parameters may not be found, but this can be checked against the
  369. //DOC value returned in FoundParams (which is a REQUIRED parameter) using the FOUND_ARG(FoundParams,Arg#)
  370. //DOC where the Args are numbered from 0 starting at UniqueKey..
  371. //DOC Return Values:
  372. //DOC ERROR_DDS_UNEXPECTED_ERROR some entirely unexpected error
  373. //DOC ERROR_DDS_TOO_MANY_ERRORS multiple errors occured, and was caught
  374. //DOC Store any errors returned by the store apis
  375. DWORD
  376. DhcpDsGetAttribs( // get list of attributes
  377. IN DWORD Reserved, // must be zero -- for future use
  378. IN OUT LPSTORE_HANDLE hStore,
  379. IN OUT DWORD *FoundParams, // which of the following params was found?
  380. IN OUT LARGE_INTEGER *UniqueKey, // fill in an unique key
  381. IN OUT DWORD *Type, // object type
  382. IN OUT LARGE_INTEGER *Flags, // additional info about the object
  383. IN OUT LPWSTR *Name, // Allocated, name of object
  384. IN OUT LPWSTR *Description, // Allocated, something that describes this object
  385. IN OUT LPWSTR *Location, // the reference location from which to do other stuff
  386. IN OUT DWORD *MScopeId // what is the scope id used?
  387. ) //EndExport(function)
  388. {
  389. HRESULT hResult;
  390. DWORD i;
  391. DWORD nAttribs, nAttributes;
  392. LPWSTR Attribs[10]; // atmost 10 attribs are defined now...
  393. PADS_ATTR_INFO Attributes;
  394. if( Reserved != 0 ) return ERROR_INVALID_PARAMETER;
  395. if( NULL == FoundParams ) return ERROR_INVALID_PARAMETER;
  396. if( NULL == hStore || NULL == hStore->ADSIHandle ) return ERROR_INVALID_PARAMETER;
  397. *FoundParams = 0; // nothing has been found yet.
  398. nAttribs = 0;
  399. if( UniqueKey ) Attribs[nAttribs++] = DHCP_ATTRIB_UNIQUE_KEY;
  400. if( Type ) Attribs[nAttribs++] = DHCP_ATTRIB_TYPE;
  401. if( Flags ) Attribs[nAttribs++] = DHCP_ATTRIB_FLAGS;
  402. if( Name ) Attribs[nAttribs++] = DHCP_ATTRIB_OBJ_NAME;
  403. if( Description ) Attribs[nAttribs++] = DHCP_ATTRIB_OBJ_DESCRIPTION;
  404. if( Location ) Attribs[nAttribs++] = DHCP_ATTRIB_LOCATION_DN;
  405. if( MScopeId ) Attribs[nAttribs++] = DHCP_ATTRIB_MSCOPEID;
  406. if( 0 == nAttribs ) return ERROR_INVALID_PARAMETER;
  407. Attributes = NULL; nAttributes = 0;
  408. hResult = ADSIGetObjectAttributes(
  409. /* hDSObject */ hStore->ADSIHandle,
  410. /* pAttributeNames */ Attribs,
  411. /* dwNumberAttributes */ nAttribs,
  412. /* ppAttributeEntries */ &Attributes,
  413. /* pdwNumAttributesReturned */ &nAttributes
  414. );
  415. // hResult can be E_ADS_LDAP_NO_SUCH_ATTRIBUTE if only one attrib was asked for..
  416. if( FAILED(hResult) ) return ERROR_DDS_UNEXPECTED_ERROR;
  417. if( 0 == nAttributes ) {
  418. if( Attributes ) FreeADsMem(Attributes);
  419. return ERROR_DDS_UNEXPECTED_ERROR;
  420. }
  421. for( i = 0; i < nAttributes ; i ++ ) {
  422. if( ADSTYPE_INVALID == Attributes[i].dwADsType )
  423. continue; //?? should not really happen
  424. if( 0 == Attributes[i].dwNumValues ) //?? this should not happen either
  425. continue;
  426. if( 0 == wcscmp(Attributes[i].pszAttrName, DHCP_ATTRIB_UNIQUE_KEY ) ) {
  427. if( ADSTYPE_LARGE_INTEGER != Attributes[i].pADsValues[0].dwType )
  428. continue; //?? should not happen
  429. *UniqueKey = Attributes[i].pADsValues[0].LargeInteger;
  430. MarkFoundParam(FoundParams, 0);
  431. continue;
  432. }
  433. if( 0 == wcscmp(Attributes[i].pszAttrName, DHCP_ATTRIB_TYPE ) ) {
  434. if( ADSTYPE_INTEGER != Attributes[i].pADsValues[0].dwType )
  435. continue; //?? should not happen
  436. *Type = Attributes[i].pADsValues[0].Integer;
  437. MarkFoundParam(FoundParams, 1);
  438. continue;
  439. }
  440. if( 0 == wcscmp(Attributes[i].pszAttrName, DHCP_ATTRIB_FLAGS ) ) {
  441. if( ADSTYPE_LARGE_INTEGER != Attributes[i].pADsValues[0].dwType )
  442. continue; //?? should not happen
  443. *Flags = Attributes[i].pADsValues[0].LargeInteger;
  444. MarkFoundParam(FoundParams, 2);
  445. continue;
  446. }
  447. if( 0 == wcscmp(Attributes[i].pszAttrName, DHCP_ATTRIB_OBJ_NAME ) ) {
  448. if( ADSTYPE_CASE_IGNORE_STRING != Attributes[i].pADsValues[0].dwType )
  449. continue; //?? should not happen
  450. *Name = CloneString(Attributes[i].pADsValues[0].CaseIgnoreString);
  451. MarkFoundParam(FoundParams, 3);
  452. continue;
  453. }
  454. if( 0 == wcscmp(Attributes[i].pszAttrName, DHCP_ATTRIB_OBJ_DESCRIPTION ) ) {
  455. if( ADSTYPE_CASE_IGNORE_STRING != Attributes[i].pADsValues[0].dwType )
  456. continue; //?? should not happen
  457. *Description = CloneString(Attributes[i].pADsValues[0].CaseIgnoreString);
  458. MarkFoundParam(FoundParams, 4);
  459. continue;
  460. }
  461. if( 0 == wcscmp(Attributes[i].pszAttrName, DHCP_ATTRIB_LOCATION_DN ) ) {
  462. if( ADSTYPE_DN_STRING != Attributes[i].pADsValues[0].dwType )
  463. continue; //?? should not happen
  464. *Location = CloneString(Attributes[i].pADsValues[0].CaseIgnoreString);
  465. MarkFoundParam(FoundParams, 5);
  466. continue;
  467. }
  468. if( 0 == wcscmp(Attributes[i].pszAttrName, DHCP_ATTRIB_MSCOPEID ) ) {
  469. if( ADSTYPE_PRINTABLE_STRING != Attributes[i].pADsValues[0].dwType )
  470. continue; //?? should not happen
  471. *MScopeId = _wtol(Attributes[i].pADsValues[0].PrintableString);
  472. MarkFoundParam(FoundParams, 6);
  473. continue;
  474. }
  475. }
  476. FreeADsMem(Attributes);
  477. return ERROR_SUCCESS;
  478. }
  479. //BeginExport(inline)
  480. //DOC DhcpCheckParams checks to see if the argument numbered (ArgNo) was found
  481. //DOC as marked in the bitmap FoundParams. Essentially used by the DhcpDsGetAttribs function only.
  482. //DOC Return Values:
  483. BOOL _inline
  484. DhcpCheckParams( // check to see if requested param was returned
  485. IN DWORD FoundParams,
  486. IN DWORD ArgNo
  487. )
  488. {
  489. if( ArgNo > sizeof(FoundParams)*8 ) return FALSE;
  490. return ((FoundParams) & (1 << ArgNo) )?TRUE:FALSE;
  491. }
  492. //EndExport(inline)
  493. //BeginExport(function)
  494. //DOC DhcpDsSetLists function sets the various list of attributes to the values given.
  495. //DOC it walks the arrays and encapsulates the arrays.
  496. //DOC Note that in case of error, this function returns immediately.
  497. //DOC In case of error, pl check the SetParams parameter with the CheckParams function
  498. //DOC to determine which parameters were set... (no order guarantee is made for setting
  499. //DOC the parameters).
  500. //DOC Any PARRAY parameter may be omitted if it is not required to be modified.
  501. //DOC SetParams is REQUIRED to be present. See the discussion in DhcpDsGetAttribs for
  502. //DOC the meaning of this parameter.
  503. //DOC Return Values:
  504. //DOC ERROR_DDS_UNEXPECTED_ERROR something bad happened
  505. //DOC ERROR_DDS_TOO_MANY_ERRORS too many simple errors
  506. //DOC Store any errors returned by the store module
  507. DWORD
  508. DhcpDsSetLists( // set the list of attributes after encapsulating them
  509. IN DWORD Reserved, // must be zero -- for future use
  510. IN OUT LPSTORE_HANDLE hStore, // the object to get the lists for
  511. IN OUT LPDWORD SetParams, // which of the following params got modified really?
  512. IN PARRAY Servers, // <Name,Description,IpAddress,State,Location>
  513. IN PARRAY Subnets, // <Name,Description,IpAddress,Mask,State,Location>
  514. IN PARRAY IpAddress, // <Name,Description,IpAddress,State,Location>
  515. IN PARRAY Mask, // <Name,Description,IpAddress,State,Location>
  516. IN PARRAY Ranges, // <Name,Description,IpAddress1,IpAddress2,State,Location>
  517. IN PARRAY Sites, // dont know what this looks like now
  518. IN PARRAY Reservations, // <Name,Description,IpAddress,State,Location>
  519. IN PARRAY SuperScopes, // <Name,Description,State,DWORD, Location>
  520. //IN PARRAY SuperScopesDescription, // UNUSED
  521. IN PARRAY OptionDescription, // option definitions..
  522. IN PARRAY OptionsLocation, // <Location>
  523. IN PARRAY Options, // xxx <Name, Description, String1=HexStream>
  524. IN PARRAY ClassDescription, // <Name, Description, String, Location>
  525. IN PARRAY Classes // xxx <Name, Description, String1=HexStream>
  526. ) //EndExport(function)
  527. {
  528. DWORD Result;
  529. DWORD LastError;
  530. DWORD ArgNo;
  531. if( 0 != Reserved ) return ERROR_INVALID_PARAMETER;
  532. if( NULL == hStore || NULL == hStore->ADSIHandle ) return ERROR_INVALID_PARAMETER;
  533. if( NULL == SetParams ) return ERROR_INVALID_PARAMETER;
  534. LastError = ERROR_SUCCESS;
  535. ArgNo = 0;
  536. if( NULL != Servers ) {
  537. Result = StoreUpdateAttributes(
  538. /* hStore */ hStore,
  539. /* Reserved */ DDS_RESERVED_DWORD,
  540. /* AttribName */ DHCP_ATTRIB_SERVERS,
  541. /* ArrayToWrite */ Servers
  542. );
  543. if( ERROR_SUCCESS != Result ) LastError = Result;
  544. else MarkFoundParam(SetParams, ArgNo);
  545. }
  546. ArgNo ++;
  547. if( NULL != Subnets ) {
  548. Result = StoreUpdateAttributes(
  549. /* hStore */ hStore,
  550. /* Reserved */ DDS_RESERVED_DWORD,
  551. /* AttribName */ DHCP_ATTRIB_SUBNETS,
  552. /* ArrayToWrite */ Subnets
  553. );
  554. if( ERROR_SUCCESS != Result ) LastError = Result;
  555. else MarkFoundParam(SetParams, ArgNo);
  556. }
  557. ArgNo ++;
  558. if( NULL != IpAddress ) {
  559. Result = StoreUpdateAttributes(
  560. /* hStore */ hStore,
  561. /* Reserved */ DDS_RESERVED_DWORD,
  562. /* AttribName */ DHCP_ATTRIB_ADDRESS,
  563. /* ArrayToWrite */ IpAddress
  564. );
  565. if( ERROR_SUCCESS != Result ) LastError = Result;
  566. else MarkFoundParam(SetParams, ArgNo);
  567. }
  568. ArgNo ++;
  569. if( NULL != Mask ) {
  570. Result = StoreUpdateAttributes(
  571. /* hStore */ hStore,
  572. /* Reserved */ DDS_RESERVED_DWORD,
  573. /* AttribName */ DHCP_ATTRIB_MASK,
  574. /* ArrayToWrite */ Mask
  575. );
  576. if( ERROR_SUCCESS != Result ) LastError = Result;
  577. else MarkFoundParam(SetParams, ArgNo);
  578. }
  579. ArgNo ++;
  580. if( NULL != Ranges ) {
  581. Result = StoreUpdateAttributes(
  582. /* hStore */ hStore,
  583. /* Reserved */ DDS_RESERVED_DWORD,
  584. /* AttribName */ DHCP_ATTRIB_RANGES,
  585. /* ArrayToWrite */ Ranges
  586. );
  587. if( ERROR_SUCCESS != Result ) LastError = Result;
  588. else MarkFoundParam(SetParams, ArgNo);
  589. }
  590. ArgNo ++;
  591. if( NULL != Sites ) {
  592. // ignored for now
  593. MarkFoundParam(SetParams, ArgNo);
  594. }
  595. ArgNo ++;
  596. if( NULL != Reservations ) {
  597. Result = StoreUpdateAttributes(
  598. /* hStore */ hStore,
  599. /* Reserved */ DDS_RESERVED_DWORD,
  600. /* AttribName */ DHCP_ATTRIB_RESERVATIONS,
  601. /* ArrayToWrite */ Reservations
  602. );
  603. if( ERROR_SUCCESS != Result ) LastError = Result;
  604. else MarkFoundParam(SetParams, ArgNo);
  605. }
  606. ArgNo ++;
  607. if( NULL != SuperScopes ) {
  608. Result = StoreUpdateAttributes(
  609. /* hStore */ hStore,
  610. /* Reserved */ DDS_RESERVED_DWORD,
  611. /* AttribName */ DHCP_ATTRIB_SUPERSCOPES,
  612. /* ArrayToWrite */ SuperScopes
  613. );
  614. if( ERROR_SUCCESS != Result ) LastError = Result;
  615. else MarkFoundParam(SetParams, ArgNo);
  616. }
  617. ArgNo ++;
  618. if( NULL != OptionsLocation ) {
  619. Result = StoreUpdateAttributes(
  620. /* hStore */ hStore,
  621. /* Reserved */ DDS_RESERVED_DWORD,
  622. /* AttribName */ DHCP_ATTRIB_OPTIONS_LOC,
  623. /* ArrayToWrite */ OptionsLocation
  624. );
  625. if( ERROR_SUCCESS != Result ) LastError = Result;
  626. else MarkFoundParam(SetParams, ArgNo);
  627. }
  628. ArgNo ++;
  629. if( NULL != OptionDescription ) {
  630. Result = StoreUpdateAttributes(
  631. /* hStore */ hStore,
  632. /* Reserved */ DDS_RESERVED_DWORD,
  633. /* AttribName */ DHCP_ATTRIB_OPTION_DESCRIPTION,
  634. /* ArrayToWrite */ OptionDescription
  635. );
  636. if( ERROR_SUCCESS != Result ) LastError = Result;
  637. else MarkFoundParam(SetParams, ArgNo);
  638. }
  639. ArgNo ++;
  640. if( NULL != Options ) {
  641. Result = StoreUpdateBinaryAttributes(
  642. /* hStore */ hStore,
  643. /* Reserved */ DDS_RESERVED_DWORD,
  644. /* AttribName */ DHCP_ATTRIB_OPTIONS,
  645. /* ArrayToWrite */ Options
  646. );
  647. if( ERROR_SUCCESS != Result ) LastError = Result;
  648. else MarkFoundParam(SetParams, ArgNo);
  649. }
  650. ArgNo ++;
  651. if( NULL != Classes ) {
  652. Result = StoreUpdateBinaryAttributes(
  653. /* hStore */ hStore,
  654. /* Reserved */ DDS_RESERVED_DWORD,
  655. /* AttribName */ DHCP_ATTRIB_CLASSES,
  656. /* ArrayToWrite */ Classes
  657. );
  658. if( ERROR_SUCCESS != Result ) LastError = Result;
  659. else MarkFoundParam(SetParams, ArgNo);
  660. }
  661. return LastError;
  662. }
  663. //BeginExport(function)
  664. //DOC DhcpDsSetAttribs sets the miscellaneous single-valued attributes. Any of the attributes
  665. //DOC may be omitted if not required to be set. (In this case they must be set to NULL).
  666. //DOC SetParams contains the information on which parameters were actually modified.
  667. //DOC See DhcpDsGetAttribs on using this parameter.
  668. //DOC Return Values:
  669. //DOC ERROR_DDS_UNEXPECTED_ERROR something unexpected
  670. //DOC Store any errors returned by the Store APIs
  671. DWORD
  672. DhcpDsSetAttribs( // set these attributes
  673. IN DWORD Reserved, // must be zero -- for future use
  674. IN OUT LPSTORE_HANDLE hStore, // the object to set the attributes
  675. IN OUT DWORD *SetParams, // which of the following params were actually modified?
  676. IN OUT LARGE_INTEGER *UniqueKey, // fill in an unique key
  677. IN OUT DWORD *Type, // object type
  678. IN OUT LPWSTR *Name, // Allocated, name of object
  679. IN OUT LPWSTR *Description, // Allocated, something that describes this object
  680. IN OUT LPWSTR *Location, // the reference location from which to do other stuff
  681. IN OUT DWORD *MScopeId // what is the scope id used?
  682. ) //EndExport(function)
  683. {
  684. DWORD Result, nAttributes, i, ArgNo;
  685. HRESULT hResult;
  686. ADS_ATTR_INFO Attributes[10];
  687. ADSVALUE Values[10];
  688. WCHAR MScopeIdString[20];
  689. if( NULL == hStore || NULL == hStore->ADSIHandle )
  690. return ERROR_INVALID_PARAMETER;
  691. i = ArgNo = 0;
  692. if( UniqueKey ) { // this attribute is present
  693. Attributes[i].pszAttrName = DHCP_ATTRIB_UNIQUE_KEY;
  694. Attributes[i].dwControlCode = ADS_ATTR_UPDATE;
  695. Attributes[i].dwADsType = ADSTYPE_LARGE_INTEGER;
  696. Attributes[i].dwNumValues = 1;
  697. Attributes[i].pADsValues = &Values[i];
  698. Attributes[i].pADsValues[0].dwType = ADSTYPE_LARGE_INTEGER;
  699. Attributes[i].pADsValues[0].LargeInteger = *UniqueKey;
  700. MarkFoundParam(SetParams,ArgNo);
  701. i ++;
  702. }
  703. ArgNo ++;
  704. if( Type ) { // this attribute is present
  705. Attributes[i].pszAttrName = DHCP_ATTRIB_TYPE;
  706. Attributes[i].dwControlCode = ADS_ATTR_UPDATE;
  707. Attributes[i].dwADsType = ADSTYPE_INTEGER;
  708. Attributes[i].dwNumValues = 1;
  709. Attributes[i].pADsValues = &Values[i];
  710. Attributes[i].pADsValues[0].dwType = ADSTYPE_INTEGER;
  711. Attributes[i].pADsValues[0].Integer = *Type;
  712. MarkFoundParam(SetParams,ArgNo);
  713. i ++;
  714. }
  715. ArgNo ++;
  716. if( Name ) { // this attribute is present
  717. Attributes[i].pszAttrName = DHCP_ATTRIB_OBJ_NAME;
  718. Attributes[i].dwControlCode = ADS_ATTR_UPDATE;
  719. Attributes[i].dwADsType = ADSTYPE_DN_STRING;
  720. Attributes[i].dwNumValues = 1;
  721. Attributes[i].pADsValues = &Values[i];
  722. Attributes[i].pADsValues[0].dwType = ADSTYPE_DN_STRING;
  723. Attributes[i].pADsValues[0].DNString = *Name;
  724. MarkFoundParam(SetParams,ArgNo);
  725. i ++;
  726. }
  727. ArgNo ++;
  728. if( Description ) { // this attribute is present
  729. Attributes[i].pszAttrName = DHCP_ATTRIB_OBJ_DESCRIPTION;
  730. Attributes[i].dwControlCode = ADS_ATTR_UPDATE;
  731. Attributes[i].dwNumValues = 1;
  732. Attributes[i].dwADsType = ADSTYPE_DN_STRING;
  733. Attributes[i].pADsValues = &Values[i];
  734. Attributes[i].pADsValues[0].dwType = ADSTYPE_DN_STRING;
  735. Attributes[i].pADsValues[0].DNString = *Description;
  736. MarkFoundParam(SetParams,ArgNo);
  737. i ++;
  738. }
  739. ArgNo ++;
  740. if( Location ) { // this attribute is present
  741. Attributes[i].pszAttrName = DHCP_ATTRIB_LOCATION_DN ;
  742. Attributes[i].dwControlCode = ADS_ATTR_UPDATE;
  743. Attributes[i].dwADsType = ADSTYPE_DN_STRING;
  744. Attributes[i].dwNumValues = 1;
  745. Attributes[i].pADsValues = &Values[i];
  746. Attributes[i].pADsValues[0].dwType = ADSTYPE_DN_STRING;
  747. Attributes[i].pADsValues[0].DNString = *Location;
  748. MarkFoundParam(SetParams,ArgNo);
  749. i ++;
  750. }
  751. ArgNo ++;
  752. if( MScopeId ) { // this attribute is present
  753. swprintf(MScopeIdString, L"0x%lx", MScopeIdString);
  754. Attributes[i].pszAttrName = DHCP_ATTRIB_MSCOPEID;
  755. Attributes[i].dwControlCode = ADS_ATTR_UPDATE;
  756. Attributes[i].dwADsType = ADSTYPE_DN_STRING;
  757. Attributes[i].dwNumValues = 1;
  758. Attributes[i].pADsValues = &Values[i];
  759. Attributes[i].pADsValues[0].dwType = ADSTYPE_DN_STRING;
  760. Attributes[i].pADsValues[0].DNString = MScopeIdString;
  761. MarkFoundParam(SetParams,ArgNo);
  762. i ++;
  763. }
  764. nAttributes = i;
  765. hResult = ADSISetObjectAttributes(
  766. /* hDSObject */ hStore->ADSIHandle,
  767. /* pAttributeEntries */ Attributes,
  768. /* dwNumAttributes */ nAttributes,
  769. /* pdwNumAttributesMo.. */ &i
  770. );
  771. if( FAILED(hResult) ) return ERROR_DDS_UNEXPECTED_ERROR;
  772. return ERROR_SUCCESS;
  773. }
  774. //================================================================================
  775. // end of file
  776. //================================================================================