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.

1499 lines
40 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: ldap2umi.cxx
  7. //
  8. // Contents: File containing the implemenation of the conversion routines
  9. // that conver the cached ldap values to UMI data types.
  10. // LdapTypeToUMITypeCopyConstruct.
  11. //
  12. // History: 02-14-00 AjayR Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "ldap.hxx"
  16. //+---------------------------------------------------------------------------
  17. // Function: ConvertLdapSyntaxIdToUmiType.
  18. //
  19. // Synopsis: Converts the ldapsyntaxId to the corresponding Umi type.
  20. //
  21. //
  22. // Arguments: dwLdapSyntax - Input ldapSyntaxId to convert.
  23. // uUmiType - Reference to return value.
  24. //
  25. // Returns: HRESULT - S_OK or any failure code.
  26. //
  27. // Modifies: uUmiType.
  28. //
  29. //----------------------------------------------------------------------------
  30. HRESULT
  31. ConvertLdapSyntaxIdToUmiType(
  32. DWORD dwLdapSyntaxId,
  33. ULONG &uUmiType
  34. )
  35. {
  36. HRESULT hr = S_OK;
  37. switch (dwLdapSyntaxId) {
  38. case LDAPTYPE_BITSTRING:
  39. case LDAPTYPE_PRINTABLESTRING:
  40. case LDAPTYPE_DIRECTORYSTRING:
  41. case LDAPTYPE_COUNTRYSTRING:
  42. case LDAPTYPE_DN:
  43. case LDAPTYPE_NUMERICSTRING:
  44. case LDAPTYPE_IA5STRING:
  45. case LDAPTYPE_CASEIGNORESTRING:
  46. case LDAPTYPE_CASEEXACTSTRING:
  47. // case LDAPTYPE_CASEIGNOREIA5STRING:
  48. case LDAPTYPE_OID:
  49. case LDAPTYPE_TELEPHONENUMBER:
  50. case LDAPTYPE_ATTRIBUTETYPEDESCRIPTION:
  51. case LDAPTYPE_OBJECTCLASSDESCRIPTION:
  52. case LDAPTYPE_DELIVERYMETHOD:
  53. case LDAPTYPE_ENHANCEDGUIDE:
  54. case LDAPTYPE_FACSIMILETELEPHONENUMBER:
  55. case LDAPTYPE_GUIDE:
  56. case LDAPTYPE_NAMEANDOPTIONALUID:
  57. case LDAPTYPE_POSTALADDRESS:
  58. case LDAPTYPE_PRESENTATIONADDRESS:
  59. case LDAPTYPE_TELEXNUMBER:
  60. case LDAPTYPE_DSAQUALITYSYNTAX:
  61. case LDAPTYPE_DATAQUALITYSYNTAX:
  62. case LDAPTYPE_MAILPREFERENCE:
  63. case LDAPTYPE_OTHERMAILBOX:
  64. case LDAPTYPE_ACCESSPOINTDN:
  65. case LDAPTYPE_ORNAME:
  66. case LDAPTYPE_ORADDRESS:
  67. uUmiType = UMI_TYPE_LPWSTR;
  68. break;
  69. case LDAPTYPE_BOOLEAN:
  70. uUmiType = UMI_TYPE_BOOL;
  71. break;
  72. case LDAPTYPE_INTEGER:
  73. uUmiType = UMI_TYPE_I4;
  74. break;
  75. case LDAPTYPE_OCTETSTRING:
  76. case LDAPTYPE_CERTIFICATE:
  77. case LDAPTYPE_CERTIFICATELIST:
  78. case LDAPTYPE_CERTIFICATEPAIR:
  79. case LDAPTYPE_PASSWORD:
  80. case LDAPTYPE_TELETEXTERMINALIDENTIFIER:
  81. case LDAPTYPE_AUDIO:
  82. case LDAPTYPE_JPEG:
  83. case LDAPTYPE_FAX:
  84. uUmiType = UMI_TYPE_OCTETSTRING;
  85. break;
  86. case LDAPTYPE_GENERALIZEDTIME:
  87. uUmiType = UMI_TYPE_SYSTEMTIME;
  88. break;
  89. case LDAPTYPE_UTCTIME:
  90. uUmiType = UMI_TYPE_SYSTEMTIME;
  91. break;
  92. case LDAPTYPE_SECURITY_DESCRIPTOR:
  93. uUmiType = UMI_TYPE_IUNKNOWN;
  94. break;
  95. case LDAPTYPE_INTEGER8:
  96. uUmiType = UMI_TYPE_I8;
  97. break;
  98. case LDAPTYPE_DNWITHBINARY:
  99. uUmiType = UMI_TYPE_IUNKNOWN;
  100. break;
  101. case LDAPTYPE_DNWITHSTRING:
  102. uUmiType = UMI_TYPE_IUNKNOWN;
  103. break;
  104. default:
  105. //
  106. // LDAPTYPE_UNKNOWN (schemaless server property) will be
  107. // not be converted.
  108. //
  109. hr = E_ADS_CANT_CONVERT_DATATYPE;
  110. break;
  111. } // end of switch.
  112. RRETURN(hr);
  113. }
  114. //
  115. // Note about functions in this file and the difference between the functions
  116. // in Ldap2var.cxx. In that file, we allocate everything into variants
  117. // and then we put all the variants in a safe array.
  118. // The functions in this file are also different from those in
  119. // ldapc\ldap2ods.cxx in that each of the actual conversion routines deals
  120. // with a native data type rather than the UMI_VALUE as a whole (or ADSVALUE
  121. // in the case of ldap2ods.cxx). This is because in UMI_VALUE's each UMI_VALUE
  122. // struct can contain an array in itself, so you do not need multiple
  123. // UMI_VALUE's to represent all values of an attribute.
  124. //
  125. //+---------------------------------------------------------------------------
  126. // Function: LdapTypeToUmiTypeLPWSTR
  127. //
  128. // Synopsis: Converts an ldap string value to a LPWSTR. Note that the
  129. // output is not a UMI_VALUE but a string.
  130. //
  131. // Arguments: Self explanatory
  132. //
  133. //
  134. // Returns: HRESULT - S_OK or any failure error code.
  135. //
  136. // Modifies: pszUmiString to point to the string being copied.
  137. //
  138. //----------------------------------------------------------------------------
  139. HRESULT
  140. LdapTypeToUmiTypeLPWSTR(
  141. PLDAPOBJECT pLdapSrcObject,
  142. LPWSTR *pszUmiString
  143. )
  144. {
  145. HRESULT hr = S_OK;
  146. ADsAssert(pszUmiString);
  147. //
  148. // We should not have NULL values but it is a good idea to check.
  149. //
  150. if (LDAPOBJECT_STRING(pLdapSrcObject)) {
  151. *pszUmiString = AllocADsStr(LDAPOBJECT_STRING(pLdapSrcObject));
  152. if (!pszUmiString) {
  153. hr = E_OUTOFMEMORY;
  154. }
  155. }
  156. RRETURN(hr);
  157. }
  158. //+---------------------------------------------------------------------------
  159. // Function: LdapTypeToUmiTypeCopyStrings
  160. //
  161. // Synopsis: Converts the ldap source objects into an array of strings
  162. // and assigns the array to the values in the UMI_VALUE *.
  163. //
  164. // Arguments: pLdapSrcObjects - array of ldap values.
  165. // pUmiProp - ptr to UMI_Property we modify the pValue.
  166. // uCount& - used to return the number of values.
  167. //
  168. // Returns: HRESULT - S_OK or any failure error code.
  169. //
  170. // Modifies: pUmiProp->pValue points to the string array.
  171. //
  172. //----------------------------------------------------------------------------
  173. HRESULT
  174. LdapTypeToUmiTypeCopyStrings(
  175. LDAPOBJECTARRAY pLdapSrcObjects,
  176. PUMI_PROPERTY pUmiProp
  177. )
  178. {
  179. HRESULT hr = S_OK;
  180. DWORD dwCount = pLdapSrcObjects.dwCount, dwCtr = 0;
  181. LPWSTR *pszStrArray = NULL;
  182. LPWSTR pszTmpString = NULL;
  183. //
  184. // Allocate string array to hold all the entries.
  185. //
  186. pszStrArray = (LPWSTR *) AllocADsMem(sizeof(LPWSTR) * dwCount);
  187. if (!pszStrArray) {
  188. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  189. }
  190. for (dwCtr = 0; (dwCtr < dwCount && SUCCEEDED(hr)); dwCtr++) {
  191. //
  192. // Go through and convert each of the elements in the ldap array
  193. //
  194. hr = LdapTypeToUmiTypeLPWSTR(
  195. pLdapSrcObjects.pLdapObjects + dwCtr,
  196. &pszTmpString
  197. );
  198. if (SUCCEEDED(hr)) {
  199. pszStrArray[dwCtr] = pszTmpString;
  200. pszTmpString = NULL;
  201. }
  202. }
  203. BAIL_ON_FAILURE(hr);
  204. //
  205. // Have the valid string array, need to set the data into UMI_VALUE.
  206. //
  207. pUmiProp->pUmiValue = (UMI_VALUE *)(void *)pszStrArray;
  208. pUmiProp->uCount = dwCount;
  209. RRETURN(hr);
  210. error:
  211. //
  212. // Do not think this is really necessary but cannot hurt.
  213. //
  214. if (pszTmpString) {
  215. FreeADsStr(pszTmpString);
  216. }
  217. if (pszStrArray) {
  218. if (dwCtr) {
  219. //
  220. // Need to go through the array and free the other strings
  221. //
  222. for (; dwCtr > 0; dwCtr --) {
  223. if (pszStrArray[dwCtr-1]) {
  224. FreeADsStr(pszStrArray[dwCtr-1]);
  225. }
  226. }
  227. } // if (dwCtr)
  228. //
  229. // Still need to free the array itself.
  230. //
  231. FreeADsMem((void*) pszStrArray);
  232. }
  233. RRETURN(hr);
  234. }
  235. //+---------------------------------------------------------------------------
  236. // Function: LdapTypeToUmiTypeBool
  237. //
  238. // Synopsis: Converts an ldap boolean value to a BOOL value
  239. //
  240. // Arguments: Self explanatory
  241. //
  242. // Returns: HRESULT - S_OK or any failure error code.
  243. //
  244. // Modifies: pfBool points to the returned value.
  245. //
  246. //----------------------------------------------------------------------------
  247. HRESULT
  248. LdapTypeToUmiTypeBool(
  249. PLDAPOBJECT pLdapSrcObject,
  250. PBOOL pfBool
  251. )
  252. {
  253. HRESULT hr = S_OK;
  254. LPTSTR pszSrc = LDAPOBJECT_STRING(pLdapSrcObject);
  255. ADsAssert(pfBool);
  256. if ( _tcsicmp( pszSrc, TEXT("TRUE")) == 0 ) {
  257. *pfBool = TRUE;
  258. }
  259. else if ( _tcsicmp( pszSrc, TEXT("FALSE")) == 0 ) {
  260. *pfBool = FALSE;
  261. }
  262. else
  263. {
  264. hr = E_ADS_CANT_CONVERT_DATATYPE;
  265. }
  266. RRETURN(hr);
  267. }
  268. //+---------------------------------------------------------------------------
  269. // Function: LdapTypeToUmiTypeCopyBooleans
  270. //
  271. // Synopsis: Converts the ldap source objects into an array of booleans
  272. // and assigns the array to the values in the UMI_PROPERTY *.
  273. //
  274. // Arguments: pLdapSrcObjects - array of ldap values.
  275. // pUmiProp - ptr to UMI_Property we modify the pValue.
  276. //
  277. // Returns: HRESULT - S_OK or any failure error code.
  278. //
  279. // Modifies: pUmiProp->pValue points to the newly created array of bools.
  280. //
  281. //----------------------------------------------------------------------------
  282. HRESULT
  283. LdapTypeToUmiTypeCopyBooleans(
  284. LDAPOBJECTARRAY pLdapSrcObjects,
  285. PUMI_PROPERTY pUmiProp
  286. )
  287. {
  288. HRESULT hr = S_OK;
  289. DWORD dwCount = pLdapSrcObjects.dwCount, dwCtr = 0;
  290. BOOL *pfBoolArray = NULL;
  291. BOOL fTempVal;
  292. //
  293. // Allocate array of boolean values to hold all the entries.
  294. //
  295. pfBoolArray = (BOOL *) AllocADsMem(sizeof(BOOL) * dwCount);
  296. if (!pfBoolArray) {
  297. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  298. }
  299. for (dwCtr = 0; (dwCtr < dwCount && SUCCEEDED(hr)); dwCtr++) {
  300. //
  301. // Go through and convert each of the elements in the ldap array
  302. //
  303. hr = LdapTypeToUmiTypeBool(
  304. pLdapSrcObjects.pLdapObjects + dwCtr,
  305. &fTempVal
  306. );
  307. if (SUCCEEDED(hr)) {
  308. pfBoolArray[dwCtr] = fTempVal;
  309. }
  310. }
  311. BAIL_ON_FAILURE(hr);
  312. //
  313. // Have the valid string array, need to set the data into UMI_VALUE.
  314. //
  315. pUmiProp->pUmiValue = (UMI_VALUE *)(void *)pfBoolArray;
  316. pUmiProp->uCount = dwCount;
  317. RRETURN(hr);
  318. error:
  319. if (pfBoolArray) {
  320. FreeADsMem( (void *) pfBoolArray);
  321. }
  322. RRETURN(hr);
  323. }
  324. //+---------------------------------------------------------------------------
  325. // Function: LdapTypeToUmiTypeInteger
  326. //
  327. // Synopsis: Converts an ldap boolean value to a BOOL value. It appears
  328. // that if _ttol fails, there is no real way to tell cause 0 is
  329. // returned in that case. There is no way to distinguish a value
  330. // 0 coming back from ldap and 0 because the conversion failed.
  331. //
  332. // Arguments: Self explanatory
  333. //
  334. // Returns: HRESULT - S_OK or any failure error code.
  335. //
  336. // Modifies: pLong points to the returned value.
  337. //
  338. //----------------------------------------------------------------------------
  339. HRESULT
  340. LdapTypeToUmiTypeInteger(
  341. PLDAPOBJECT pLdapSrcObject,
  342. LONG *pLong
  343. )
  344. {
  345. HRESULT hr = S_OK;
  346. ADsAssert(pLong);
  347. *pLong = _ttol(LDAPOBJECT_STRING(pLdapSrcObject));
  348. RRETURN(hr);
  349. }
  350. //+---------------------------------------------------------------------------
  351. // Function: LdapTypeToUmiTypeCopyIntegers
  352. //
  353. // Synopsis: Converts the ldap source objects into an array of integers
  354. // and assigns the array to the values in the UMI_PROPERTY *.
  355. //
  356. // Arguments: pLdapSrcObjects - array of ldap values.
  357. // pUmiProp - ptr to UMI_Property we modify the pValue.
  358. // uCount& - used to return the number of values.
  359. //
  360. // Returns: HRESULT - S_OK or any failure error code.
  361. //
  362. // Modifies: pUmiProp->pValue points to the newly created array of integers.
  363. //
  364. //----------------------------------------------------------------------------
  365. HRESULT
  366. LdapTypeToUmiTypeCopyIntegers(
  367. LDAPOBJECTARRAY pLdapSrcObjects,
  368. PUMI_PROPERTY pUmiProp
  369. )
  370. {
  371. HRESULT hr = S_OK;
  372. DWORD dwCount = pLdapSrcObjects.dwCount, dwCtr = 0;
  373. LONG *pLongArray = NULL;
  374. LONG lTempVal;
  375. //
  376. // Allocate array of boolean values to hold all the entries.
  377. //
  378. pLongArray = (LONG *) AllocADsMem(sizeof(LONG) * dwCount);
  379. if (!pLongArray) {
  380. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  381. }
  382. for (dwCtr = 0; (dwCtr < dwCount && SUCCEEDED(hr)); dwCtr++) {
  383. //
  384. // Go through and convert each of the elements in the ldap array
  385. //
  386. hr = LdapTypeToUmiTypeInteger(
  387. pLdapSrcObjects.pLdapObjects + dwCtr,
  388. &lTempVal
  389. );
  390. if (SUCCEEDED(hr)) {
  391. pLongArray[dwCtr] = lTempVal;
  392. }
  393. }
  394. BAIL_ON_FAILURE(hr);
  395. //
  396. // Have the valid string array, need to set the data into UMI_VALUE.
  397. //
  398. pUmiProp->pUmiValue = (UMI_VALUE *)(void *)pLongArray;
  399. pUmiProp->uCount = dwCount;
  400. RRETURN(hr);
  401. error:
  402. if (pLongArray) {
  403. FreeADsMem( (void *) pLongArray);
  404. }
  405. RRETURN(hr);
  406. }
  407. //+---------------------------------------------------------------------------
  408. // Function: LdapTypeToUmiTypeOctetString
  409. //
  410. // Synopsis: Converts an ldap security ber value to an octet string.
  411. //
  412. // Arguments: Self explanatory
  413. //
  414. // Returns: HRESULT - S_OK or any failure error code.
  415. //
  416. // Modifies: pOctetStr points to the returned binary blob value.
  417. //
  418. //----------------------------------------------------------------------------
  419. HRESULT
  420. LdapTypeToUmiTypeOctetString(
  421. PLDAPOBJECT pLdapSrcObject,
  422. PUMI_OCTET_STRING pUmiOctetString
  423. )
  424. {
  425. DWORD dwLength;
  426. dwLength = LDAPOBJECT_BERVAL_LEN(pLdapSrcObject);
  427. pUmiOctetString->lpValue = (byte*)AllocADsMem(dwLength);
  428. pUmiOctetString->uLength = dwLength;
  429. if (!pUmiOctetString->lpValue) {
  430. RRETURN(E_OUTOFMEMORY);
  431. }
  432. memcpy(
  433. pUmiOctetString->lpValue,
  434. LDAPOBJECT_BERVAL_VAL(pLdapSrcObject),
  435. dwLength
  436. );
  437. RRETURN(S_OK);
  438. }
  439. //+---------------------------------------------------------------------------
  440. // Function: LdapTypeToUmiTypeCopyOctetStrings
  441. //
  442. // Synopsis: Converts the ldap source objects into an array of octet strings
  443. // and assigns the array to the values in the UMI_VALUE *.
  444. //
  445. // Arguments: pLdapSrcObjects - array of ldap values.
  446. // pUmiProp - ptr to UMI_Property we modify the pValue.
  447. // uCount& - used to return the number of values.
  448. //
  449. // Returns: HRESULT - S_OK or any failure error code.
  450. //
  451. // Modifies: pUmiProp->pValue points to the octet string array.
  452. //
  453. //----------------------------------------------------------------------------
  454. HRESULT
  455. LdapTypeToUmiTypeCopyOctetStrings(
  456. LDAPOBJECTARRAY pLdapSrcObjects,
  457. PUMI_PROPERTY pUmiProp
  458. )
  459. {
  460. HRESULT hr = S_OK;
  461. DWORD dwCount = pLdapSrcObjects.dwCount, dwCtr = 0;
  462. PUMI_OCTET_STRING pOctetArray = NULL;
  463. //
  464. // Allocate string array to hold all the entries.
  465. //
  466. pOctetArray = (PUMI_OCTET_STRING)
  467. AllocADsMem(sizeof(UMI_OCTET_STRING) * dwCount);
  468. if (!pOctetArray) {
  469. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  470. }
  471. for (dwCtr = 0; (dwCtr < dwCount && SUCCEEDED(hr)); dwCtr++) {
  472. //
  473. // Go through and convert each of the elements in the ldap array
  474. //
  475. hr = LdapTypeToUmiTypeOctetString(
  476. pLdapSrcObjects.pLdapObjects + dwCtr,
  477. &pOctetArray[dwCtr]
  478. );
  479. }
  480. BAIL_ON_FAILURE(hr);
  481. //
  482. // Have the valid string array, need to set the data into UMI_VALUE.
  483. //
  484. pUmiProp->pUmiValue = (UMI_VALUE *)(void *)pOctetArray;
  485. pUmiProp->uCount = dwCount;
  486. RRETURN(hr);
  487. error:
  488. if (pOctetArray) {
  489. if (dwCtr) {
  490. //
  491. // Need to go through the array and free the other strings
  492. //
  493. for (; dwCtr > 0; dwCtr --) {
  494. if (pOctetArray[dwCtr-1].lpValue) {
  495. FreeADsMem(pOctetArray[dwCtr-1].lpValue);
  496. }
  497. }
  498. } // if (dwCtr)
  499. //
  500. // Still need to free the array itself.
  501. //
  502. FreeADsMem((void*) pOctetArray);
  503. }
  504. RRETURN(hr);
  505. }
  506. //+---------------------------------------------------------------------------
  507. // Function: LdapTypeToUmiTypeDNWithBinary
  508. //
  509. // Synopsis: Converts ldap DNWithBinary data to a UMI_COM_OBJECT with
  510. // the interface IADsDNWithBinary.
  511. //
  512. // Arguments: pLdapSrcObject - Binary security descriptor to convert.
  513. // pUmiComObject - Return value.
  514. //
  515. // Returns: HRESULT - S_OK or any failure error code.
  516. //
  517. // Modifies: pUmiComObject has valid data if successful.
  518. //
  519. //----------------------------------------------------------------------------
  520. HRESULT
  521. LdapTypeToUmiTypeDNWithBinary(
  522. PLDAPOBJECT pLdapSrcObject,
  523. PUMI_COM_OBJECT pUmiComObject
  524. )
  525. {
  526. HRESULT hr = S_OK;
  527. VARIANT vVar;
  528. IADsDNWithBinary *pDNBin = NULL;
  529. VariantInit(&vVar);
  530. hr = LdapTypeToVarTypeDNWithBinary(
  531. pLdapSrcObject,
  532. &vVar
  533. );
  534. if (vVar.vt != VT_DISPATCH) {
  535. BAIL_ON_FAILURE(hr = E_FAIL);
  536. }
  537. //
  538. // Now we need to QI for IID_IADsSecurityDescriptor.
  539. //
  540. hr = vVar.pdispVal->QueryInterface(
  541. IID_IADsDNWithBinary,
  542. (void **) &pDNBin
  543. );
  544. BAIL_ON_FAILURE(hr);
  545. //
  546. // We need to fill in the details in the com object.
  547. //
  548. pUmiComObject->priid = (IID*) AllocADsMem(sizeof(IID));
  549. if (!pUmiComObject->priid) {
  550. //
  551. // Need to free the secdesc as this is a failure case.
  552. //
  553. pDNBin->Release();
  554. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  555. }
  556. memcpy(pUmiComObject->priid, &(IID_IADsDNWithBinary), sizeof(IID));
  557. pUmiComObject->pInterface = (void *) pDNBin;
  558. error:
  559. //
  560. // Need to clear even in success case.
  561. //
  562. VariantClear(&vVar);
  563. RRETURN(hr);
  564. }
  565. //+---------------------------------------------------------------------------
  566. // Function: LdapTypeToUmiTypeDNWithString
  567. //
  568. // Synopsis: Converts ldap DNWithString data to a UMI_COM_OBJECT with
  569. // the interface IADsDNWithString.
  570. //
  571. // Arguments: pLdapSrcObject - Binary security descriptor to convert.
  572. // pUmiComObject - Return value.
  573. //
  574. // Returns: HRESULT - S_OK or any failure error code.
  575. //
  576. // Modifies: pUmiComObject has valid data if successful.
  577. //
  578. //----------------------------------------------------------------------------
  579. HRESULT
  580. LdapTypeToUmiTypeDNWithString(
  581. PLDAPOBJECT pLdapSrcObject,
  582. PUMI_COM_OBJECT pUmiComObject
  583. )
  584. {
  585. HRESULT hr = S_OK;
  586. VARIANT vVar;
  587. IADsDNWithString *pDNStr = NULL;
  588. VariantInit(&vVar);
  589. hr = LdapTypeToVarTypeDNWithString(
  590. pLdapSrcObject,
  591. &vVar
  592. );
  593. if (vVar.vt != VT_DISPATCH) {
  594. BAIL_ON_FAILURE(hr = E_FAIL);
  595. }
  596. //
  597. // Now we need to QI for IID_IADsSecurityDescriptor.
  598. //
  599. hr = vVar.pdispVal->QueryInterface(
  600. IID_IADsDNWithString,
  601. (void **) &pDNStr
  602. );
  603. BAIL_ON_FAILURE(hr);
  604. //
  605. // We need to fill in the details in the com object.
  606. //
  607. pUmiComObject->priid = (IID*) AllocADsMem(sizeof(IID));
  608. if (!pUmiComObject->priid) {
  609. //
  610. // Need to free the secdesc as this is a failure case.
  611. //
  612. pDNStr->Release();
  613. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  614. }
  615. memcpy(pUmiComObject->priid, &(IID_IADsDNWithString), sizeof(IID));
  616. pUmiComObject->pInterface = (void *) pDNStr;
  617. error:
  618. //
  619. // Need to clear even in success case.
  620. //
  621. VariantClear(&vVar);
  622. RRETURN(hr);
  623. }
  624. //+---------------------------------------------------------------------------
  625. // Function: LdapTypeToUmiTypeSecurityDescriptor
  626. //
  627. // Synopsis: Converts an ldap security descriptor to an
  628. // IADsSecurityDescriptor Com object. Note that this routine assumes
  629. // that we are dealing only with NT style SD's and that specifically
  630. // we do not have the old SS type SD's.
  631. //
  632. // Arguments: pLdapSrcObject - Binary security descriptor to convert.
  633. // pCreds - Pointer to credentials (for conversion).
  634. // pszServerName - Name of server we got this blob from.
  635. // pUmiComObject - Return value.
  636. //
  637. // Returns: HRESULT - S_OK or any failure error code.
  638. //
  639. // Modifies: pUmiComObject has valid data if succesful.
  640. //
  641. //----------------------------------------------------------------------------
  642. HRESULT
  643. LdapTypeToUmiTypeSecurityDescriptor(
  644. PLDAPOBJECT pLdapSrcObject,
  645. CCredentials *pCreds,
  646. LPWSTR pszServerName,
  647. PUMI_COM_OBJECT pUmiComObject
  648. )
  649. {
  650. HRESULT hr = S_OK;
  651. CCredentials creds;
  652. VARIANT vVar;
  653. IADsSecurityDescriptor *pSecDesc = NULL;
  654. VariantInit(&vVar);
  655. //
  656. // Update the credentials object with value passed in if applicable.
  657. //
  658. if (pCreds) {
  659. creds = *pCreds;
  660. }
  661. hr = ConvertSecDescriptorToVariant(
  662. pszServerName,
  663. creds,
  664. LDAPOBJECT_BERVAL_VAL(pLdapSrcObject),
  665. &vVar,
  666. TRUE // fNTDS type flag
  667. );
  668. BAIL_ON_FAILURE(hr);
  669. if (vVar.vt != VT_DISPATCH) {
  670. BAIL_ON_FAILURE(hr = E_FAIL);
  671. }
  672. //
  673. // Now we need to QI for IID_IADsSecurityDescriptor.
  674. //
  675. hr = vVar.pdispVal->QueryInterface(
  676. IID_IADsSecurityDescriptor,
  677. (void **) &pSecDesc
  678. );
  679. BAIL_ON_FAILURE(hr);
  680. //
  681. // We need to fill in the details in the com object.
  682. //
  683. pUmiComObject->priid = (IID*) AllocADsMem(sizeof(IID));
  684. if (!pUmiComObject->priid) {
  685. //
  686. // Need to free the secdesc as this is a failure case.
  687. //
  688. pSecDesc->Release();
  689. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  690. }
  691. memcpy(pUmiComObject->priid, &(IID_IADsSecurityDescriptor), sizeof(IID));
  692. pUmiComObject->pInterface = (void *) pSecDesc;
  693. error:
  694. //
  695. // Need to clear even in success case.
  696. //
  697. VariantClear(&vVar);
  698. RRETURN(hr);
  699. }
  700. //+---------------------------------------------------------------------------
  701. // Function: LdapTypeToUmiTypeComObjects
  702. //
  703. // Synopsis: Converts the ldap data to the corresponding com objects.
  704. // This routine calls the individual conversion routines,
  705. // converting one object at a time and packages the result into
  706. // the output values.
  707. //
  708. // Arguments: pLdapSrcObjects - raw ldap data that needs to be converted.
  709. // pCreds - Credentials used for SD's can be NULL.
  710. // pszServerName - Server Name again only for SD's NULL legal.
  711. // requiredIID - Tells us what type of COM_OBJECT to return.
  712. // pUmiProp - Return value.
  713. //
  714. // Returns: HRESULT - S_OK or any failure error code.
  715. //
  716. // Modifies: pUmiProp->pValue points to the COM_OBJECT array.
  717. //
  718. //----------------------------------------------------------------------------
  719. LdapTypeToUmiTypeCopyComObjects(
  720. LDAPOBJECTARRAY pLdapSrcObjects,
  721. CCredentials *pCreds,
  722. LPWSTR pszServerName,
  723. IID requiredIID,
  724. PUMI_PROPERTY pUmiProp
  725. )
  726. {
  727. HRESULT hr = S_OK;
  728. DWORD dwCount = pLdapSrcObjects.dwCount, dwCtr = 0;
  729. PUMI_COM_OBJECT pComObjectArray = NULL;
  730. //
  731. // Allocate string array to hold all the entries.
  732. //
  733. pComObjectArray = (PUMI_COM_OBJECT)
  734. AllocADsMem(sizeof(UMI_COM_OBJECT) * dwCount);
  735. if (!pComObjectArray) {
  736. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  737. }
  738. for (dwCtr = 0; (dwCtr < dwCount && SUCCEEDED(hr)); dwCtr++) {
  739. //
  740. // Call the appropriate conversion routine based on the
  741. // IID that we need to return.
  742. //
  743. if (requiredIID == IID_IADsSecurityDescriptor) {
  744. //
  745. // Copy over security descriptor.
  746. //
  747. hr = LdapTypeToUmiTypeSecurityDescriptor(
  748. pLdapSrcObjects.pLdapObjects + dwCtr,
  749. pCreds,
  750. pszServerName,
  751. &pComObjectArray[dwCtr]
  752. );
  753. }
  754. else if (requiredIID == IID_IADsDNWithBinary) {
  755. //
  756. // Copy over the Dn With Binary object.
  757. //
  758. hr = LdapTypeToUmiTypeDNWithBinary(
  759. pLdapSrcObjects.pLdapObjects + dwCtr,
  760. &pComObjectArray[dwCtr]
  761. );
  762. }
  763. else if (requiredIID == IID_IADsDNWithString) {
  764. //
  765. // Copy over the Dn With String object.
  766. //
  767. hr = LdapTypeToUmiTypeDNWithString(
  768. pLdapSrcObjects.pLdapObjects + dwCtr,
  769. &pComObjectArray[dwCtr]
  770. );
  771. }
  772. else {
  773. //
  774. // Got to be bad data.
  775. //
  776. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE)
  777. }
  778. }
  779. BAIL_ON_FAILURE(hr);
  780. //
  781. // Have the valid string array, need to set the data into UMI_VALUE.
  782. //
  783. pUmiProp->pUmiValue = (UMI_VALUE *)(void *)pComObjectArray;
  784. pUmiProp->uCount = dwCount;
  785. RRETURN(hr);
  786. error:
  787. if (pComObjectArray) {
  788. if (dwCtr) {
  789. //
  790. // Need to go through the array and free the other strings
  791. //
  792. for (; dwCtr > 0; dwCtr --) {
  793. if (pComObjectArray[dwCtr-1].pInterface) {
  794. //
  795. // Releasing the object will delete it if appropriate.
  796. //
  797. ((IUnknown*)
  798. pComObjectArray[dwCtr-1].pInterface)->Release();
  799. }
  800. if (pComObjectArray[dwCtr-1].priid) {
  801. FreeADsMem((void *)pComObjectArray[dwCtr-1].priid);
  802. }
  803. }
  804. } // if (dwCtr)
  805. //
  806. // Still need to free the array itself.
  807. //
  808. FreeADsMem((void*) pComObjectArray);
  809. }
  810. RRETURN(hr);
  811. }
  812. //+---------------------------------------------------------------------------
  813. // Function: LdapTypeToUmiTypeI8
  814. //
  815. // Synopsis: Converts an ldap security large integer to an I8.
  816. //
  817. // Arguments: Self explanatory
  818. //
  819. // Returns: HRESULT - S_OK or any failure error code.
  820. //
  821. // Modifies: pInt8 points to the returned large integer value.
  822. //
  823. //----------------------------------------------------------------------------
  824. HRESULT
  825. LdapTypeToUmiTypeI8(
  826. PLDAPOBJECT pLdapSrcObject,
  827. __int64 *pInt64
  828. )
  829. {
  830. ADsAssert(pInt64);
  831. *pInt64 = _ttoi64(LDAPOBJECT_STRING(pLdapSrcObject));
  832. RRETURN(S_OK);
  833. }
  834. //+---------------------------------------------------------------------------
  835. // Function: LdapTypeToUmiTypeCopyLargeIntegers
  836. //
  837. // Synopsis: Converts the ldap source objects into an array of int64's
  838. // and assigns the array to the values in the UMI_PROPERTY *.
  839. //
  840. // Arguments: pLdapSrcObjects - array of ldap values.
  841. // pUmiProp - ptr to UMI_Property we modify the pValue.
  842. //
  843. // Returns: HRESULT - S_OK or any failure error code.
  844. //
  845. // Modifies: pUmiProp->pValue points to the newly created array of int64's.
  846. //
  847. //----------------------------------------------------------------------------
  848. HRESULT
  849. LdapTypeToUmiTypeCopyLargeIntegers(
  850. LDAPOBJECTARRAY pLdapSrcObjects,
  851. PUMI_PROPERTY pUmiProp
  852. )
  853. {
  854. HRESULT hr = S_OK;
  855. DWORD dwCount = pLdapSrcObjects.dwCount, dwCtr = 0;
  856. __int64 *pInt64Array = NULL;
  857. __int64 int64Val;
  858. //
  859. // Allocate array of boolean values to hold all the entries.
  860. //
  861. pInt64Array = (__int64 *) AllocADsMem(sizeof(__int64) * dwCount);
  862. if (!pInt64Array) {
  863. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  864. }
  865. for (dwCtr = 0; (dwCtr < dwCount && SUCCEEDED(hr)); dwCtr++) {
  866. //
  867. // Go through and convert each of the elements in the ldap array
  868. //
  869. hr = LdapTypeToUmiTypeI8(
  870. pLdapSrcObjects.pLdapObjects + dwCtr,
  871. &int64Val
  872. );
  873. if (SUCCEEDED(hr)) {
  874. pInt64Array[dwCtr] = int64Val;
  875. }
  876. }
  877. BAIL_ON_FAILURE(hr);
  878. //
  879. // Have the valid string array, need to set the data into UMI_VALUE.
  880. //
  881. pUmiProp->pUmiValue = (UMI_VALUE *)(void *)pInt64Array;
  882. pUmiProp->uCount = dwCount;
  883. RRETURN(hr);
  884. error:
  885. if (pInt64Array) {
  886. FreeADsMem( (void *) pInt64Array);
  887. }
  888. RRETURN(hr);
  889. }
  890. //+---------------------------------------------------------------------------
  891. // Function: LdapTypeToUmiTypeTime
  892. //
  893. // Synopsis: Converts an ldap time value to a SystemTime value.
  894. //
  895. // Arguments: Self explanatory
  896. //
  897. // Returns: HRESULT - S_OK or any failure error code.
  898. //
  899. // Modifies: pSysTime points to the returned time value.
  900. //
  901. //----------------------------------------------------------------------------
  902. HRESULT
  903. LdapTypeUTCTimeToUmiTypeTime(
  904. PLDAPOBJECT pLdapSrcObject,
  905. SYSTEMTIME *pSystemTime
  906. )
  907. {
  908. HRESULT hr = S_OK;
  909. ADSVALUE AdsValue;
  910. ADsAssert(pSystemTime);
  911. //
  912. // This converts to a SYSTEMTIME.
  913. //
  914. hr = LdapTypeToAdsTypeUTCTime(
  915. pLdapSrcObject,
  916. &AdsValue
  917. );
  918. BAIL_ON_FAILURE(hr);
  919. *pSystemTime = AdsValue.UTCTime;
  920. error:
  921. RRETURN(hr);
  922. }
  923. //+---------------------------------------------------------------------------
  924. // Function: LdapTypeGeneralizedTimeToUmiTypeTime
  925. //
  926. // Synopsis: Converts an ldap time value to a SystemTime value.
  927. //
  928. // Arguments: Self explanatory
  929. //
  930. // Returns: HRESULT - S_OK or any failure error code.
  931. //
  932. // Modifies: pSysTime points to the returned time value.
  933. //
  934. //----------------------------------------------------------------------------
  935. HRESULT
  936. LdapTypeGeneralizedTimeToUmiTypeTime(
  937. PLDAPOBJECT pLdapSrcObject,
  938. SYSTEMTIME *pSystemTime
  939. )
  940. {
  941. HRESULT hr = S_OK;
  942. ADSVALUE AdsValue;
  943. //
  944. // This converts to a SYSTEMTIME.
  945. //
  946. hr = LdapTypeToAdsTypeGeneralizedTime(
  947. pLdapSrcObject,
  948. &AdsValue
  949. );
  950. BAIL_ON_FAILURE(hr);
  951. *pSystemTime = AdsValue.UTCTime;
  952. error:
  953. RRETURN(hr);
  954. }
  955. //+---------------------------------------------------------------------------
  956. // Function: LdapTypeToUmiTypeTimeObjects
  957. //
  958. // Synopsis: Converts the ldap source objects into an array of systemtimes
  959. // and assigns the array to the values in the UMI_PROPERTY *.
  960. //
  961. // Arguments: pLdapSrcObjects - array of ldap values.
  962. // pUmiProp - ptr to UMI_Property we modify the pValue.
  963. // dwSyntaxId - tells us what type of time this is (rather
  964. // write the same code again for UTC and Gen).
  965. //
  966. // Returns: HRESULT - S_OK or any failure error code.
  967. //
  968. // Modifies: pUmiProp->pValue points to the new array of systimes.
  969. //
  970. //----------------------------------------------------------------------------
  971. HRESULT
  972. LdapTypeToUmiTypeCopyTimeObjects(
  973. LDAPOBJECTARRAY pLdapSrcObjects,
  974. PUMI_PROPERTY pUmiProp,
  975. DWORD dwSyntaxId
  976. )
  977. {
  978. HRESULT hr = S_OK;
  979. DWORD dwCount = pLdapSrcObjects.dwCount, dwCtr = 0;
  980. SYSTEMTIME *pSysTimeArray = NULL;
  981. SYSTEMTIME sysTimeVal;
  982. //
  983. // Allocate array of boolean values to hold all the entries.
  984. //
  985. pSysTimeArray = (SYSTEMTIME *) AllocADsMem(sizeof(SYSTEMTIME) * dwCount);
  986. if (!pSysTimeArray) {
  987. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  988. }
  989. for (dwCtr = 0; (dwCtr < dwCount && SUCCEEDED(hr)); dwCtr++) {
  990. //
  991. // Go through and convert each element appropriately.
  992. //
  993. switch (dwSyntaxId) {
  994. case LDAPTYPE_UTCTIME :
  995. hr = LdapTypeGeneralizedTimeToUmiTypeTime(
  996. pLdapSrcObjects.pLdapObjects + dwCtr,
  997. &sysTimeVal
  998. );
  999. break;
  1000. case LDAPTYPE_GENERALIZEDTIME :
  1001. hr = LdapTypeGeneralizedTimeToUmiTypeTime(
  1002. pLdapSrcObjects.pLdapObjects + dwCtr,
  1003. &sysTimeVal
  1004. );
  1005. break;
  1006. default:
  1007. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1008. }
  1009. BAIL_ON_FAILURE(hr);
  1010. if (SUCCEEDED(hr)) {
  1011. pSysTimeArray[dwCtr] = sysTimeVal;
  1012. }
  1013. }
  1014. BAIL_ON_FAILURE(hr);
  1015. //
  1016. // Have the valid string array, need to set the data into UMI_VALUE.
  1017. //
  1018. pUmiProp->pUmiValue = (UMI_VALUE *)(void *)pSysTimeArray;
  1019. pUmiProp->uCount = dwCount;
  1020. RRETURN(hr);
  1021. error:
  1022. if (pSysTimeArray) {
  1023. FreeADsMem( (void *) pSysTimeArray);
  1024. }
  1025. RRETURN(hr);
  1026. }
  1027. //+---------------------------------------------------------------------------
  1028. // Function: LdapTypeToUmiTypeCopy.
  1029. //
  1030. // Synopsis: Helper routine to convert ldap values to the required UMI
  1031. // data type.
  1032. //
  1033. // Arguments: pLdapSrcObjects - The source objects to convert.
  1034. // pProp - Return value.
  1035. // dwStatus - Indicates status of property in cache.
  1036. // dwLdapSyntaxId - Ldap syntax of the data.
  1037. // pCreds - Ptr to credentials to use for conversion.
  1038. // pszServerName - Name of the server to use for conversion.
  1039. // uUmiFlags - UMI flag corresponding to dwStatus.
  1040. //
  1041. // Returns: HRESULT - S_OK or any failure error code.
  1042. //
  1043. // Modifies: pProp and dwLdapSyntaxId
  1044. //
  1045. //----------------------------------------------------------------------------
  1046. HRESULT
  1047. LdapTypeToUmiTypeCopy(
  1048. LDAPOBJECTARRAY pLdapSrcObjects,
  1049. UMI_PROPERTY_VALUES **pProp,
  1050. DWORD dwStatus,
  1051. DWORD dwLdapSyntaxId,
  1052. CCredentials *pCreds, // needed for sd's
  1053. LPWSTR pszServerName, // needed for sd's
  1054. ULONG uUmiFlags
  1055. )
  1056. {
  1057. HRESULT hr = S_OK;
  1058. DWORD dwCount = pLdapSrcObjects.dwCount, dwCtr;
  1059. UMI_PROPERTY *pProperty = NULL;
  1060. LPVOID lpVoid = NULL;
  1061. //
  1062. // Allocate the UMI_PROPERTY_VALUES needed, only one element for now.
  1063. //
  1064. *pProp = (UMI_PROPERTY_VALUES*)AllocADsMem(sizeof(UMI_PROPERTY_VALUES));
  1065. if (!*pProp) {
  1066. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1067. }
  1068. //
  1069. // We are only going to have one value.
  1070. //
  1071. (*pProp)->uCount = 1;
  1072. //
  1073. // Now allocate the actual property object.
  1074. //
  1075. pProperty = (UMI_PROPERTY*) AllocADsMem(sizeof(UMI_PROPERTY));
  1076. if (!pProperty) {
  1077. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1078. }
  1079. (*pProp)->pPropArray = pProperty;
  1080. //
  1081. // If the operation is clear/delete, then we do not have anything
  1082. // to return. There is one Umi object with no values in it and
  1083. // possibly no datatype.
  1084. //
  1085. if (dwStatus == PROPERTY_DELETE) {
  1086. pProperty->pUmiValue = NULL;
  1087. pProperty->uType = 0;
  1088. }
  1089. else {
  1090. switch (dwLdapSyntaxId) {
  1091. case LDAPTYPE_BITSTRING:
  1092. case LDAPTYPE_PRINTABLESTRING:
  1093. case LDAPTYPE_DIRECTORYSTRING:
  1094. case LDAPTYPE_COUNTRYSTRING:
  1095. case LDAPTYPE_DN:
  1096. case LDAPTYPE_NUMERICSTRING:
  1097. case LDAPTYPE_IA5STRING:
  1098. case LDAPTYPE_CASEIGNORESTRING:
  1099. case LDAPTYPE_CASEEXACTSTRING:
  1100. // case LDAPTYPE_CASEIGNOREIA5STRING:
  1101. case LDAPTYPE_OID:
  1102. case LDAPTYPE_TELEPHONENUMBER:
  1103. case LDAPTYPE_ATTRIBUTETYPEDESCRIPTION:
  1104. case LDAPTYPE_OBJECTCLASSDESCRIPTION:
  1105. case LDAPTYPE_DELIVERYMETHOD:
  1106. case LDAPTYPE_ENHANCEDGUIDE:
  1107. case LDAPTYPE_FACSIMILETELEPHONENUMBER:
  1108. case LDAPTYPE_GUIDE:
  1109. case LDAPTYPE_NAMEANDOPTIONALUID:
  1110. case LDAPTYPE_POSTALADDRESS:
  1111. case LDAPTYPE_PRESENTATIONADDRESS:
  1112. case LDAPTYPE_TELEXNUMBER:
  1113. case LDAPTYPE_DSAQUALITYSYNTAX:
  1114. case LDAPTYPE_DATAQUALITYSYNTAX:
  1115. case LDAPTYPE_MAILPREFERENCE:
  1116. case LDAPTYPE_OTHERMAILBOX:
  1117. case LDAPTYPE_ACCESSPOINTDN:
  1118. case LDAPTYPE_ORNAME:
  1119. case LDAPTYPE_ORADDRESS:
  1120. hr = LdapTypeToUmiTypeCopyStrings(
  1121. pLdapSrcObjects,
  1122. pProperty
  1123. );
  1124. BAIL_ON_FAILURE(hr);
  1125. pProperty->uType = UMI_TYPE_LPWSTR;
  1126. pProperty->pszPropertyName = NULL;
  1127. break;
  1128. case LDAPTYPE_BOOLEAN:
  1129. hr = LdapTypeToUmiTypeCopyBooleans(
  1130. pLdapSrcObjects,
  1131. pProperty
  1132. );
  1133. BAIL_ON_FAILURE(hr);
  1134. pProperty->uType = UMI_TYPE_BOOL;
  1135. pProperty->pszPropertyName = NULL;
  1136. break;
  1137. case LDAPTYPE_INTEGER:
  1138. hr = LdapTypeToUmiTypeCopyIntegers(
  1139. pLdapSrcObjects,
  1140. pProperty
  1141. );
  1142. BAIL_ON_FAILURE(hr);
  1143. pProperty->uType = UMI_TYPE_I4;
  1144. pProperty->pszPropertyName = NULL;
  1145. break;
  1146. case LDAPTYPE_OCTETSTRING:
  1147. case LDAPTYPE_CERTIFICATE:
  1148. case LDAPTYPE_CERTIFICATELIST:
  1149. case LDAPTYPE_CERTIFICATEPAIR:
  1150. case LDAPTYPE_PASSWORD:
  1151. case LDAPTYPE_TELETEXTERMINALIDENTIFIER:
  1152. case LDAPTYPE_AUDIO:
  1153. case LDAPTYPE_JPEG:
  1154. case LDAPTYPE_FAX:
  1155. hr = LdapTypeToUmiTypeCopyOctetStrings(
  1156. pLdapSrcObjects,
  1157. pProperty
  1158. );
  1159. BAIL_ON_FAILURE(hr);
  1160. pProperty->uType = UMI_TYPE_OCTETSTRING;
  1161. pProperty->pszPropertyName = NULL;
  1162. break;
  1163. case LDAPTYPE_GENERALIZEDTIME:
  1164. hr = LdapTypeToUmiTypeCopyTimeObjects(
  1165. pLdapSrcObjects,
  1166. pProperty,
  1167. LDAPTYPE_GENERALIZEDTIME
  1168. );
  1169. BAIL_ON_FAILURE(hr);
  1170. pProperty->uType = UMI_TYPE_SYSTEMTIME;
  1171. pProperty->pszPropertyName = NULL;
  1172. break;
  1173. case LDAPTYPE_UTCTIME:
  1174. hr = LdapTypeToUmiTypeCopyTimeObjects(
  1175. pLdapSrcObjects,
  1176. pProperty,
  1177. LDAPTYPE_UTCTIME
  1178. );
  1179. BAIL_ON_FAILURE(hr);
  1180. pProperty->uType = UMI_TYPE_SYSTEMTIME;
  1181. pProperty->pszPropertyName = NULL;
  1182. break;
  1183. case LDAPTYPE_SECURITY_DESCRIPTOR:
  1184. hr = LdapTypeToUmiTypeCopyComObjects(
  1185. pLdapSrcObjects,
  1186. pCreds,
  1187. pszServerName,
  1188. IID_IADsSecurityDescriptor,
  1189. pProperty
  1190. );
  1191. BAIL_ON_FAILURE(hr);
  1192. pProperty->uType = UMI_TYPE_IUNKNOWN;
  1193. pProperty->pszPropertyName = NULL;
  1194. break;
  1195. case LDAPTYPE_INTEGER8:
  1196. hr = LdapTypeToUmiTypeCopyLargeIntegers(
  1197. pLdapSrcObjects,
  1198. pProperty
  1199. );
  1200. BAIL_ON_FAILURE(hr);
  1201. pProperty->uType = UMI_TYPE_I8;
  1202. pProperty->pszPropertyName = NULL;
  1203. break;
  1204. /*
  1205. #if 0
  1206. case LDAPTYPE_CASEEXACTLIST:
  1207. case LDAPTYPE_CASEIGNORELIST:
  1208. #endif
  1209. */
  1210. case LDAPTYPE_DNWITHBINARY:
  1211. hr = LdapTypeToUmiTypeCopyComObjects(
  1212. pLdapSrcObjects,
  1213. pCreds,
  1214. pszServerName,
  1215. IID_IADsDNWithBinary,
  1216. pProperty
  1217. );
  1218. BAIL_ON_FAILURE(hr);
  1219. pProperty->uType = UMI_TYPE_IUNKNOWN;
  1220. pProperty->pszPropertyName = NULL;
  1221. break;
  1222. case LDAPTYPE_DNWITHSTRING:
  1223. hr = LdapTypeToUmiTypeCopyComObjects(
  1224. pLdapSrcObjects,
  1225. pCreds,
  1226. pszServerName,
  1227. IID_IADsDNWithString,
  1228. pProperty
  1229. );
  1230. BAIL_ON_FAILURE(hr);
  1231. pProperty->uType = UMI_TYPE_IUNKNOWN;
  1232. pProperty->pszPropertyName = NULL;
  1233. break;
  1234. default:
  1235. //
  1236. // LDAPTYPE_UNKNOWN (schemaless server property) will be
  1237. // not be converted.
  1238. //
  1239. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1240. break;
  1241. } // end of case.
  1242. } // end of if property != DELETE.
  1243. //
  1244. // Need to set the property type on the operation if we get here.
  1245. //
  1246. pProperty->uOperationType = uUmiFlags;
  1247. RRETURN(hr);
  1248. error:
  1249. //
  1250. // Free the Property array as needed.
  1251. //
  1252. // FreeUmiPropertyArray();
  1253. // DO NOT FREE pProperty it will be handled byt FreeUmiPropertyArray
  1254. // Write code to free lpVoid as it will have valid data in failure cases.
  1255. RRETURN(hr);
  1256. }