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.

863 lines
17 KiB

  1. #include "ldap.hxx"
  2. #pragma hdrstop
  3. #define VALIDATE_PTR(pPtr) \
  4. if (!pPtr) { \
  5. hr = E_ADS_BAD_PARAMETER;\
  6. }\
  7. BAIL_ON_FAILURE(hr);
  8. static HRESULT
  9. PackAccountExpirationDateinVariant(
  10. DATE daValue,
  11. VARIANT * pvarInputData
  12. );
  13. static HRESULT
  14. UnpackAccountExpirationDatefromVariant(
  15. VARIANT varSrcData,
  16. DATE * pdaValue
  17. );
  18. // This is the date used in AccountExpirationDate property to specify that the
  19. // account never expires
  20. //
  21. static FILETIME g_Date_1_1_1970 = { 0xd53e8000, 0x019db1de };
  22. // This is the value actually returned by the server
  23. //
  24. static FILETIME g_Date_Never = { 0xffffffff, 0x7fffffff };
  25. HRESULT
  26. put_BSTR_Property(
  27. IADs * pADsObject,
  28. BSTR bstrPropertyName,
  29. BSTR pSrcStringProperty
  30. )
  31. {
  32. HRESULT hr = S_OK;
  33. VARIANT varInputData;
  34. hr = PackStringinVariant(
  35. pSrcStringProperty,
  36. &varInputData
  37. );
  38. BAIL_ON_FAILURE(hr);
  39. hr = pADsObject->Put(
  40. bstrPropertyName,
  41. varInputData
  42. );
  43. BAIL_ON_FAILURE(hr);
  44. error:
  45. VariantClear( &varInputData );
  46. RRETURN(hr);
  47. }
  48. HRESULT
  49. get_BSTR_Property(
  50. IADs * pADsObject,
  51. BSTR bstrPropertyName,
  52. BSTR *ppDestStringProperty
  53. )
  54. {
  55. HRESULT hr = S_OK;
  56. VARIANT varOutputData;
  57. VALIDATE_PTR( ppDestStringProperty );
  58. VariantInit( &varOutputData );
  59. hr = pADsObject->Get(
  60. bstrPropertyName,
  61. &varOutputData
  62. );
  63. BAIL_ON_FAILURE(hr);
  64. hr = UnpackStringfromVariant(
  65. varOutputData,
  66. ppDestStringProperty
  67. );
  68. BAIL_ON_FAILURE(hr);
  69. error:
  70. VariantClear( &varOutputData );
  71. RRETURN(hr);
  72. }
  73. HRESULT
  74. put_LONG_Property(
  75. IADs * pADsObject,
  76. BSTR bstrPropertyName,
  77. LONG lSrcProperty
  78. )
  79. {
  80. HRESULT hr = S_OK;
  81. VARIANT varInputData;
  82. hr = PackLONGinVariant(
  83. lSrcProperty,
  84. &varInputData
  85. );
  86. BAIL_ON_FAILURE(hr);
  87. hr = pADsObject->Put(
  88. bstrPropertyName,
  89. varInputData
  90. );
  91. BAIL_ON_FAILURE(hr);
  92. error:
  93. VariantClear( &varInputData );
  94. RRETURN(hr);
  95. }
  96. HRESULT
  97. get_LONG_Property(
  98. IADs * pADsObject,
  99. BSTR bstrPropertyName,
  100. PLONG plDestProperty
  101. )
  102. {
  103. HRESULT hr = S_OK;
  104. VARIANT varOutputData;
  105. VALIDATE_PTR( plDestProperty );
  106. VariantInit( &varOutputData );
  107. hr = pADsObject->Get(
  108. bstrPropertyName,
  109. &varOutputData
  110. );
  111. BAIL_ON_FAILURE(hr);
  112. hr = UnpackLONGfromVariant(
  113. varOutputData,
  114. plDestProperty
  115. );
  116. BAIL_ON_FAILURE(hr);
  117. error:
  118. VariantClear( &varOutputData );
  119. RRETURN(hr);
  120. }
  121. HRESULT
  122. put_DATE_Property(
  123. IADs * pADsObject,
  124. BSTR bstrPropertyName,
  125. DATE daSrcProperty
  126. )
  127. {
  128. HRESULT hr = S_OK;
  129. VARIANT varInputData;
  130. hr = PackDATEinVariant(
  131. daSrcProperty,
  132. &varInputData
  133. );
  134. BAIL_ON_FAILURE(hr);
  135. hr = pADsObject->Put(
  136. bstrPropertyName,
  137. varInputData
  138. );
  139. BAIL_ON_FAILURE(hr);
  140. error:
  141. VariantClear( &varInputData );
  142. RRETURN(hr);
  143. }
  144. HRESULT
  145. get_DATE_Property(
  146. IADs * pADsObject,
  147. BSTR bstrPropertyName,
  148. PDATE pdaDestProperty
  149. )
  150. {
  151. HRESULT hr = S_OK;
  152. VARIANT varOutputData;
  153. VALIDATE_PTR( pdaDestProperty );
  154. VariantInit( &varOutputData );
  155. hr = pADsObject->Get(
  156. bstrPropertyName,
  157. &varOutputData
  158. );
  159. BAIL_ON_FAILURE(hr);
  160. hr = UnpackDATEfromVariant(
  161. varOutputData,
  162. pdaDestProperty
  163. );
  164. BAIL_ON_FAILURE(hr);
  165. error:
  166. VariantClear( &varOutputData );
  167. RRETURN(hr);
  168. }
  169. HRESULT
  170. put_VARIANT_BOOL_Property(
  171. IADs * pADsObject,
  172. BSTR bstrPropertyName,
  173. VARIANT_BOOL fSrcProperty
  174. )
  175. {
  176. HRESULT hr = S_OK;
  177. VARIANT varInputData;
  178. hr = PackVARIANT_BOOLinVariant(
  179. fSrcProperty,
  180. &varInputData
  181. );
  182. BAIL_ON_FAILURE(hr);
  183. hr = pADsObject->Put(
  184. bstrPropertyName,
  185. varInputData
  186. );
  187. BAIL_ON_FAILURE(hr);
  188. error:
  189. VariantClear( &varInputData );
  190. RRETURN(hr);
  191. }
  192. HRESULT
  193. get_VARIANT_BOOL_Property(
  194. IADs * pADsObject,
  195. BSTR bstrPropertyName,
  196. PVARIANT_BOOL pfDestProperty
  197. )
  198. {
  199. HRESULT hr = S_OK;
  200. VARIANT varOutputData;
  201. VALIDATE_PTR( pfDestProperty );
  202. VariantInit( &varOutputData );
  203. hr = pADsObject->Get(
  204. bstrPropertyName,
  205. &varOutputData
  206. );
  207. BAIL_ON_FAILURE(hr);
  208. hr = UnpackVARIANT_BOOLfromVariant(
  209. varOutputData,
  210. pfDestProperty
  211. );
  212. BAIL_ON_FAILURE(hr);
  213. error:
  214. VariantClear( &varOutputData );
  215. RRETURN(hr);
  216. }
  217. HRESULT
  218. put_VARIANT_Property(
  219. IADs * pADsObject,
  220. BSTR bstrPropertyName,
  221. VARIANT vSrcProperty
  222. )
  223. {
  224. HRESULT hr = S_OK;
  225. VARIANT varInputData;
  226. hr = PackVARIANTinVariant(
  227. vSrcProperty,
  228. &varInputData
  229. );
  230. BAIL_ON_FAILURE(hr);
  231. hr = pADsObject->Put(
  232. bstrPropertyName,
  233. varInputData
  234. );
  235. BAIL_ON_FAILURE(hr);
  236. error:
  237. VariantClear( &varInputData );
  238. RRETURN(hr);
  239. }
  240. HRESULT
  241. get_VARIANT_Property(
  242. IADs * pADsObject,
  243. BSTR bstrPropertyName,
  244. PVARIANT pvDestProperty
  245. )
  246. {
  247. HRESULT hr = S_OK;
  248. VARIANT varOutputData;
  249. VALIDATE_PTR( pvDestProperty );
  250. VariantInit( &varOutputData );
  251. hr = pADsObject->Get(
  252. bstrPropertyName,
  253. &varOutputData
  254. );
  255. BAIL_ON_FAILURE(hr);
  256. hr = UnpackVARIANTfromVariant(
  257. varOutputData,
  258. pvDestProperty
  259. );
  260. BAIL_ON_FAILURE(hr);
  261. error:
  262. VariantClear( &varOutputData );
  263. RRETURN(hr);
  264. }
  265. HRESULT
  266. put_FILETIME_Property(
  267. IADs * pADsObject,
  268. BSTR bstrPropertyName,
  269. DATE daSrcProperty
  270. )
  271. {
  272. HRESULT hr = S_OK;
  273. VARIANT varInputData;
  274. if (_wcsicmp(bstrPropertyName, L"accountExpirationDate") == 0 ) {
  275. hr = PackAccountExpirationDateinVariant(
  276. daSrcProperty,
  277. &varInputData
  278. );
  279. }
  280. else {
  281. hr = PackFILETIMEinVariant(
  282. daSrcProperty,
  283. &varInputData
  284. );
  285. }
  286. BAIL_ON_FAILURE(hr);
  287. hr = pADsObject->Put(
  288. bstrPropertyName,
  289. varInputData
  290. );
  291. BAIL_ON_FAILURE(hr);
  292. error:
  293. VariantClear( &varInputData );
  294. RRETURN(hr);
  295. }
  296. HRESULT
  297. get_FILETIME_Property(
  298. IADs * pADsObject,
  299. BSTR bstrPropertyName,
  300. PDATE pdaDestProperty
  301. )
  302. {
  303. HRESULT hr = S_OK;
  304. VARIANT varOutputData;
  305. VALIDATE_PTR( pdaDestProperty );
  306. VariantInit( &varOutputData );
  307. hr = pADsObject->Get(
  308. bstrPropertyName,
  309. &varOutputData
  310. );
  311. BAIL_ON_FAILURE(hr);
  312. // Special case for Account Expiration Date
  313. //
  314. if (_wcsicmp (bstrPropertyName, L"accountExpirationDate") == 0) {
  315. hr = UnpackAccountExpirationDatefromVariant(
  316. varOutputData,
  317. pdaDestProperty
  318. );
  319. }
  320. else {
  321. hr = UnpackFILETIMEfromVariant(
  322. varOutputData,
  323. pdaDestProperty
  324. );
  325. }
  326. BAIL_ON_FAILURE(hr);
  327. error:
  328. VariantClear( &varOutputData );
  329. RRETURN(hr);
  330. }
  331. HRESULT
  332. put_BSTRARRAY_Property(
  333. IADs * pADsObject,
  334. BSTR bstrPropertyName,
  335. VARIANT vSrcProperty
  336. )
  337. {
  338. HRESULT hr = S_OK;
  339. VARIANT varInputData;
  340. DWORD dwSLBound = 0;
  341. DWORD dwSUBound = 0;
  342. DWORD dwNumVariants = 0;
  343. DWORD i = 0;
  344. LPWSTR* rgszArray = NULL;
  345. SAFEARRAY * pArray = NULL;
  346. DWORD dwSize = 0;
  347. LPWSTR szValue = NULL;
  348. if(!((V_VT(&vSrcProperty) & VT_VARIANT) && V_ISARRAY(&vSrcProperty)))
  349. return(E_FAIL);
  350. //
  351. // This handles by-ref and regular SafeArrays.
  352. //
  353. if (V_VT(&vSrcProperty) & VT_BYREF)
  354. pArray = *(V_ARRAYREF(&vSrcProperty));
  355. else
  356. pArray = V_ARRAY(&vSrcProperty);
  357. //
  358. // Check that there is only one dimension in this array
  359. //
  360. if (pArray->cDims != 1) {
  361. hr = E_FAIL;
  362. BAIL_ON_FAILURE(hr);
  363. }
  364. //
  365. // Check that there is at least one element in this array
  366. //
  367. if (pArray->rgsabound[0].cElements == 0){
  368. hr = E_FAIL;
  369. BAIL_ON_FAILURE(hr);
  370. }
  371. //
  372. // We know that this is a valid single dimension array
  373. //
  374. hr = SafeArrayGetLBound(pArray,
  375. 1,
  376. (long FAR *)&dwSLBound
  377. );
  378. BAIL_ON_FAILURE(hr);
  379. hr = SafeArrayGetUBound(pArray,
  380. 1,
  381. (long FAR *)&dwSUBound
  382. );
  383. BAIL_ON_FAILURE(hr);
  384. dwNumVariants = dwSUBound - dwSLBound + 1;
  385. //
  386. // Get Size
  387. //
  388. if ((V_VT(&vSrcProperty) & VT_VARIANT) == VT_BSTR) {
  389. BSTR bstrElement;
  390. for (i = dwSLBound; i <= dwSUBound; i++) {
  391. hr = SafeArrayGetElement(pArray,
  392. (long FAR *)&i,
  393. &bstrElement
  394. );
  395. BAIL_ON_FAILURE(hr);
  396. dwSize += (wcslen(bstrElement)+1);
  397. BAIL_ON_FAILURE(hr);
  398. }
  399. }
  400. else {
  401. VARIANT varElement;
  402. for (i = dwSLBound; i <= dwSUBound; i++) {
  403. VariantInit(&varElement);
  404. hr = SafeArrayGetElement(pArray,
  405. (long FAR *)&i,
  406. &varElement
  407. );
  408. BAIL_ON_FAILURE(hr);
  409. dwSize += (wcslen(V_BSTR(&varElement))+1);
  410. BAIL_ON_FAILURE(hr);
  411. VariantClear(&varElement);
  412. }
  413. }
  414. szValue = (LPWSTR)AllocADsMem(sizeof(WCHAR) * (dwSize + 1));
  415. if (!szValue) {
  416. hr = E_FAIL;
  417. BAIL_ON_FAILURE(hr);
  418. }
  419. szValue[0] = '\0';
  420. //
  421. // Put in String
  422. //
  423. if ((V_VT(&vSrcProperty) & VT_VARIANT) == VT_BSTR) {
  424. BSTR bstrElement;
  425. for (i = dwSLBound; i <= dwSUBound; i++) {
  426. hr = SafeArrayGetElement(pArray,
  427. (long FAR *)&i,
  428. &bstrElement
  429. );
  430. BAIL_ON_FAILURE(hr);
  431. wcscat(szValue,bstrElement);
  432. if (i!=dwSUBound) {
  433. wcscat(szValue,L",");
  434. }
  435. }
  436. }
  437. else {
  438. VARIANT varElement;
  439. for (i = dwSLBound; i <= dwSUBound; i++) {
  440. VariantInit(&varElement);
  441. hr = SafeArrayGetElement(pArray,
  442. (long FAR *)&i,
  443. &varElement
  444. );
  445. BAIL_ON_FAILURE(hr);
  446. wcscat(szValue,V_BSTR(&varElement));
  447. if (i!=dwSUBound) {
  448. wcscat(szValue,L",");
  449. }
  450. VariantClear(&varElement);
  451. }
  452. }
  453. VariantInit(&varInputData);
  454. varInputData.vt = VT_BSTR;
  455. hr = ADsAllocString(
  456. szValue,
  457. &varInputData.bstrVal
  458. );
  459. BAIL_ON_FAILURE(hr);
  460. hr = pADsObject->Put(
  461. bstrPropertyName,
  462. varInputData
  463. );
  464. BAIL_ON_FAILURE(hr);
  465. error:
  466. if (szValue) {
  467. FreeADsMem(szValue);
  468. }
  469. VariantClear( &varInputData );
  470. RRETURN(hr);
  471. }
  472. HRESULT
  473. get_BSTRARRAY_Property(
  474. IADs * pADsObject,
  475. BSTR bstrPropertyName,
  476. PVARIANT pvDestProperty
  477. )
  478. {
  479. HRESULT hr = S_OK;
  480. VARIANT varOutputData;
  481. LPWSTR szString = NULL;
  482. LPWSTR szValue = NULL;
  483. DWORD dwCount = 1;
  484. SAFEARRAY *aList = NULL;
  485. SAFEARRAYBOUND aBound;
  486. long i;
  487. VALIDATE_PTR( pvDestProperty );
  488. VariantInit( &varOutputData );
  489. hr = pADsObject->Get(
  490. bstrPropertyName,
  491. &varOutputData
  492. );
  493. BAIL_ON_FAILURE(hr);
  494. szString = varOutputData.bstrVal;
  495. if (!szString) {
  496. hr = E_ADS_PROPERTY_NOT_FOUND;
  497. BAIL_ON_FAILURE(hr);
  498. }
  499. while (szString = wcschr(szString,',')) {
  500. szString++;
  501. dwCount++;
  502. }
  503. VariantInit(pvDestProperty);
  504. aBound.lLbound = 0;
  505. aBound.cElements = dwCount;
  506. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  507. if ( aList == NULL ) {
  508. hr = E_OUTOFMEMORY;
  509. BAIL_ON_FAILURE(hr);
  510. }
  511. szString = varOutputData.bstrVal;
  512. szValue = wcstok(szString,L",");
  513. for (i=0;i<(long)dwCount;i++) {
  514. VARIANT v;
  515. VariantInit(&v);
  516. if (!szValue) {
  517. hr = E_FAIL;
  518. BAIL_ON_FAILURE(hr);
  519. }
  520. v.vt = VT_BSTR;
  521. hr = ADsAllocString(
  522. szValue,
  523. &v.bstrVal
  524. );
  525. BAIL_ON_FAILURE(hr);
  526. hr = SafeArrayPutElement( aList, &i, &v);
  527. BAIL_ON_FAILURE(hr);
  528. VariantClear(&v);
  529. szValue = wcstok(NULL,L",");
  530. }
  531. V_VT(pvDestProperty) = VT_ARRAY | VT_VARIANT;
  532. V_ARRAY(pvDestProperty) = aList;
  533. BAIL_ON_FAILURE(hr);
  534. error:
  535. VariantClear( &varOutputData );
  536. RRETURN(hr);
  537. }
  538. HRESULT
  539. put_DATE_Property_ToLong(
  540. IADs * pADsObject,
  541. BSTR bstrPropertyName,
  542. DATE daSrcProperty
  543. )
  544. {
  545. HRESULT hr = S_OK;
  546. VARIANT varInputData;
  547. hr = PackDATEinLONGVariant(
  548. daSrcProperty,
  549. &varInputData
  550. );
  551. BAIL_ON_FAILURE(hr);
  552. hr = pADsObject->Put(
  553. bstrPropertyName,
  554. varInputData
  555. );
  556. BAIL_ON_FAILURE(hr);
  557. error:
  558. VariantClear( &varInputData );
  559. RRETURN(hr);
  560. }
  561. HRESULT
  562. get_DATE_Property_FromLong(
  563. IADs * pADsObject,
  564. BSTR bstrPropertyName,
  565. PDATE pdaDestProperty
  566. )
  567. {
  568. HRESULT hr = S_OK;
  569. VARIANT varOutputData;
  570. VALIDATE_PTR( pdaDestProperty );
  571. VariantInit( &varOutputData );
  572. hr = pADsObject->Get(
  573. bstrPropertyName,
  574. &varOutputData
  575. );
  576. BAIL_ON_FAILURE(hr);
  577. //
  578. // the Variant returned is expected to be a DWORD
  579. //
  580. hr = UnpackDATEfromLONGVariant(
  581. varOutputData,
  582. pdaDestProperty
  583. );
  584. BAIL_ON_FAILURE(hr);
  585. error:
  586. VariantClear( &varOutputData );
  587. RRETURN(hr);
  588. }
  589. //
  590. // The following functions are very similar to the PackFILETIMEinVariant and
  591. // UnpackFILETIMEfromVariant in ..\utils\pack.cxx except for a special casing of
  592. // 1/1/1970. This date is meant to indicate that the account never expires. The date
  593. // is used both for put and get.
  594. //
  595. HRESULT
  596. PackAccountExpirationDateinVariant(
  597. DATE daValue,
  598. VARIANT * pvarInputData
  599. )
  600. {
  601. IADsLargeInteger *pTime = NULL;
  602. VARIANT var;
  603. SYSTEMTIME systemtime;
  604. FILETIME filetime;
  605. HRESULT hr = S_OK;
  606. if (VariantTimeToSystemTime(daValue,
  607. &systemtime) == 0) {
  608. hr = E_FAIL;
  609. BAIL_ON_FAILURE(hr);
  610. }
  611. if (SystemTimeToFileTime(&systemtime,
  612. &filetime) == 0) {
  613. hr = E_FAIL;
  614. BAIL_ON_FAILURE(hr);
  615. }
  616. if (filetime.dwLowDateTime == g_Date_1_1_1970.dwLowDateTime &&
  617. filetime.dwHighDateTime == g_Date_1_1_1970.dwHighDateTime) {
  618. filetime = g_Date_Never;
  619. }
  620. else {
  621. if (LocalFileTimeToFileTime(&filetime, &filetime ) == 0) {
  622. hr = E_FAIL;
  623. BAIL_ON_FAILURE(hr);
  624. }
  625. }
  626. hr = CoCreateInstance(
  627. CLSID_LargeInteger,
  628. NULL,
  629. CLSCTX_ALL,
  630. IID_IADsLargeInteger,
  631. (void**)&pTime
  632. );
  633. BAIL_ON_FAILURE(hr);
  634. hr = pTime->put_HighPart(filetime.dwHighDateTime);
  635. BAIL_ON_FAILURE(hr);
  636. hr = pTime->put_LowPart(filetime.dwLowDateTime);
  637. BAIL_ON_FAILURE(hr);
  638. VariantInit(pvarInputData);
  639. pvarInputData->pdispVal = pTime;
  640. pvarInputData->vt = VT_DISPATCH;
  641. error:
  642. return hr;
  643. }
  644. HRESULT
  645. UnpackAccountExpirationDatefromVariant(
  646. VARIANT varSrcData,
  647. DATE * pdaValue
  648. )
  649. {
  650. IADsLargeInteger *pLarge = NULL;
  651. IDispatch *pDispatch = NULL;
  652. FILETIME filetime;
  653. SYSTEMTIME systemtime;
  654. DATE date;
  655. HRESULT hr = S_OK;
  656. if( varSrcData.vt != VT_DISPATCH){
  657. RRETURN(E_ADS_CANT_CONVERT_DATATYPE);
  658. }
  659. pDispatch = varSrcData.pdispVal;
  660. hr = pDispatch->QueryInterface(IID_IADsLargeInteger, (VOID **) &pLarge);
  661. BAIL_ON_FAILURE(hr);
  662. hr = pLarge->get_HighPart((long*)&filetime.dwHighDateTime);
  663. BAIL_ON_FAILURE(hr);
  664. hr = pLarge->get_LowPart((long*)&filetime.dwLowDateTime);
  665. BAIL_ON_FAILURE(hr);
  666. // Treat this as special case and return 1/1/1970 (don't localize either)
  667. //
  668. if (filetime.dwLowDateTime == g_Date_Never.dwLowDateTime &&
  669. filetime.dwHighDateTime == g_Date_Never.dwHighDateTime) {
  670. filetime = g_Date_1_1_1970;
  671. }
  672. else {
  673. if (FileTimeToLocalFileTime(&filetime, &filetime) == 0) {
  674. hr = E_FAIL;
  675. BAIL_ON_FAILURE(hr);
  676. }
  677. }
  678. if (FileTimeToSystemTime(&filetime,
  679. &systemtime) == 0) {
  680. hr = E_FAIL;
  681. BAIL_ON_FAILURE(hr);
  682. }
  683. if (SystemTimeToVariantTime(&systemtime,
  684. &date) == 0) {
  685. hr = E_FAIL;
  686. BAIL_ON_FAILURE(hr);
  687. }
  688. *pdaValue = date;
  689. error:
  690. return hr;
  691. }