Leaked source code of windows server 2003
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.

877 lines
18 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. SysFreeString(bstrElement);
  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. VariantClear(&varElement);
  411. }
  412. }
  413. szValue = (LPWSTR)AllocADsMem(sizeof(WCHAR) * (dwSize + 1));
  414. if (!szValue) {
  415. hr = E_FAIL;
  416. BAIL_ON_FAILURE(hr);
  417. }
  418. szValue[0] = '\0';
  419. //
  420. // Put in String
  421. //
  422. if ((V_VT(&vSrcProperty) & VT_VARIANT) == VT_BSTR) {
  423. BSTR bstrElement;
  424. for (i = dwSLBound; i <= dwSUBound; i++) {
  425. hr = SafeArrayGetElement(pArray,
  426. (long FAR *)&i,
  427. &bstrElement
  428. );
  429. BAIL_ON_FAILURE(hr);
  430. wcscat(szValue,bstrElement);
  431. if (i!=dwSUBound) {
  432. wcscat(szValue,L",");
  433. }
  434. SysFreeString(bstrElement);
  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. VariantClear(&v);
  528. BAIL_ON_FAILURE(hr);
  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. if ( FAILED(hr) && aList )
  537. SafeArrayDestroy( aList );
  538. RRETURN(hr);
  539. }
  540. HRESULT
  541. put_DATE_Property_ToLong(
  542. IADs * pADsObject,
  543. BSTR bstrPropertyName,
  544. DATE daSrcProperty
  545. )
  546. {
  547. HRESULT hr = S_OK;
  548. VARIANT varInputData;
  549. hr = PackDATEinLONGVariant(
  550. daSrcProperty,
  551. &varInputData
  552. );
  553. BAIL_ON_FAILURE(hr);
  554. hr = pADsObject->Put(
  555. bstrPropertyName,
  556. varInputData
  557. );
  558. BAIL_ON_FAILURE(hr);
  559. error:
  560. VariantClear( &varInputData );
  561. RRETURN(hr);
  562. }
  563. HRESULT
  564. get_DATE_Property_FromLong(
  565. IADs * pADsObject,
  566. BSTR bstrPropertyName,
  567. PDATE pdaDestProperty
  568. )
  569. {
  570. HRESULT hr = S_OK;
  571. VARIANT varOutputData;
  572. VALIDATE_PTR( pdaDestProperty );
  573. VariantInit( &varOutputData );
  574. hr = pADsObject->Get(
  575. bstrPropertyName,
  576. &varOutputData
  577. );
  578. BAIL_ON_FAILURE(hr);
  579. //
  580. // the Variant returned is expected to be a DWORD
  581. //
  582. hr = UnpackDATEfromLONGVariant(
  583. varOutputData,
  584. pdaDestProperty
  585. );
  586. BAIL_ON_FAILURE(hr);
  587. error:
  588. VariantClear( &varOutputData );
  589. RRETURN(hr);
  590. }
  591. //
  592. // The following functions are very similar to the PackFILETIMEinVariant and
  593. // UnpackFILETIMEfromVariant in ..\utils\pack.cxx except for a special casing of
  594. // 1/1/1970. This date is meant to indicate that the account never expires. The date
  595. // is used both for put and get.
  596. //
  597. HRESULT
  598. PackAccountExpirationDateinVariant(
  599. DATE daValue,
  600. VARIANT * pvarInputData
  601. )
  602. {
  603. IADsLargeInteger *pTime = NULL;
  604. VARIANT var;
  605. SYSTEMTIME systemtime;
  606. FILETIME filetime;
  607. HRESULT hr = S_OK;
  608. if (VariantTimeToSystemTime(daValue,
  609. &systemtime) == 0) {
  610. hr = E_FAIL;
  611. BAIL_ON_FAILURE(hr);
  612. }
  613. if (SystemTimeToFileTime(&systemtime,
  614. &filetime) == 0) {
  615. hr = E_FAIL;
  616. BAIL_ON_FAILURE(hr);
  617. }
  618. if (filetime.dwLowDateTime == g_Date_1_1_1970.dwLowDateTime &&
  619. filetime.dwHighDateTime == g_Date_1_1_1970.dwHighDateTime) {
  620. filetime = g_Date_Never;
  621. }
  622. else {
  623. if (LocalFileTimeToFileTime(&filetime, &filetime ) == 0) {
  624. hr = E_FAIL;
  625. BAIL_ON_FAILURE(hr);
  626. }
  627. }
  628. hr = CoCreateInstance(
  629. CLSID_LargeInteger,
  630. NULL,
  631. CLSCTX_ALL,
  632. IID_IADsLargeInteger,
  633. (void**)&pTime
  634. );
  635. BAIL_ON_FAILURE(hr);
  636. hr = pTime->put_HighPart(filetime.dwHighDateTime);
  637. BAIL_ON_FAILURE(hr);
  638. hr = pTime->put_LowPart(filetime.dwLowDateTime);
  639. BAIL_ON_FAILURE(hr);
  640. VariantInit(pvarInputData);
  641. pvarInputData->pdispVal = pTime;
  642. pvarInputData->vt = VT_DISPATCH;
  643. error:
  644. return hr;
  645. }
  646. HRESULT
  647. UnpackAccountExpirationDatefromVariant(
  648. VARIANT varSrcData,
  649. DATE * pdaValue
  650. )
  651. {
  652. IADsLargeInteger *pLarge = NULL;
  653. IDispatch *pDispatch = NULL;
  654. FILETIME filetime;
  655. SYSTEMTIME systemtime;
  656. DATE date;
  657. HRESULT hr = S_OK;
  658. if( varSrcData.vt != VT_DISPATCH){
  659. RRETURN(E_ADS_CANT_CONVERT_DATATYPE);
  660. }
  661. pDispatch = varSrcData.pdispVal;
  662. hr = pDispatch->QueryInterface(IID_IADsLargeInteger, (VOID **) &pLarge);
  663. BAIL_ON_FAILURE(hr);
  664. hr = pLarge->get_HighPart((long*)&filetime.dwHighDateTime);
  665. BAIL_ON_FAILURE(hr);
  666. hr = pLarge->get_LowPart((long*)&filetime.dwLowDateTime);
  667. BAIL_ON_FAILURE(hr);
  668. // Treat this as special case and return 1/1/1970 (don't localize either)
  669. //
  670. if (filetime.dwLowDateTime == g_Date_Never.dwLowDateTime &&
  671. filetime.dwHighDateTime == g_Date_Never.dwHighDateTime) {
  672. filetime = g_Date_1_1_1970;
  673. }
  674. else {
  675. if (FileTimeToLocalFileTime(&filetime, &filetime) == 0) {
  676. hr = E_FAIL;
  677. BAIL_ON_FAILURE(hr);
  678. }
  679. }
  680. if (FileTimeToSystemTime(&filetime,
  681. &systemtime) == 0) {
  682. hr = E_FAIL;
  683. BAIL_ON_FAILURE(hr);
  684. }
  685. if (SystemTimeToVariantTime(&systemtime,
  686. &date) == 0) {
  687. hr = E_FAIL;
  688. BAIL_ON_FAILURE(hr);
  689. }
  690. *pdaValue = date;
  691. error:
  692. if(pLarge)
  693. {
  694. pLarge->Release();
  695. pLarge = NULL;
  696. }
  697. return hr;
  698. }