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.

3324 lines
75 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cPropertyValue.cxx
  7. //
  8. // Contents: PropertyValue object
  9. //
  10. // History: 11-1-95 krishnag Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "oleds.hxx"
  14. #pragma hdrstop
  15. DEFINE_IDispatch_Implementation(CPropertyValue)
  16. CPropertyValue::CPropertyValue():
  17. _pDispMgr(NULL),
  18. _dwDataType(0),
  19. _pDispatch(NULL)
  20. {
  21. memset(&_ADsValue, 0, sizeof(ADSVALUE));
  22. ENLIST_TRACKING(CPropertyValue);
  23. }
  24. HRESULT
  25. CPropertyValue::CreatePropertyValue(
  26. REFIID riid,
  27. void **ppvObj
  28. )
  29. {
  30. CPropertyValue FAR * pPropertyValue = NULL;
  31. HRESULT hr = S_OK;
  32. hr = AllocatePropertyValueObject(&pPropertyValue);
  33. BAIL_ON_FAILURE(hr);
  34. hr = pPropertyValue->QueryInterface(riid, ppvObj);
  35. BAIL_ON_FAILURE(hr);
  36. pPropertyValue->Release();
  37. RRETURN(hr);
  38. error:
  39. delete pPropertyValue;
  40. RRETURN_EXP_IF_ERR(hr);
  41. }
  42. CPropertyValue::~CPropertyValue( )
  43. {
  44. ClearData();
  45. delete _pDispMgr;
  46. }
  47. STDMETHODIMP
  48. CPropertyValue::QueryInterface(
  49. REFIID iid,
  50. LPVOID FAR* ppv
  51. )
  52. {
  53. if (IsEqualIID(iid, IID_IUnknown))
  54. {
  55. *ppv = (IADsPropertyValue FAR *) this;
  56. }
  57. else if (IsEqualIID(iid, IID_IADsPropertyValue))
  58. {
  59. *ppv = (IADsPropertyValue FAR *) this;
  60. }
  61. else if (IsEqualIID(iid, IID_IADsPropertyValue2))
  62. {
  63. *ppv = (IADsPropertyValue2 FAR *) this;
  64. }
  65. else if (IsEqualIID(iid, IID_IDispatch))
  66. {
  67. *ppv = (IADsPropertyValue FAR *) this;
  68. }
  69. else if (IsEqualIID(iid, IID_ISupportErrorInfo))
  70. {
  71. *ppv = (ISupportErrorInfo FAR *) this;
  72. }
  73. else if (IsEqualIID(iid, IID_IADsValue))
  74. {
  75. *ppv = (IADsValue FAR *) this;
  76. }
  77. else
  78. {
  79. *ppv = NULL;
  80. return E_NOINTERFACE;
  81. }
  82. AddRef();
  83. return NOERROR;
  84. }
  85. HRESULT
  86. CPropertyValue::AllocatePropertyValueObject(
  87. CPropertyValue ** ppPropertyValue
  88. )
  89. {
  90. CPropertyValue FAR * pPropertyValue = NULL;
  91. CDispatchMgr FAR * pDispMgr = NULL;
  92. HRESULT hr = S_OK;
  93. pPropertyValue = new CPropertyValue();
  94. if (pPropertyValue == NULL) {
  95. hr = E_OUTOFMEMORY;
  96. }
  97. BAIL_ON_FAILURE(hr);
  98. pDispMgr = new CDispatchMgr;
  99. if (pDispMgr == NULL) {
  100. hr = E_OUTOFMEMORY;
  101. }
  102. BAIL_ON_FAILURE(hr);
  103. hr = LoadTypeInfoEntry(
  104. pDispMgr,
  105. LIBID_ADs,
  106. IID_IADsPropertyValue,
  107. (IADsPropertyValue *)pPropertyValue,
  108. DISPID_REGULAR
  109. );
  110. BAIL_ON_FAILURE(hr);
  111. hr = LoadTypeInfoEntry(
  112. pDispMgr,
  113. LIBID_ADs,
  114. IID_IADsPropertyValue2,
  115. (IADsPropertyValue2 *)pPropertyValue,
  116. DISPID_REGULAR
  117. );
  118. BAIL_ON_FAILURE(hr);
  119. pPropertyValue->_pDispMgr = pDispMgr;
  120. *ppPropertyValue = pPropertyValue;
  121. RRETURN(hr);
  122. error:
  123. delete pDispMgr;
  124. RRETURN_EXP_IF_ERR(hr);
  125. }
  126. //
  127. // ISupportErrorInfo method
  128. //
  129. STDMETHODIMP
  130. CPropertyValue::InterfaceSupportsErrorInfo(THIS_ REFIID riid)
  131. {
  132. if (IsEqualIID(riid, IID_IADsPropertyValue) ||
  133. IsEqualIID(riid, IID_IADsPropertyValue) ||
  134. IsEqualIID(riid, IID_IADsValue)) {
  135. return S_OK;
  136. } else {
  137. return S_FALSE;
  138. }
  139. }
  140. STDMETHODIMP
  141. CPropertyValue::Clear(THIS_ )
  142. {
  143. ClearData();
  144. RRETURN(S_OK);
  145. }
  146. STDMETHODIMP
  147. CPropertyValue::get_ADsType(THIS_ long FAR * retval)
  148. {
  149. *retval = _ADsValue.dwType;
  150. RRETURN(S_OK);
  151. }
  152. STDMETHODIMP
  153. CPropertyValue::put_ADsType(THIS_ long lnADsType)
  154. {
  155. _ADsValue.dwType = (ADSTYPE)lnADsType;
  156. RRETURN(S_OK);
  157. }
  158. STDMETHODIMP
  159. CPropertyValue::get_DNString(THIS_ BSTR FAR * retval)
  160. {
  161. HRESULT hr = S_OK;
  162. if (_ADsValue.dwType != ADSTYPE_DN_STRING) {
  163. RRETURN(E_ADS_CANT_CONVERT_DATATYPE);
  164. }
  165. hr = ADsAllocString(_ADsValue.DNString, retval);
  166. RRETURN_EXP_IF_ERR(hr);
  167. }
  168. STDMETHODIMP
  169. CPropertyValue::put_DNString(THIS_ BSTR bstrDNString)
  170. {
  171. ClearData();
  172. _ADsValue.DNString = AllocADsStr(bstrDNString);
  173. _ADsValue.dwType = ADSTYPE_DN_STRING;
  174. RRETURN(S_OK);
  175. }
  176. STDMETHODIMP
  177. CPropertyValue::get_CaseExactString(THIS_ BSTR FAR * retval)
  178. {
  179. HRESULT hr = S_OK;
  180. if (_ADsValue.dwType != ADSTYPE_CASE_EXACT_STRING) {
  181. RRETURN(E_ADS_CANT_CONVERT_DATATYPE);
  182. }
  183. hr = ADsAllocString(_ADsValue.CaseExactString, retval);
  184. RRETURN_EXP_IF_ERR(hr);
  185. }
  186. STDMETHODIMP
  187. CPropertyValue::put_CaseExactString(THIS_ BSTR bstrCaseExactString)
  188. {
  189. ClearData();
  190. _ADsValue.DNString = AllocADsStr(bstrCaseExactString);
  191. _ADsValue.dwType = ADSTYPE_CASE_EXACT_STRING;
  192. RRETURN(S_OK);
  193. }
  194. STDMETHODIMP
  195. CPropertyValue::get_CaseIgnoreString(THIS_ BSTR FAR * retval)
  196. {
  197. HRESULT hr = S_OK;
  198. if (_ADsValue.dwType != ADSTYPE_CASE_IGNORE_STRING) {
  199. RRETURN_EXP_IF_ERR(E_ADS_CANT_CONVERT_DATATYPE);
  200. }
  201. hr = ADsAllocString(_ADsValue.CaseIgnoreString, retval);
  202. RRETURN_EXP_IF_ERR(hr);
  203. }
  204. STDMETHODIMP
  205. CPropertyValue::put_CaseIgnoreString(THIS_ BSTR bstrCaseIgnoreString)
  206. {
  207. ClearData();
  208. _ADsValue.DNString = AllocADsStr(bstrCaseIgnoreString);
  209. _ADsValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
  210. RRETURN(S_OK);
  211. }
  212. STDMETHODIMP
  213. CPropertyValue::get_PrintableString(THIS_ BSTR FAR * retval)
  214. {
  215. HRESULT hr = S_OK;
  216. if (_ADsValue.dwType != ADSTYPE_PRINTABLE_STRING) {
  217. RRETURN_EXP_IF_ERR(E_ADS_CANT_CONVERT_DATATYPE);
  218. }
  219. hr = ADsAllocString(_ADsValue.PrintableString, retval);
  220. RRETURN_EXP_IF_ERR(hr);
  221. }
  222. STDMETHODIMP
  223. CPropertyValue::put_PrintableString(THIS_ BSTR bstrPrintableString)
  224. {
  225. ClearData();
  226. _ADsValue.PrintableString = AllocADsStr(bstrPrintableString);
  227. _ADsValue.dwType = ADSTYPE_PRINTABLE_STRING;
  228. RRETURN(S_OK);
  229. }
  230. STDMETHODIMP
  231. CPropertyValue::get_NumericString(THIS_ BSTR FAR * retval)
  232. {
  233. HRESULT hr = S_OK;
  234. if (_ADsValue.dwType != ADSTYPE_NUMERIC_STRING) {
  235. RRETURN_EXP_IF_ERR(E_ADS_CANT_CONVERT_DATATYPE);
  236. }
  237. hr = ADsAllocString(_ADsValue.NumericString, retval);
  238. RRETURN_EXP_IF_ERR(hr);
  239. }
  240. STDMETHODIMP
  241. CPropertyValue::put_NumericString(THIS_ BSTR bstrNumericString)
  242. {
  243. ClearData();
  244. _ADsValue.DNString = AllocADsStr(bstrNumericString);
  245. _ADsValue.dwType = ADSTYPE_NUMERIC_STRING;
  246. RRETURN(S_OK);
  247. }
  248. STDMETHODIMP
  249. CPropertyValue::get_OctetString(THIS_ VARIANT FAR *retval )
  250. {
  251. HRESULT hr = S_OK;
  252. SAFEARRAY *aList = NULL;
  253. SAFEARRAYBOUND aBound;
  254. CHAR HUGEP *pArray = NULL;
  255. if (_ADsValue.dwType != ADSTYPE_OCTET_STRING) {
  256. RRETURN(E_ADS_CANT_CONVERT_DATATYPE);
  257. }
  258. aBound.lLbound = 0;
  259. aBound.cElements = _ADsValue.OctetString.dwLength;
  260. aList = SafeArrayCreate( VT_UI1, 1, &aBound );
  261. if ( aList == NULL )
  262. {
  263. hr = E_OUTOFMEMORY;
  264. BAIL_ON_FAILURE(hr);
  265. }
  266. hr = SafeArrayAccessData( aList, (void HUGEP * FAR *) &pArray );
  267. BAIL_ON_FAILURE(hr);
  268. memcpy( pArray,
  269. _ADsValue.OctetString.lpValue,
  270. aBound.cElements );
  271. SafeArrayUnaccessData( aList );
  272. V_VT(retval) = VT_ARRAY | VT_UI1;
  273. V_ARRAY(retval) = aList;
  274. RRETURN(hr);
  275. error:
  276. if ( aList ) {
  277. SafeArrayDestroy( aList );
  278. }
  279. RRETURN_EXP_IF_ERR(hr);
  280. }
  281. STDMETHODIMP
  282. CPropertyValue::put_OctetString(THIS_ VARIANT VarOctetString)
  283. {
  284. LONG dwSLBound = 0;
  285. LONG dwSUBound = 0;
  286. CHAR HUGEP *pArray = NULL;
  287. VARIANT * pvVar = &VarOctetString;
  288. HRESULT hr = S_OK;
  289. ClearData();
  290. _ADsValue.dwType = ADSTYPE_OCTET_STRING;
  291. if ( VarOctetString.vt == (VT_ARRAY | VT_BYREF)) {
  292. pvVar = V_VARIANTREF(&VarOctetString);
  293. }
  294. if( pvVar->vt != (VT_ARRAY | VT_UI1)) {
  295. RRETURN(hr = E_ADS_CANT_CONVERT_DATATYPE);
  296. }
  297. hr = SafeArrayGetLBound(V_ARRAY(pvVar),
  298. 1,
  299. (long FAR *) &dwSLBound );
  300. BAIL_ON_FAILURE(hr);
  301. hr = SafeArrayGetUBound(V_ARRAY(pvVar),
  302. 1,
  303. (long FAR *) &dwSUBound );
  304. BAIL_ON_FAILURE(hr);
  305. _ADsValue.OctetString.lpValue = (LPBYTE)AllocADsMem(dwSUBound - dwSLBound + 1);
  306. if ( _ADsValue.OctetString.lpValue == NULL) {
  307. hr = E_OUTOFMEMORY;
  308. BAIL_ON_FAILURE(hr);
  309. }
  310. _ADsValue.OctetString.dwLength = dwSUBound - dwSLBound + 1;
  311. hr = SafeArrayAccessData( V_ARRAY(pvVar),
  312. (void HUGEP * FAR *) &pArray );
  313. BAIL_ON_FAILURE(hr);
  314. memcpy( _ADsValue.OctetString.lpValue,
  315. pArray,
  316. dwSUBound-dwSLBound+1);
  317. SafeArrayUnaccessData( V_ARRAY(pvVar) );
  318. error:
  319. RRETURN_EXP_IF_ERR(hr);
  320. }
  321. STDMETHODIMP
  322. CPropertyValue::get_Integer(THIS_ LONG FAR * retval)
  323. {
  324. HRESULT hr = S_OK;
  325. if (_ADsValue.dwType != ADSTYPE_INTEGER) {
  326. RRETURN(E_ADS_CANT_CONVERT_DATATYPE);
  327. }
  328. *retval = _ADsValue.Boolean;
  329. RRETURN_EXP_IF_ERR(hr);
  330. }
  331. STDMETHODIMP
  332. CPropertyValue::put_Integer(THIS_ LONG lnInteger)
  333. {
  334. ClearData();
  335. _ADsValue.Integer = lnInteger;
  336. _ADsValue.dwType = ADSTYPE_INTEGER;
  337. RRETURN(S_OK);
  338. }
  339. STDMETHODIMP
  340. CPropertyValue::get_Boolean(THIS_ LONG FAR * retval)
  341. {
  342. HRESULT hr = S_OK;
  343. if (_ADsValue.dwType != ADSTYPE_BOOLEAN) {
  344. RRETURN(E_ADS_CANT_CONVERT_DATATYPE);
  345. }
  346. *retval = _ADsValue.Boolean;
  347. RRETURN_EXP_IF_ERR(hr);
  348. }
  349. STDMETHODIMP
  350. CPropertyValue::put_Boolean(THIS_ LONG lnBoolean)
  351. {
  352. ClearData();
  353. _ADsValue.Boolean = lnBoolean;
  354. _ADsValue.dwType = ADSTYPE_BOOLEAN;
  355. RRETURN(S_OK);
  356. }
  357. STDMETHODIMP
  358. CPropertyValue::get_SecurityDescriptor(THIS_ IDispatch FAR * FAR * ppDispatch)
  359. {
  360. HRESULT hr = E_ADS_CANT_CONVERT_DATATYPE;
  361. //
  362. // Check if we have a valid IDispatch at this point
  363. //
  364. if (_pDispatch) {
  365. switch (_dwDataType) {
  366. case VAL_IDISPATCH_SECDESC_ONLY :
  367. case VAL_IDISPATCH_SECDESC_ALL :
  368. hr = _pDispatch->QueryInterface(
  369. IID_IDispatch,
  370. (void **) ppDispatch
  371. );
  372. break;
  373. default:
  374. hr = E_ADS_CANT_CONVERT_DATATYPE;
  375. }
  376. }
  377. RRETURN(hr);
  378. }
  379. STDMETHODIMP
  380. CPropertyValue::put_SecurityDescriptor(THIS_ IDispatch * pSecurityDescriptor)
  381. {
  382. HRESULT hr = S_OK;
  383. IADsSecurityDescriptor *pIADsSecDes;
  384. IDispatch* pIDispatch;
  385. ClearData();
  386. _ADsValue.dwType = ADSTYPE_NT_SECURITY_DESCRIPTOR;
  387. //
  388. // This qi ensures that this is a security descriptor
  389. //
  390. hr = pSecurityDescriptor->QueryInterface(
  391. IID_IADsSecurityDescriptor,
  392. (void **) &pIADsSecDes
  393. );
  394. BAIL_ON_FAILURE(hr);
  395. pIADsSecDes->Release();
  396. pIADsSecDes = NULL;
  397. hr = pSecurityDescriptor->QueryInterface(
  398. IID_IDispatch,
  399. (void **) &pIDispatch
  400. );
  401. BAIL_ON_FAILURE(hr);
  402. _dwDataType = VAL_IDISPATCH_SECDESC_ONLY;
  403. _pDispatch = pIDispatch;
  404. RRETURN(hr);
  405. error:
  406. if (pIADsSecDes) {
  407. pIADsSecDes->Release();
  408. }
  409. RRETURN_EXP_IF_ERR(hr);
  410. }
  411. STDMETHODIMP
  412. CPropertyValue::get_LargeInteger(THIS_ IDispatch FAR * FAR *retval)
  413. {
  414. HRESULT hr = S_OK;
  415. IADsLargeInteger * pLargeInteger = NULL;
  416. IDispatch * pDispatch = NULL;
  417. if (_ADsValue.dwType != ADSTYPE_LARGE_INTEGER) {
  418. hr = E_ADS_CANT_CONVERT_DATATYPE;
  419. BAIL_ON_FAILURE(hr);
  420. }
  421. hr = CoCreateInstance(
  422. CLSID_LargeInteger,
  423. NULL,
  424. CLSCTX_INPROC_SERVER,
  425. IID_IADsLargeInteger,
  426. (void **) &pLargeInteger);
  427. BAIL_ON_FAILURE(hr);
  428. hr = pLargeInteger->put_LowPart(_ADsValue.LargeInteger.LowPart);
  429. BAIL_ON_FAILURE(hr);
  430. hr = pLargeInteger->put_HighPart(_ADsValue.LargeInteger.HighPart);
  431. BAIL_ON_FAILURE(hr);
  432. pLargeInteger->QueryInterface(
  433. IID_IDispatch,
  434. (void **) &pDispatch
  435. );
  436. BAIL_ON_FAILURE(hr);
  437. *retval = pDispatch;
  438. error:
  439. if (pLargeInteger) {
  440. pLargeInteger->Release();
  441. }
  442. RRETURN_EXP_IF_ERR(hr);
  443. }
  444. STDMETHODIMP
  445. CPropertyValue::put_LargeInteger(THIS_ IDispatch FAR* lnLargeInteger)
  446. {
  447. IADsLargeInteger *pLargeInteger = NULL;
  448. HRESULT hr = S_OK;
  449. LONG lnDataHigh = 0;
  450. LONG lnDataLow = 0;
  451. ClearData();
  452. hr = lnLargeInteger->QueryInterface(
  453. IID_IADsLargeInteger,
  454. (void **)&pLargeInteger
  455. );
  456. BAIL_ON_FAILURE(hr);
  457. hr = pLargeInteger->get_HighPart(&lnDataHigh);
  458. BAIL_ON_FAILURE(hr);
  459. hr = pLargeInteger->get_LowPart(&lnDataLow);
  460. BAIL_ON_FAILURE(hr);
  461. _ADsValue.dwType = ADSTYPE_LARGE_INTEGER;
  462. _ADsValue.LargeInteger.HighPart = lnDataHigh;
  463. _ADsValue.LargeInteger.LowPart = lnDataLow;
  464. error:
  465. if (pLargeInteger) {
  466. pLargeInteger->Release();
  467. }
  468. RRETURN_EXP_IF_ERR(hr);
  469. }
  470. STDMETHODIMP
  471. CPropertyValue::get_UTCTime(THIS_ DATE *retval)
  472. {
  473. HRESULT hr = S_OK;
  474. int result = FALSE;
  475. if (_ADsValue.dwType != ADSTYPE_UTC_TIME) {
  476. RRETURN(hr = E_ADS_CANT_CONVERT_DATATYPE);
  477. }
  478. result = SystemTimeToVariantTime(&_ADsValue.UTCTime, retval);
  479. if (result != TRUE) {
  480. hr = E_FAIL;
  481. }
  482. RRETURN_EXP_IF_ERR(hr);
  483. }
  484. STDMETHODIMP
  485. CPropertyValue::put_UTCTime(THIS_ DATE DateInDate)
  486. {
  487. HRESULT hr = S_OK;
  488. int result = FALSE;
  489. ClearData();
  490. _ADsValue.dwType = ADSTYPE_UTC_TIME;
  491. result = VariantTimeToSystemTime(DateInDate, &_ADsValue.UTCTime);
  492. if (result != TRUE) {
  493. hr = E_FAIL;
  494. }
  495. RRETURN_EXP_IF_ERR(hr);
  496. }
  497. STDMETHODIMP
  498. CPropertyValue::ConvertADsValueToPropertyValue(THIS_ PADSVALUE pADsValue)
  499. {
  500. HRESULT hr = S_OK;
  501. hr = ConvertADsValueToPropertyValue2(
  502. pADsValue,
  503. NULL,
  504. NULL,
  505. TRUE
  506. );
  507. RRETURN_EXP_IF_ERR(hr);
  508. }
  509. STDMETHODIMP
  510. CPropertyValue::ConvertADsValueToPropertyValue2(
  511. THIS_ PADSVALUE pADsValue,
  512. LPWSTR pszServerName,
  513. CCredentials* pCredentials,
  514. BOOL fNTDSType
  515. )
  516. {
  517. HRESULT hr = S_OK;
  518. ClearData();
  519. hr = AdsCopyADsValueToPropObj(
  520. pADsValue,
  521. this,
  522. pszServerName,
  523. pCredentials,
  524. fNTDSType
  525. );
  526. RRETURN_EXP_IF_ERR(hr);
  527. }
  528. STDMETHODIMP
  529. CPropertyValue::ConvertPropertyValueToADsValue(THIS_ PADSVALUE pADsValue)
  530. {
  531. return( ConvertPropertyValueToADsValue2(
  532. pADsValue,
  533. NULL, // serverName
  534. NULL, // userName
  535. NULL, // userPassword
  536. 0, // default flags.
  537. TRUE // flag NTDS
  538. )
  539. );
  540. }
  541. //
  542. // Handles all the parameters
  543. //
  544. STDMETHODIMP
  545. CPropertyValue::ConvertPropertyValueToADsValue2(
  546. THIS_ PADSVALUE pADsValue,
  547. LPWSTR pszServerName,
  548. LPWSTR pszUserName,
  549. LPWSTR pszPassWord,
  550. LONG dwFlags,
  551. BOOL fNTDSType
  552. )
  553. {
  554. HRESULT hr = S_OK;
  555. CCredentials Credentials( pszUserName, pszPassWord, dwFlags);
  556. hr = AdsCopyPropObjToADsValue(
  557. this,
  558. pADsValue,
  559. pszServerName,
  560. &Credentials,
  561. fNTDSType
  562. );
  563. RRETURN_EXP_IF_ERR(hr);
  564. }
  565. STDMETHODIMP
  566. CPropertyValue::get_CaseIgnoreList(THIS_ IDispatch FAR * FAR *retval)
  567. {
  568. HRESULT hr = S_OK;
  569. IADsCaseIgnoreList * pCaseIgnoreList = NULL;
  570. IDispatch * pDispatch = NULL;
  571. SAFEARRAY *aList = NULL;
  572. SAFEARRAYBOUND aBound;
  573. CHAR HUGEP *pArray = NULL;
  574. long i;
  575. BSTR bstrAddress;
  576. PADS_CASEIGNORE_LIST pCurrent = NULL;
  577. DWORD cElements = 0;
  578. VARIANT VarDestObject;
  579. VariantInit( &VarDestObject );
  580. if (_ADsValue.dwType != ADSTYPE_CASEIGNORE_LIST) {
  581. hr = E_ADS_CANT_CONVERT_DATATYPE;
  582. BAIL_ON_FAILURE(hr);
  583. }
  584. if (!_ADsValue.pCaseIgnoreList) {
  585. hr = E_FAIL;
  586. BAIL_ON_FAILURE(hr);
  587. }
  588. hr = CoCreateInstance(
  589. CLSID_CaseIgnoreList,
  590. NULL,
  591. CLSCTX_INPROC_SERVER,
  592. IID_IADsCaseIgnoreList,
  593. (void **) &pCaseIgnoreList);
  594. BAIL_ON_FAILURE(hr);
  595. pCurrent = _ADsValue.pCaseIgnoreList;
  596. while (pCurrent) {
  597. cElements++;
  598. pCurrent = pCurrent->Next;
  599. }
  600. aBound.lLbound = 0;
  601. aBound.cElements = cElements;
  602. aList = SafeArrayCreate( VT_BSTR, 1, &aBound );
  603. if ( aList == NULL ) {
  604. hr = E_OUTOFMEMORY;
  605. BAIL_ON_FAILURE(hr);
  606. }
  607. pCurrent = _ADsValue.pCaseIgnoreList;
  608. for ( i = 0; i < (long)cElements; i++ ) {
  609. hr = ADsAllocString(
  610. pCurrent->String,
  611. &bstrAddress
  612. );
  613. BAIL_ON_FAILURE(hr);
  614. hr = SafeArrayPutElement( aList, &i, bstrAddress );
  615. BAIL_ON_FAILURE(hr);
  616. pCurrent = pCurrent->Next;
  617. }
  618. V_VT(&VarDestObject) = VT_ARRAY | VT_BSTR;
  619. V_ARRAY(&VarDestObject) = aList;
  620. hr = pCaseIgnoreList->put_CaseIgnoreList(VarDestObject);
  621. BAIL_ON_FAILURE(hr);
  622. hr = pCaseIgnoreList->QueryInterface(IID_IDispatch, (void**)&pDispatch);
  623. BAIL_ON_FAILURE(hr);
  624. *retval = pDispatch;
  625. error:
  626. VariantClear( &VarDestObject );
  627. if (pCaseIgnoreList) {
  628. pCaseIgnoreList->Release();
  629. }
  630. if ( aList ) {
  631. SafeArrayDestroy( aList );
  632. }
  633. RRETURN(hr);
  634. }
  635. STDMETHODIMP
  636. CPropertyValue::put_CaseIgnoreList(THIS_ IDispatch FAR* pdCaseIgnoreList)
  637. {
  638. IADsCaseIgnoreList *pCaseIgnoreList = NULL;
  639. HRESULT hr = S_OK;
  640. LONG lnAmount= 0;
  641. DWORD dwSLBound = 0;
  642. DWORD dwSUBound = 0;
  643. long i;
  644. PADS_CASEIGNORE_LIST pCurrent = NULL;
  645. IDispatch FAR * pDispatch = NULL;
  646. BYTE* pbParameter = NULL;
  647. VARIANT varCaseIgnoreList;
  648. VARIANT varBstrElement;
  649. ClearData();
  650. VariantInit(&varCaseIgnoreList);
  651. hr = pdCaseIgnoreList->QueryInterface(
  652. IID_IADsCaseIgnoreList,
  653. (void **)&pCaseIgnoreList
  654. );
  655. BAIL_ON_FAILURE(hr);
  656. _ADsValue.dwType = ADSTYPE_CASEIGNORE_LIST;
  657. hr = pCaseIgnoreList->get_CaseIgnoreList(&varCaseIgnoreList);
  658. BAIL_ON_FAILURE(hr);
  659. if(!((V_VT(&varCaseIgnoreList) & VT_VARIANT) && V_ISARRAY(&varCaseIgnoreList))) {
  660. return(E_FAIL);
  661. }
  662. if ((V_ARRAY(&varCaseIgnoreList))->cDims != 1) {
  663. hr = E_FAIL;
  664. BAIL_ON_FAILURE(hr);
  665. }
  666. if ((V_ARRAY(&varCaseIgnoreList))->rgsabound[0].cElements <= 0) {
  667. hr = E_FAIL;
  668. BAIL_ON_FAILURE(hr);
  669. }
  670. hr = SafeArrayGetLBound(V_ARRAY(&varCaseIgnoreList),
  671. 1,
  672. (long FAR *)&dwSLBound
  673. );
  674. BAIL_ON_FAILURE(hr);
  675. hr = SafeArrayGetUBound(V_ARRAY(&varCaseIgnoreList),
  676. 1,
  677. (long FAR *)&dwSUBound
  678. );
  679. BAIL_ON_FAILURE(hr);
  680. _ADsValue.pCaseIgnoreList = (PADS_CASEIGNORE_LIST)AllocADsMem(sizeof(ADS_CASEIGNORE_LIST));
  681. if (!_ADsValue.pCaseIgnoreList) {
  682. hr = E_OUTOFMEMORY;
  683. BAIL_ON_FAILURE(hr);
  684. }
  685. pCurrent = _ADsValue.pCaseIgnoreList;
  686. for (i = dwSLBound; i <= (long)dwSUBound; i++) {
  687. VariantInit(&varBstrElement);
  688. hr = SafeArrayGetElement(V_ARRAY(&varCaseIgnoreList),
  689. (long FAR *)&i,
  690. &varBstrElement
  691. );
  692. BAIL_ON_FAILURE(hr);
  693. pCurrent->String = AllocADsStr(V_BSTR(&varBstrElement));
  694. VariantClear(&varBstrElement);
  695. if (!pCurrent->String) {
  696. hr = E_OUTOFMEMORY;
  697. BAIL_ON_FAILURE(hr);
  698. }
  699. if (i != (long)dwSUBound) {
  700. pCurrent->Next = (PADS_CASEIGNORE_LIST)AllocADsMem(sizeof(ADS_CASEIGNORE_LIST));
  701. if (!pCurrent->Next) {
  702. hr = E_OUTOFMEMORY;
  703. BAIL_ON_FAILURE(hr);
  704. }
  705. pCurrent = pCurrent->Next;
  706. }
  707. }
  708. pCurrent->Next = NULL;
  709. RRETURN(S_OK);
  710. error:
  711. VariantClear(&varCaseIgnoreList);
  712. if (pCaseIgnoreList) {
  713. pCaseIgnoreList->Release();
  714. }
  715. RRETURN(hr);
  716. }
  717. STDMETHODIMP
  718. CPropertyValue::get_FaxNumber(THIS_ IDispatch FAR * FAR *retval)
  719. {
  720. HRESULT hr = S_OK;
  721. IADsFaxNumber * pFaxNumber = NULL;
  722. IDispatch * pDispatch = NULL;
  723. VARIANT Var;
  724. if (_ADsValue.dwType != ADSTYPE_FAXNUMBER) {
  725. hr = E_ADS_CANT_CONVERT_DATATYPE;
  726. BAIL_ON_FAILURE(hr);
  727. }
  728. if (!_ADsValue.pFaxNumber) {
  729. hr = E_FAIL;
  730. BAIL_ON_FAILURE(hr);
  731. }
  732. hr = CoCreateInstance(
  733. CLSID_FaxNumber,
  734. NULL,
  735. CLSCTX_INPROC_SERVER,
  736. IID_IADsFaxNumber,
  737. (void **) &pFaxNumber);
  738. BAIL_ON_FAILURE(hr);
  739. VariantInit(&Var);
  740. hr = BinaryToVariant(
  741. _ADsValue.pFaxNumber->NumberOfBits,
  742. _ADsValue.pFaxNumber->Parameters,
  743. &Var);
  744. BAIL_ON_FAILURE(hr);
  745. hr = pFaxNumber->put_Parameters(Var);
  746. BAIL_ON_FAILURE(hr);
  747. VariantClear(&Var);
  748. hr = pFaxNumber->put_TelephoneNumber(_ADsValue.pFaxNumber->TelephoneNumber);
  749. BAIL_ON_FAILURE(hr);
  750. pFaxNumber->QueryInterface(
  751. IID_IDispatch,
  752. (void **) &pDispatch
  753. );
  754. BAIL_ON_FAILURE(hr);
  755. *retval = pDispatch;
  756. error:
  757. if (pFaxNumber) {
  758. pFaxNumber->Release();
  759. }
  760. RRETURN(hr);
  761. }
  762. STDMETHODIMP
  763. CPropertyValue::put_FaxNumber(THIS_ IDispatch FAR* pdFaxNumber)
  764. {
  765. IADsFaxNumber *pFaxNumber = NULL;
  766. HRESULT hr = S_OK;
  767. BSTR bstrTelephoneNumber;
  768. VARIANT varAddress;
  769. VariantInit(&varAddress);
  770. ClearData();
  771. hr = pdFaxNumber->QueryInterface(
  772. IID_IADsFaxNumber,
  773. (void **)&pFaxNumber
  774. );
  775. BAIL_ON_FAILURE(hr);
  776. hr = pFaxNumber->get_TelephoneNumber(&bstrTelephoneNumber);
  777. BAIL_ON_FAILURE(hr);
  778. _ADsValue.dwType = ADSTYPE_FAXNUMBER;
  779. _ADsValue.pFaxNumber = (PADS_FAXNUMBER)AllocADsMem(sizeof(ADS_FAXNUMBER));
  780. if (!_ADsValue.pFaxNumber) {
  781. hr = E_OUTOFMEMORY;
  782. BAIL_ON_FAILURE(hr);
  783. }
  784. _ADsValue.pFaxNumber->TelephoneNumber = AllocADsStr(bstrTelephoneNumber);
  785. if (!_ADsValue.pFaxNumber->TelephoneNumber) {
  786. hr = E_OUTOFMEMORY;
  787. BAIL_ON_FAILURE(hr);
  788. }
  789. hr = pFaxNumber->get_Parameters(&varAddress);
  790. BAIL_ON_FAILURE(hr);
  791. hr = VariantToBinary(
  792. &varAddress,
  793. &_ADsValue.pFaxNumber->NumberOfBits,
  794. &_ADsValue.pFaxNumber->Parameters
  795. );
  796. BAIL_ON_FAILURE(hr);
  797. error:
  798. VariantClear(&varAddress);
  799. if (pFaxNumber) {
  800. pFaxNumber->Release();
  801. }
  802. RRETURN(hr);
  803. }
  804. STDMETHODIMP
  805. CPropertyValue::get_NetAddress(THIS_ IDispatch FAR * FAR *retval)
  806. {
  807. HRESULT hr = S_OK;
  808. IADsNetAddress * pNetAddress = NULL;
  809. IDispatch * pDispatch = NULL;
  810. VARIANT VarAddress;
  811. VariantInit(&VarAddress);
  812. if (_ADsValue.dwType != ADSTYPE_NETADDRESS) {
  813. hr = E_ADS_CANT_CONVERT_DATATYPE;
  814. BAIL_ON_FAILURE(hr);
  815. }
  816. if (!_ADsValue.pNetAddress) {
  817. hr = E_FAIL;
  818. BAIL_ON_FAILURE(hr);
  819. }
  820. hr = CoCreateInstance(
  821. CLSID_NetAddress,
  822. NULL,
  823. CLSCTX_INPROC_SERVER,
  824. IID_IADsNetAddress,
  825. (void **) &pNetAddress);
  826. BAIL_ON_FAILURE(hr);
  827. hr = pNetAddress->put_AddressType(_ADsValue.pNetAddress->AddressType);
  828. BAIL_ON_FAILURE(hr);
  829. hr = BinaryToVariant(
  830. _ADsValue.pNetAddress->AddressLength,
  831. _ADsValue.pNetAddress->Address,
  832. &VarAddress);
  833. BAIL_ON_FAILURE(hr);
  834. hr = pNetAddress->put_Address(VarAddress);
  835. BAIL_ON_FAILURE(hr);
  836. pNetAddress->QueryInterface(
  837. IID_IDispatch,
  838. (void **) &pDispatch
  839. );
  840. BAIL_ON_FAILURE(hr);
  841. *retval = pDispatch;
  842. error:
  843. VariantClear(&VarAddress);
  844. if (pNetAddress) {
  845. pNetAddress->Release();
  846. }
  847. RRETURN(hr);
  848. }
  849. STDMETHODIMP
  850. CPropertyValue::put_NetAddress(THIS_ IDispatch FAR* pdNetAddress)
  851. {
  852. IADsNetAddress *pNetAddress = NULL;
  853. HRESULT hr = S_OK;
  854. LONG lnAddressType = 0;
  855. VARIANT varAddress;
  856. ClearData();
  857. VariantInit(&varAddress);
  858. _ADsValue.pNetAddress = (PADS_NETADDRESS)AllocADsMem(sizeof(ADS_NETADDRESS));
  859. if (!_ADsValue.pNetAddress) {
  860. hr = E_OUTOFMEMORY;
  861. BAIL_ON_FAILURE(hr);
  862. }
  863. hr = pdNetAddress->QueryInterface(
  864. IID_IADsNetAddress,
  865. (void **)&pNetAddress
  866. );
  867. BAIL_ON_FAILURE(hr);
  868. hr = pNetAddress->get_AddressType(
  869. &lnAddressType
  870. );
  871. BAIL_ON_FAILURE(hr);
  872. hr = pNetAddress->get_Address(
  873. &varAddress
  874. );
  875. BAIL_ON_FAILURE(hr);
  876. hr = VariantToBinary(
  877. &varAddress,
  878. &_ADsValue.pNetAddress->AddressLength,
  879. &_ADsValue.pNetAddress->Address
  880. );
  881. BAIL_ON_FAILURE(hr);
  882. _ADsValue.dwType = ADSTYPE_NETADDRESS;
  883. _ADsValue.pNetAddress->AddressType = lnAddressType;
  884. error:
  885. VariantClear(&varAddress);
  886. if (pNetAddress) {
  887. pNetAddress->Release();
  888. }
  889. RRETURN(hr);
  890. }
  891. STDMETHODIMP
  892. CPropertyValue::get_OctetList(THIS_ IDispatch FAR * FAR *retval)
  893. {
  894. HRESULT hr = S_OK;
  895. IADsOctetList* pOctetList = NULL;
  896. IDispatch * pDispatch = NULL;
  897. SAFEARRAY *aList = NULL;
  898. SAFEARRAYBOUND aBound;
  899. CHAR HUGEP *pArray = NULL;
  900. long i;
  901. PADS_OCTET_LIST pCurrent = NULL;
  902. DWORD cElements = 0;
  903. VARIANT VarDestObject;
  904. VARIANT varElement;
  905. VariantInit( &VarDestObject );
  906. if (_ADsValue.dwType != ADSTYPE_OCTET_LIST) {
  907. hr = E_ADS_CANT_CONVERT_DATATYPE;
  908. BAIL_ON_FAILURE(hr);
  909. }
  910. if (!_ADsValue.pOctetList) {
  911. hr = E_FAIL;
  912. BAIL_ON_FAILURE(hr);
  913. }
  914. hr = CoCreateInstance(
  915. CLSID_OctetList,
  916. NULL,
  917. CLSCTX_INPROC_SERVER,
  918. IID_IADsOctetList,
  919. (void **) &pOctetList);
  920. BAIL_ON_FAILURE(hr);
  921. pCurrent = _ADsValue.pOctetList;
  922. while (pCurrent) {
  923. cElements++;
  924. pCurrent = pCurrent->Next;
  925. }
  926. aBound.lLbound = 0;
  927. aBound.cElements = cElements;
  928. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  929. if ( aList == NULL ) {
  930. hr = E_OUTOFMEMORY;
  931. BAIL_ON_FAILURE(hr);
  932. }
  933. pCurrent = _ADsValue.pOctetList;
  934. for ( i = 0; i < (long)cElements; i++ ) {
  935. hr = BinaryToVariant(
  936. pCurrent->Length,
  937. pCurrent->Data,
  938. &varElement);
  939. BAIL_ON_FAILURE(hr);
  940. hr = SafeArrayPutElement( aList, &i, &varElement);
  941. BAIL_ON_FAILURE(hr);
  942. pCurrent = pCurrent->Next;
  943. }
  944. V_VT(&VarDestObject) = VT_ARRAY | VT_BSTR;
  945. V_ARRAY(&VarDestObject) = aList;
  946. hr = pOctetList->put_OctetList(VarDestObject);
  947. BAIL_ON_FAILURE(hr);
  948. hr = pOctetList->QueryInterface(IID_IDispatch, (void**)&pDispatch);
  949. BAIL_ON_FAILURE(hr);
  950. *retval = pDispatch;
  951. error:
  952. VariantClear( &VarDestObject );
  953. if (pOctetList) {
  954. pOctetList->Release();
  955. }
  956. if ( aList ) {
  957. SafeArrayDestroy( aList );
  958. }
  959. RRETURN(hr);
  960. }
  961. STDMETHODIMP
  962. CPropertyValue::put_OctetList(THIS_ IDispatch FAR* pdOctetList)
  963. {
  964. IADsOctetList *pOctetList = NULL;
  965. HRESULT hr = S_OK;
  966. LONG lnAmount= 0;
  967. DWORD dwSLBound = 0;
  968. DWORD dwSUBound = 0;
  969. long i;
  970. PADS_OCTET_LIST pCurrent = NULL;
  971. IDispatch FAR * pDispatch = NULL;
  972. BYTE* pbParameter = NULL;
  973. VARIANT varOctetList;
  974. VARIANT varElement;
  975. VariantInit(&varOctetList);
  976. ClearData();
  977. hr = pdOctetList->QueryInterface(
  978. IID_IADsOctetList,
  979. (void **)&pOctetList
  980. );
  981. BAIL_ON_FAILURE(hr);
  982. _ADsValue.dwType = ADSTYPE_OCTET_LIST;
  983. hr = pOctetList->get_OctetList(&varOctetList);
  984. BAIL_ON_FAILURE(hr);
  985. if(!((V_VT(&varOctetList) & VT_VARIANT) && V_ISARRAY(&varOctetList))) {
  986. return(E_FAIL);
  987. }
  988. if ((V_ARRAY(&varOctetList))->cDims != 1) {
  989. hr = E_FAIL;
  990. BAIL_ON_FAILURE(hr);
  991. }
  992. if ((V_ARRAY(&varOctetList))->rgsabound[0].cElements <= 0) {
  993. hr = E_FAIL;
  994. BAIL_ON_FAILURE(hr);
  995. }
  996. hr = SafeArrayGetLBound(V_ARRAY(&varOctetList),
  997. 1,
  998. (long FAR *)&dwSLBound
  999. );
  1000. BAIL_ON_FAILURE(hr);
  1001. hr = SafeArrayGetUBound(V_ARRAY(&varOctetList),
  1002. 1,
  1003. (long FAR *)&dwSUBound
  1004. );
  1005. BAIL_ON_FAILURE(hr);
  1006. _ADsValue.pOctetList = (PADS_OCTET_LIST)AllocADsMem(sizeof(ADS_OCTET_LIST));
  1007. if (!_ADsValue.pOctetList) {
  1008. hr = E_OUTOFMEMORY;
  1009. BAIL_ON_FAILURE(hr);
  1010. }
  1011. pCurrent = _ADsValue.pOctetList;
  1012. for (i = dwSLBound; i <= (long)dwSUBound; i++) {
  1013. VariantInit(&varElement);
  1014. hr = SafeArrayGetElement(V_ARRAY(&varOctetList),
  1015. (long FAR *)&i,
  1016. &varElement
  1017. );
  1018. BAIL_ON_FAILURE(hr);
  1019. hr = VariantToBinary(
  1020. &varElement,
  1021. &pCurrent->Length,
  1022. &pCurrent->Data
  1023. );
  1024. BAIL_ON_FAILURE(hr);
  1025. if (i != (long)dwSUBound) {
  1026. pCurrent->Next = (PADS_OCTET_LIST)AllocADsMem(sizeof(ADS_OCTET_LIST));
  1027. if (!pCurrent->Next) {
  1028. hr = E_OUTOFMEMORY;
  1029. BAIL_ON_FAILURE(hr);
  1030. }
  1031. pCurrent = pCurrent->Next;
  1032. }
  1033. VariantClear(&varElement);
  1034. }
  1035. pCurrent->Next = NULL;
  1036. error:
  1037. VariantClear(&varOctetList);
  1038. if (pOctetList) {
  1039. pOctetList->Release();
  1040. }
  1041. RRETURN(hr);
  1042. }
  1043. STDMETHODIMP
  1044. CPropertyValue::get_Email(THIS_ IDispatch FAR * FAR *retval)
  1045. {
  1046. HRESULT hr = S_OK;
  1047. IADsEmail* pEmail = NULL;
  1048. IDispatch * pDispatch = NULL;
  1049. if (_ADsValue.dwType != ADSTYPE_EMAIL) {
  1050. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1051. BAIL_ON_FAILURE(hr);
  1052. }
  1053. hr = CoCreateInstance(
  1054. CLSID_Email,
  1055. NULL,
  1056. CLSCTX_INPROC_SERVER,
  1057. IID_IADsEmail,
  1058. (void **) &pEmail);
  1059. BAIL_ON_FAILURE(hr);
  1060. hr = pEmail->put_Type(_ADsValue.Email.Type);
  1061. BAIL_ON_FAILURE(hr);
  1062. hr = pEmail->put_Address(_ADsValue.Email.Address);
  1063. BAIL_ON_FAILURE(hr);
  1064. pEmail->QueryInterface(
  1065. IID_IDispatch,
  1066. (void **) &pDispatch
  1067. );
  1068. BAIL_ON_FAILURE(hr);
  1069. *retval = pDispatch;
  1070. error:
  1071. if (pEmail) {
  1072. pEmail->Release();
  1073. }
  1074. RRETURN(hr);
  1075. }
  1076. STDMETHODIMP
  1077. CPropertyValue::put_Email(THIS_ IDispatch FAR* pdEmail)
  1078. {
  1079. IADsEmail *pEmail = NULL;
  1080. HRESULT hr = S_OK;
  1081. LONG lnType= 0;
  1082. BSTR bstrAddress;
  1083. ClearData();
  1084. hr = pdEmail->QueryInterface(
  1085. IID_IADsEmail,
  1086. (void **)&pEmail
  1087. );
  1088. BAIL_ON_FAILURE(hr);
  1089. hr = pEmail->get_Type(
  1090. &lnType
  1091. );
  1092. BAIL_ON_FAILURE(hr);
  1093. hr = pEmail->get_Address(&bstrAddress);
  1094. BAIL_ON_FAILURE(hr);
  1095. _ADsValue.dwType = ADSTYPE_EMAIL;
  1096. _ADsValue.Email.Type = lnType;
  1097. _ADsValue.Email.Address = AllocADsStr(bstrAddress);
  1098. if (!_ADsValue.Email.Address) {
  1099. hr = E_OUTOFMEMORY;
  1100. BAIL_ON_FAILURE(hr);
  1101. }
  1102. error:
  1103. if (pEmail) {
  1104. pEmail->Release();
  1105. }
  1106. RRETURN(hr);
  1107. }
  1108. STDMETHODIMP
  1109. CPropertyValue::get_Path(THIS_ IDispatch FAR * FAR *retval)
  1110. {
  1111. HRESULT hr = S_OK;
  1112. IADsPath* pPath = NULL;
  1113. IDispatch * pDispatch = NULL;
  1114. if (_ADsValue.dwType != ADSTYPE_PATH) {
  1115. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1116. BAIL_ON_FAILURE(hr);
  1117. }
  1118. if (!_ADsValue.pPath) {
  1119. hr = E_FAIL;
  1120. BAIL_ON_FAILURE(hr);
  1121. }
  1122. hr = CoCreateInstance(
  1123. CLSID_Path,
  1124. NULL,
  1125. CLSCTX_INPROC_SERVER,
  1126. IID_IADsPath,
  1127. (void **) &pPath);
  1128. BAIL_ON_FAILURE(hr);
  1129. hr = pPath->put_Type(_ADsValue.pPath->Type);
  1130. BAIL_ON_FAILURE(hr);
  1131. hr = pPath->put_VolumeName(_ADsValue.pPath->VolumeName);
  1132. BAIL_ON_FAILURE(hr);
  1133. hr = pPath->put_Path(_ADsValue.pPath->Path);
  1134. BAIL_ON_FAILURE(hr);
  1135. pPath->QueryInterface(
  1136. IID_IDispatch,
  1137. (void **) &pDispatch
  1138. );
  1139. BAIL_ON_FAILURE(hr);
  1140. *retval = pDispatch;
  1141. error:
  1142. if (pPath) {
  1143. pPath->Release();
  1144. }
  1145. RRETURN(hr);
  1146. }
  1147. STDMETHODIMP
  1148. CPropertyValue::put_Path(THIS_ IDispatch FAR* pdPath)
  1149. {
  1150. IADsPath *pPath = NULL;
  1151. HRESULT hr = S_OK;
  1152. LONG lnType = 0;
  1153. BSTR bstrVolumeName;
  1154. BSTR bstrPath;
  1155. ClearData();
  1156. hr = pdPath->QueryInterface(
  1157. IID_IADsPath,
  1158. (void **)&pPath
  1159. );
  1160. BAIL_ON_FAILURE(hr);
  1161. hr = pPath->get_Type(
  1162. &lnType
  1163. );
  1164. BAIL_ON_FAILURE(hr);
  1165. hr = pPath->get_VolumeName(
  1166. &bstrVolumeName
  1167. );
  1168. BAIL_ON_FAILURE(hr);
  1169. hr = pPath->get_Path(
  1170. &bstrPath
  1171. );
  1172. BAIL_ON_FAILURE(hr);
  1173. _ADsValue.dwType = ADSTYPE_PATH;
  1174. _ADsValue.pPath = (PADS_PATH)AllocADsMem(sizeof(ADS_PATH));
  1175. if (!_ADsValue.pPath) {
  1176. hr = E_OUTOFMEMORY;
  1177. BAIL_ON_FAILURE(hr);
  1178. }
  1179. _ADsValue.pPath->Type = lnType;
  1180. _ADsValue.pPath->VolumeName = AllocADsStr(bstrVolumeName);
  1181. if (!_ADsValue.pPath->VolumeName) {
  1182. hr = E_OUTOFMEMORY;
  1183. BAIL_ON_FAILURE(hr);
  1184. }
  1185. _ADsValue.pPath->Path = AllocADsStr(bstrPath);
  1186. if (!_ADsValue.pPath->Path) {
  1187. hr = E_OUTOFMEMORY;
  1188. BAIL_ON_FAILURE(hr);
  1189. }
  1190. error:
  1191. if (pPath) {
  1192. pPath->Release();
  1193. }
  1194. RRETURN(hr);
  1195. }
  1196. STDMETHODIMP
  1197. CPropertyValue::get_ReplicaPointer(THIS_ IDispatch FAR * FAR *retval)
  1198. {
  1199. HRESULT hr = S_OK;
  1200. IADsReplicaPointer* pReplicaPointer = NULL;
  1201. IDispatch * pDispatch = NULL;
  1202. IADsNetAddress* pNetAddress = NULL;
  1203. VARIANT VarNetAddress;
  1204. VARIANT VarDest;
  1205. VariantInit(&VarNetAddress);
  1206. VariantInit(&VarDest);
  1207. if (_ADsValue.dwType != ADSTYPE_REPLICAPOINTER) {
  1208. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1209. BAIL_ON_FAILURE(hr);
  1210. }
  1211. if (!_ADsValue.pReplicaPointer) {
  1212. hr = E_FAIL;
  1213. BAIL_ON_FAILURE(hr);
  1214. }
  1215. hr = CoCreateInstance(
  1216. CLSID_ReplicaPointer,
  1217. NULL,
  1218. CLSCTX_INPROC_SERVER,
  1219. IID_IADsReplicaPointer,
  1220. (void **) &pReplicaPointer);
  1221. BAIL_ON_FAILURE(hr);
  1222. hr = pReplicaPointer->put_ReplicaType(_ADsValue.pReplicaPointer->ReplicaType);
  1223. BAIL_ON_FAILURE(hr);
  1224. hr = pReplicaPointer->put_ReplicaNumber(_ADsValue.pReplicaPointer->ReplicaNumber);
  1225. BAIL_ON_FAILURE(hr);
  1226. hr = pReplicaPointer->put_Count(_ADsValue.pReplicaPointer->Count);
  1227. BAIL_ON_FAILURE(hr);
  1228. hr = pReplicaPointer->put_ServerName(_ADsValue.pReplicaPointer->ServerName);
  1229. BAIL_ON_FAILURE(hr);
  1230. ////
  1231. hr = CoCreateInstance(
  1232. CLSID_NetAddress,
  1233. NULL,
  1234. CLSCTX_INPROC_SERVER,
  1235. IID_IADsNetAddress,
  1236. (void **) &pNetAddress);
  1237. BAIL_ON_FAILURE(hr);
  1238. hr = pNetAddress->put_AddressType(_ADsValue.pReplicaPointer->ReplicaAddressHints->AddressType);
  1239. BAIL_ON_FAILURE(hr);
  1240. hr = BinaryToVariant(
  1241. _ADsValue.pReplicaPointer->ReplicaAddressHints->AddressLength,
  1242. _ADsValue.pReplicaPointer->ReplicaAddressHints->Address,
  1243. &VarNetAddress);
  1244. BAIL_ON_FAILURE(hr);
  1245. hr = pNetAddress->put_Address(VarNetAddress);
  1246. BAIL_ON_FAILURE(hr);
  1247. pNetAddress->QueryInterface(
  1248. IID_IDispatch,
  1249. (void **) &pDispatch
  1250. );
  1251. BAIL_ON_FAILURE(hr);
  1252. V_VT(&VarDest) = VT_DISPATCH;
  1253. V_DISPATCH(&VarDest) = pDispatch;
  1254. hr = pReplicaPointer->put_ReplicaAddressHints(VarDest);
  1255. BAIL_ON_FAILURE(hr);
  1256. pReplicaPointer->QueryInterface(
  1257. IID_IDispatch,
  1258. (void **) &pDispatch
  1259. );
  1260. BAIL_ON_FAILURE(hr);
  1261. *retval = pDispatch;
  1262. error:
  1263. VariantClear(&VarNetAddress);
  1264. VariantClear(&VarDest);
  1265. if (pReplicaPointer) {
  1266. pReplicaPointer->Release();
  1267. }
  1268. if (pNetAddress) {
  1269. pNetAddress->Release();
  1270. }
  1271. RRETURN(hr);
  1272. }
  1273. STDMETHODIMP
  1274. CPropertyValue::put_ReplicaPointer(THIS_ IDispatch FAR* pdReplicaPointer)
  1275. {
  1276. IADsReplicaPointer *pReplicaPointer = NULL;
  1277. HRESULT hr = S_OK;
  1278. LONG lnAmount= 0;
  1279. IADsNetAddress *pNetAddress = NULL;
  1280. LONG lnAddressType = 0;
  1281. VARIANT varAddress;
  1282. IDispatch *pdNetAddress = NULL;
  1283. long lnReplicaType;
  1284. long lnReplicaNumber;
  1285. long lnCount;
  1286. BSTR bstrServerName;
  1287. VariantInit(&varAddress);
  1288. ClearData();
  1289. _ADsValue.pReplicaPointer = (PADS_REPLICAPOINTER)AllocADsMem(sizeof(ADS_REPLICAPOINTER));
  1290. if (!_ADsValue.pReplicaPointer) {
  1291. hr = E_OUTOFMEMORY;
  1292. BAIL_ON_FAILURE(hr);
  1293. }
  1294. _ADsValue.pReplicaPointer->ReplicaAddressHints =
  1295. (PADS_NETADDRESS)
  1296. AllocADsMem(
  1297. sizeof(ADS_NETADDRESS)
  1298. );
  1299. if (!(_ADsValue.pReplicaPointer->ReplicaAddressHints)) {
  1300. hr = E_OUTOFMEMORY;
  1301. BAIL_ON_FAILURE(hr);
  1302. }
  1303. hr = pdReplicaPointer->QueryInterface(
  1304. IID_IADsReplicaPointer,
  1305. (void **)&pReplicaPointer
  1306. );
  1307. BAIL_ON_FAILURE(hr);
  1308. hr = pReplicaPointer->get_ReplicaType(
  1309. &lnReplicaType
  1310. );
  1311. BAIL_ON_FAILURE(hr);
  1312. hr = pReplicaPointer->get_ReplicaNumber(
  1313. &lnReplicaNumber
  1314. );
  1315. BAIL_ON_FAILURE(hr);
  1316. hr = pReplicaPointer->get_Count(
  1317. &lnCount
  1318. );
  1319. BAIL_ON_FAILURE(hr);
  1320. hr = pReplicaPointer->get_ServerName(
  1321. &bstrServerName
  1322. );
  1323. BAIL_ON_FAILURE(hr);
  1324. hr = pReplicaPointer->get_ReplicaAddressHints(&varAddress);
  1325. BAIL_ON_FAILURE(hr);
  1326. if (V_VT(&varAddress) != VT_DISPATCH){
  1327. hr = E_FAIL;
  1328. BAIL_ON_FAILURE(hr);
  1329. }
  1330. pdNetAddress = V_DISPATCH(&varAddress);
  1331. hr = pdNetAddress->QueryInterface(
  1332. IID_IADsNetAddress,
  1333. (void **)&pNetAddress
  1334. );
  1335. BAIL_ON_FAILURE(hr);
  1336. hr = pNetAddress->get_AddressType(
  1337. &lnAddressType
  1338. );
  1339. BAIL_ON_FAILURE(hr);
  1340. hr = pNetAddress->get_Address(
  1341. &varAddress
  1342. );
  1343. BAIL_ON_FAILURE(hr);
  1344. hr = VariantToBinary(
  1345. &varAddress,
  1346. &_ADsValue.pReplicaPointer->ReplicaAddressHints->AddressLength,
  1347. &_ADsValue.pReplicaPointer->ReplicaAddressHints->Address
  1348. );
  1349. BAIL_ON_FAILURE(hr);
  1350. _ADsValue.dwType = ADSTYPE_REPLICAPOINTER;
  1351. _ADsValue.pReplicaPointer->ReplicaAddressHints->AddressType = lnAddressType;
  1352. _ADsValue.pReplicaPointer->ReplicaType = lnReplicaType;
  1353. _ADsValue.pReplicaPointer->ReplicaNumber = lnReplicaNumber;
  1354. _ADsValue.pReplicaPointer->Count = lnCount;
  1355. _ADsValue.pReplicaPointer->ServerName = AllocADsStr(bstrServerName);
  1356. if (!_ADsValue.pReplicaPointer->ServerName) {
  1357. hr = E_OUTOFMEMORY;
  1358. BAIL_ON_FAILURE(hr);
  1359. }
  1360. error:
  1361. VariantClear(&varAddress);
  1362. if (pNetAddress) {
  1363. pNetAddress->Release();
  1364. }
  1365. if (pReplicaPointer) {
  1366. pReplicaPointer->Release();
  1367. }
  1368. RRETURN(hr);
  1369. }
  1370. STDMETHODIMP
  1371. CPropertyValue::get_Timestamp(THIS_ IDispatch FAR * FAR *retval)
  1372. {
  1373. HRESULT hr = S_OK;
  1374. IADsTimestamp* pTimestamp = NULL;
  1375. IDispatch * pDispatch = NULL;
  1376. if (_ADsValue.dwType != ADSTYPE_TIMESTAMP) {
  1377. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1378. BAIL_ON_FAILURE(hr);
  1379. }
  1380. hr = CoCreateInstance(
  1381. CLSID_Timestamp,
  1382. NULL,
  1383. CLSCTX_INPROC_SERVER,
  1384. IID_IADsTimestamp,
  1385. (void **) &pTimestamp);
  1386. BAIL_ON_FAILURE(hr);
  1387. hr = pTimestamp->put_WholeSeconds(_ADsValue.Timestamp.WholeSeconds);
  1388. BAIL_ON_FAILURE(hr);
  1389. hr = pTimestamp->put_EventID(_ADsValue.Timestamp.EventID);
  1390. BAIL_ON_FAILURE(hr);
  1391. pTimestamp->QueryInterface(
  1392. IID_IDispatch,
  1393. (void **) &pDispatch
  1394. );
  1395. BAIL_ON_FAILURE(hr);
  1396. *retval = pDispatch;
  1397. error:
  1398. if (pTimestamp) {
  1399. pTimestamp->Release();
  1400. }
  1401. RRETURN(hr);
  1402. }
  1403. STDMETHODIMP
  1404. CPropertyValue::put_Timestamp(THIS_ IDispatch FAR* lnTimestamp)
  1405. {
  1406. IADsTimestamp *pTimestamp = NULL;
  1407. HRESULT hr = S_OK;
  1408. LONG lnWholeSeconds = 0;
  1409. LONG lnEventID = 0;
  1410. ClearData();
  1411. hr = lnTimestamp->QueryInterface(
  1412. IID_IADsTimestamp,
  1413. (void **)&pTimestamp
  1414. );
  1415. BAIL_ON_FAILURE(hr);
  1416. hr = pTimestamp->get_WholeSeconds(
  1417. &lnWholeSeconds
  1418. );
  1419. BAIL_ON_FAILURE(hr);
  1420. hr = pTimestamp->get_EventID(
  1421. &lnEventID
  1422. );
  1423. BAIL_ON_FAILURE(hr);
  1424. _ADsValue.dwType = ADSTYPE_TIMESTAMP;
  1425. _ADsValue.Timestamp.WholeSeconds = lnWholeSeconds;
  1426. _ADsValue.Timestamp.EventID = lnEventID;
  1427. error:
  1428. if (pTimestamp) {
  1429. pTimestamp->Release();
  1430. }
  1431. RRETURN(hr);
  1432. }
  1433. STDMETHODIMP
  1434. CPropertyValue::get_PostalAddress(THIS_ IDispatch FAR * FAR *retval)
  1435. {
  1436. HRESULT hr = S_OK;
  1437. IADsPostalAddress * pPostalAddress = NULL;
  1438. IDispatch * pDispatch = NULL;
  1439. SAFEARRAY *aList = NULL;
  1440. SAFEARRAYBOUND aBound;
  1441. CHAR HUGEP *pArray = NULL;
  1442. long i;
  1443. BSTR bstrAddress;
  1444. DWORD cElements = 0;
  1445. VARIANT VarDestObject;
  1446. VariantInit( &VarDestObject );
  1447. if (_ADsValue.dwType != ADSTYPE_POSTALADDRESS) {
  1448. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1449. BAIL_ON_FAILURE(hr);
  1450. }
  1451. if (!_ADsValue.pPostalAddress) {
  1452. hr = E_FAIL;
  1453. BAIL_ON_FAILURE(hr);
  1454. }
  1455. hr = CoCreateInstance(
  1456. CLSID_PostalAddress,
  1457. NULL,
  1458. CLSCTX_INPROC_SERVER,
  1459. IID_IADsPostalAddress,
  1460. (void **) &pPostalAddress);
  1461. BAIL_ON_FAILURE(hr);
  1462. aBound.lLbound = 0;
  1463. aBound.cElements = 6;
  1464. aList = SafeArrayCreate( VT_BSTR, 1, &aBound );
  1465. if ( aList == NULL ) {
  1466. hr = E_OUTOFMEMORY;
  1467. BAIL_ON_FAILURE(hr);
  1468. }
  1469. for ( i = 0; i < (long) 6; i++ )
  1470. {
  1471. hr = ADsAllocString(
  1472. _ADsValue.pPostalAddress->PostalAddress[i],
  1473. &bstrAddress
  1474. );
  1475. BAIL_ON_FAILURE(hr);
  1476. hr = SafeArrayPutElement( aList, &i, bstrAddress );
  1477. BAIL_ON_FAILURE(hr);
  1478. }
  1479. V_VT(&VarDestObject) = VT_ARRAY | VT_BSTR;
  1480. V_ARRAY(&VarDestObject) = aList;
  1481. hr = pPostalAddress->put_PostalAddress(VarDestObject);
  1482. BAIL_ON_FAILURE(hr);
  1483. hr = pPostalAddress->QueryInterface(IID_IDispatch, (void**)&pDispatch);
  1484. BAIL_ON_FAILURE(hr);
  1485. *retval = pDispatch;
  1486. RRETURN(hr);
  1487. error:
  1488. VariantClear( &VarDestObject );
  1489. if (pPostalAddress) {
  1490. pPostalAddress->Release();
  1491. }
  1492. if (aList) {
  1493. SafeArrayDestroy( aList );
  1494. }
  1495. RRETURN(hr);
  1496. }
  1497. STDMETHODIMP
  1498. CPropertyValue::put_PostalAddress(THIS_ IDispatch FAR* pdPostalAddress)
  1499. {
  1500. IADsPostalAddress *pPostalAddress = NULL;
  1501. HRESULT hr = S_OK;
  1502. LONG lnAmount= 0;
  1503. DWORD dwSLBound = 0;
  1504. DWORD dwSUBound = 0;
  1505. long i;
  1506. IDispatch FAR * pDispatch = NULL;
  1507. BYTE* pbParameter = NULL;
  1508. VARIANT varAddress;
  1509. VARIANT varBstrElement;
  1510. VariantInit(&varAddress);
  1511. ClearData();
  1512. hr = pdPostalAddress->QueryInterface(
  1513. IID_IADsPostalAddress,
  1514. (void **)&pPostalAddress
  1515. );
  1516. BAIL_ON_FAILURE(hr);
  1517. _ADsValue.dwType = ADSTYPE_POSTALADDRESS;
  1518. _ADsValue.pPostalAddress = (PADS_POSTALADDRESS)AllocADsMem(sizeof(ADS_POSTALADDRESS));
  1519. if (!_ADsValue.pPostalAddress) {
  1520. hr = E_OUTOFMEMORY;
  1521. BAIL_ON_FAILURE(hr);
  1522. }
  1523. hr = pPostalAddress->get_PostalAddress(
  1524. &varAddress
  1525. );
  1526. BAIL_ON_FAILURE(hr);
  1527. if(!((V_VT(&varAddress) & VT_VARIANT) && V_ISARRAY(&varAddress))) {
  1528. return(E_FAIL);
  1529. }
  1530. if ((V_ARRAY(&varAddress))->cDims != 1) {
  1531. hr = E_FAIL;
  1532. BAIL_ON_FAILURE(hr);
  1533. }
  1534. if ( ((V_ARRAY(&varAddress))->rgsabound[0].cElements <= 0) ||
  1535. ((V_ARRAY(&varAddress))->rgsabound[0].cElements >6) ) {
  1536. hr = E_FAIL;
  1537. BAIL_ON_FAILURE(hr);
  1538. }
  1539. hr = SafeArrayGetLBound(V_ARRAY(&varAddress),
  1540. 1,
  1541. (long FAR *)&dwSLBound
  1542. );
  1543. BAIL_ON_FAILURE(hr);
  1544. hr = SafeArrayGetUBound(V_ARRAY(&varAddress),
  1545. 1,
  1546. (long FAR *)&dwSUBound
  1547. );
  1548. BAIL_ON_FAILURE(hr);
  1549. for (i = dwSLBound; i <= (long)dwSUBound; i++) {
  1550. VariantInit(&varBstrElement);
  1551. hr = SafeArrayGetElement(V_ARRAY(&varAddress),
  1552. (long FAR *)&i,
  1553. &varBstrElement
  1554. );
  1555. BAIL_ON_FAILURE(hr);
  1556. _ADsValue.pPostalAddress->PostalAddress[i-dwSLBound] = AllocADsStr(V_BSTR(&varBstrElement));
  1557. VariantClear(&varBstrElement);
  1558. if (!_ADsValue.pPostalAddress->PostalAddress[i-dwSLBound]) {
  1559. hr = E_OUTOFMEMORY;
  1560. BAIL_ON_FAILURE(hr);
  1561. }
  1562. }
  1563. RRETURN(S_OK);
  1564. error:
  1565. VariantClear(&varAddress);
  1566. if (pPostalAddress) {
  1567. pPostalAddress->Release();
  1568. }
  1569. RRETURN(hr);
  1570. }
  1571. STDMETHODIMP
  1572. CPropertyValue::get_BackLink(THIS_ IDispatch FAR * FAR *retval)
  1573. {
  1574. HRESULT hr = S_OK;
  1575. IADsBackLink* pBackLink = NULL;
  1576. IDispatch * pDispatch = NULL;
  1577. if (_ADsValue.dwType != ADSTYPE_BACKLINK) {
  1578. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1579. BAIL_ON_FAILURE(hr);
  1580. }
  1581. hr = CoCreateInstance(
  1582. CLSID_BackLink,
  1583. NULL,
  1584. CLSCTX_INPROC_SERVER,
  1585. IID_IADsBackLink,
  1586. (void **) &pBackLink);
  1587. BAIL_ON_FAILURE(hr);
  1588. hr = pBackLink->put_RemoteID(_ADsValue.BackLink.RemoteID);
  1589. BAIL_ON_FAILURE(hr);
  1590. hr = pBackLink->put_ObjectName(_ADsValue.BackLink.ObjectName);
  1591. BAIL_ON_FAILURE(hr);
  1592. pBackLink->QueryInterface(
  1593. IID_IDispatch,
  1594. (void **) &pDispatch
  1595. );
  1596. BAIL_ON_FAILURE(hr);
  1597. *retval = pDispatch;
  1598. error:
  1599. if (pBackLink) {
  1600. pBackLink->Release();
  1601. }
  1602. RRETURN(hr);
  1603. }
  1604. STDMETHODIMP
  1605. CPropertyValue::put_BackLink(THIS_ IDispatch FAR* pdBackLink)
  1606. {
  1607. IADsBackLink *pBackLink = NULL;
  1608. HRESULT hr = S_OK;
  1609. LONG lnRemoteID = 0;
  1610. BSTR bstrObjectName;
  1611. ClearData();
  1612. hr = pdBackLink->QueryInterface(
  1613. IID_IADsBackLink,
  1614. (void **)&pBackLink
  1615. );
  1616. BAIL_ON_FAILURE(hr);
  1617. hr = pBackLink->get_RemoteID(
  1618. &lnRemoteID
  1619. );
  1620. BAIL_ON_FAILURE(hr);
  1621. hr = pBackLink->get_ObjectName(
  1622. &bstrObjectName
  1623. );
  1624. BAIL_ON_FAILURE(hr);
  1625. _ADsValue.dwType = ADSTYPE_BACKLINK;
  1626. _ADsValue.BackLink.RemoteID = lnRemoteID;
  1627. _ADsValue.BackLink.ObjectName = AllocADsStr(bstrObjectName);
  1628. if (!_ADsValue.BackLink.ObjectName ) {
  1629. hr = E_OUTOFMEMORY;
  1630. BAIL_ON_FAILURE(hr);
  1631. }
  1632. error:
  1633. if (pBackLink) {
  1634. pBackLink->Release();
  1635. }
  1636. RRETURN(hr);
  1637. }
  1638. STDMETHODIMP
  1639. CPropertyValue::get_TypedName(THIS_ IDispatch FAR * FAR *retval)
  1640. {
  1641. HRESULT hr = S_OK;
  1642. IADsTypedName* pTypedName = NULL;
  1643. IDispatch * pDispatch = NULL;
  1644. if (_ADsValue.dwType != ADSTYPE_TYPEDNAME) {
  1645. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1646. BAIL_ON_FAILURE(hr);
  1647. }
  1648. if (!_ADsValue.pTypedName) {
  1649. hr = E_FAIL;
  1650. BAIL_ON_FAILURE(hr);
  1651. }
  1652. hr = CoCreateInstance(
  1653. CLSID_TypedName,
  1654. NULL,
  1655. CLSCTX_INPROC_SERVER,
  1656. IID_IADsTypedName,
  1657. (void **) &pTypedName);
  1658. BAIL_ON_FAILURE(hr);
  1659. hr = pTypedName->put_Level(_ADsValue.pTypedName->Level);
  1660. BAIL_ON_FAILURE(hr);
  1661. hr = pTypedName->put_Interval(_ADsValue.pTypedName->Interval);
  1662. BAIL_ON_FAILURE(hr);
  1663. hr = pTypedName->put_ObjectName(_ADsValue.pTypedName->ObjectName);
  1664. BAIL_ON_FAILURE(hr);
  1665. pTypedName->QueryInterface(
  1666. IID_IDispatch,
  1667. (void **) &pDispatch
  1668. );
  1669. BAIL_ON_FAILURE(hr);
  1670. *retval = pDispatch;
  1671. error:
  1672. if (pTypedName) {
  1673. pTypedName->Release();
  1674. }
  1675. RRETURN(hr);
  1676. }
  1677. STDMETHODIMP
  1678. CPropertyValue::put_TypedName(THIS_ IDispatch FAR* pdTypedName)
  1679. {
  1680. IADsTypedName* pTypedName = NULL;
  1681. HRESULT hr = S_OK;
  1682. LONG lnLevel= 0;
  1683. LONG lnInterval= 0;
  1684. BSTR bstrObjectName;
  1685. ClearData();
  1686. hr = pdTypedName->QueryInterface(
  1687. IID_IADsTypedName,
  1688. (void **)&pTypedName
  1689. );
  1690. BAIL_ON_FAILURE(hr);
  1691. hr = pTypedName->get_Level(
  1692. &lnLevel
  1693. );
  1694. BAIL_ON_FAILURE(hr);
  1695. hr = pTypedName->get_Interval(
  1696. &lnInterval
  1697. );
  1698. BAIL_ON_FAILURE(hr);
  1699. hr = pTypedName->get_ObjectName(
  1700. &bstrObjectName
  1701. );
  1702. BAIL_ON_FAILURE(hr);
  1703. _ADsValue.dwType = ADSTYPE_TYPEDNAME;
  1704. _ADsValue.pTypedName = (PADS_TYPEDNAME)AllocADsMem(sizeof(ADS_TYPEDNAME));
  1705. if (!_ADsValue.pTypedName) {
  1706. hr = E_OUTOFMEMORY;
  1707. BAIL_ON_FAILURE(hr);
  1708. }
  1709. _ADsValue.pTypedName->Level= lnLevel;
  1710. _ADsValue.pTypedName->Interval= lnInterval;
  1711. _ADsValue.pTypedName->ObjectName = AllocADsStr(bstrObjectName);
  1712. if (!_ADsValue.pTypedName->ObjectName ) {
  1713. hr = E_OUTOFMEMORY;
  1714. BAIL_ON_FAILURE(hr);
  1715. }
  1716. error:
  1717. if (pTypedName) {
  1718. pTypedName->Release();
  1719. }
  1720. RRETURN(hr);
  1721. }
  1722. STDMETHODIMP
  1723. CPropertyValue::get_Hold(THIS_ IDispatch FAR * FAR *retval)
  1724. {
  1725. HRESULT hr = S_OK;
  1726. IADsHold* pHold = NULL;
  1727. IDispatch * pDispatch = NULL;
  1728. if (_ADsValue.dwType != ADSTYPE_HOLD) {
  1729. hr = E_ADS_CANT_CONVERT_DATATYPE;
  1730. BAIL_ON_FAILURE(hr);
  1731. }
  1732. hr = CoCreateInstance(
  1733. CLSID_Hold,
  1734. NULL,
  1735. CLSCTX_INPROC_SERVER,
  1736. IID_IADsHold,
  1737. (void **) &pHold);
  1738. BAIL_ON_FAILURE(hr);
  1739. hr = pHold->put_Amount(_ADsValue.Hold.Amount);
  1740. BAIL_ON_FAILURE(hr);
  1741. hr = pHold->put_ObjectName(_ADsValue.Hold.ObjectName);
  1742. BAIL_ON_FAILURE(hr);
  1743. pHold->QueryInterface(
  1744. IID_IDispatch,
  1745. (void **) &pDispatch
  1746. );
  1747. BAIL_ON_FAILURE(hr);
  1748. *retval = pDispatch;
  1749. error:
  1750. if (pHold) {
  1751. pHold->Release();
  1752. }
  1753. RRETURN(hr);
  1754. }
  1755. STDMETHODIMP
  1756. CPropertyValue::put_Hold(THIS_ IDispatch FAR* pdHold)
  1757. {
  1758. IADsHold *pHold = NULL;
  1759. HRESULT hr = S_OK;
  1760. LONG lnAmount= 0;
  1761. BSTR bstrObjectName;
  1762. ClearData();
  1763. hr = pdHold->QueryInterface(
  1764. IID_IADsHold,
  1765. (void **)&pHold
  1766. );
  1767. BAIL_ON_FAILURE(hr);
  1768. hr = pHold->get_Amount(
  1769. &lnAmount
  1770. );
  1771. BAIL_ON_FAILURE(hr);
  1772. hr = pHold->get_ObjectName(
  1773. &bstrObjectName
  1774. );
  1775. BAIL_ON_FAILURE(hr);
  1776. _ADsValue.dwType = ADSTYPE_HOLD;
  1777. _ADsValue.Hold.Amount= lnAmount;
  1778. _ADsValue.Hold.ObjectName = AllocADsStr(bstrObjectName);
  1779. if (!_ADsValue.Hold.ObjectName ) {
  1780. hr = E_OUTOFMEMORY;
  1781. BAIL_ON_FAILURE(hr);
  1782. }
  1783. error:
  1784. if (pHold) {
  1785. pHold->Release();
  1786. }
  1787. RRETURN(hr);
  1788. }
  1789. //
  1790. // Helper to get octetString in variant if we have a
  1791. // secDesc stored underneath.
  1792. //
  1793. STDMETHODIMP
  1794. CPropertyValue::getOctetStringFromSecDesc(VARIANT FAR *retval)
  1795. {
  1796. HRESULT hr = S_OK;
  1797. SAFEARRAY *aList = NULL;
  1798. SAFEARRAYBOUND aBound;
  1799. CHAR HUGEP *pArray = NULL;
  1800. ADSVALUE ADsDestValue;
  1801. memset(&ADsDestValue, 0, sizeof(ADSVALUE));
  1802. hr = AdsCopyPropObjToADsValue(
  1803. this,
  1804. &ADsDestValue,
  1805. NULL, // pszServerName,
  1806. NULL, // pCredentials - use default credentials
  1807. TRUE // fNTDSType
  1808. );
  1809. BAIL_ON_FAILURE(hr);
  1810. if (ADsDestValue.dwType != ADSTYPE_OCTET_STRING) {
  1811. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  1812. }
  1813. aBound.lLbound = 0;
  1814. aBound.cElements = ADsDestValue.OctetString.dwLength;
  1815. aList = SafeArrayCreate( VT_UI1, 1, &aBound );
  1816. if ( aList == NULL ) {
  1817. hr = E_OUTOFMEMORY;
  1818. BAIL_ON_FAILURE(hr);
  1819. }
  1820. hr = SafeArrayAccessData( aList, (void HUGEP * FAR *) &pArray);
  1821. BAIL_ON_FAILURE(hr);
  1822. memcpy(pArray, ADsDestValue.OctetString.lpValue, aBound.cElements);
  1823. SafeArrayUnaccessData( aList );
  1824. V_VT(retval) = VT_ARRAY | VT_UI1;
  1825. V_ARRAY(retval) = aList;
  1826. error:
  1827. if (FAILED(hr) && aList) {
  1828. SafeArrayDestroy(aList);
  1829. }
  1830. AdsClear(&ADsDestValue);
  1831. RRETURN(hr);
  1832. }
  1833. //
  1834. // Helper to get SecDesc in variant if we have a
  1835. // octetString stored underneath.
  1836. //
  1837. STDMETHODIMP
  1838. CPropertyValue::getSecurityDescriptorFromOctStr(VARIANT FAR *retval)
  1839. {
  1840. HRESULT hr = S_OK;
  1841. CCredentials dummyCredentials(NULL, NULL, 0);
  1842. hr = ConvertSecDescriptorToVariant(
  1843. NULL, // pszServerName
  1844. dummyCredentials,
  1845. _ADsValue.OctetString.lpValue,
  1846. retval,
  1847. TRUE // NTDS Type
  1848. );
  1849. RRETURN(hr);
  1850. }
  1851. //
  1852. // There has to be a better way to do this. Ideally this code
  1853. // should live in one plae and we should be able to use that
  1854. // everywhere. Currently it lives here as well as in the ldap
  1855. // provider - slight differences though.
  1856. // This comment holds true for DNWithString also - AjayR 4-30-99
  1857. //
  1858. STDMETHODIMP
  1859. CPropertyValue::getDNWithBinary(THIS_ IDispatch FAR * FAR * ppDispatch)
  1860. {
  1861. HRESULT hr = S_OK;
  1862. IADsDNWithBinary *pDNWithBinary = NULL;
  1863. SAFEARRAY *aList = NULL;
  1864. SAFEARRAYBOUND aBound;
  1865. CHAR HUGEP *pArray = NULL;
  1866. BSTR bstrTemp = NULL;
  1867. VARIANT vVar;
  1868. VariantInit(&vVar);
  1869. if (_ADsValue.dwType != ADSTYPE_DN_WITH_BINARY) {
  1870. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  1871. }
  1872. hr = CoCreateInstance(
  1873. CLSID_DNWithBinary,
  1874. NULL,
  1875. CLSCTX_INPROC_SERVER,
  1876. IID_IADsDNWithBinary,
  1877. (void **) &pDNWithBinary
  1878. );
  1879. BAIL_ON_FAILURE(hr);
  1880. if (_ADsValue.pDNWithBinary->pszDNString) {
  1881. hr = ADsAllocString(_ADsValue.pDNWithBinary->pszDNString, &bstrTemp);
  1882. BAIL_ON_FAILURE(hr);
  1883. //
  1884. // Put the value in the object - we can only set BSTR's
  1885. //
  1886. hr = pDNWithBinary->put_DNString(bstrTemp);
  1887. BAIL_ON_FAILURE(hr);
  1888. }
  1889. aBound.lLbound = 0;
  1890. aBound.cElements = _ADsValue.pDNWithBinary->dwLength;
  1891. aList = SafeArrayCreate( VT_UI1, 1, &aBound );
  1892. if ( aList == NULL )
  1893. {
  1894. hr = E_OUTOFMEMORY;
  1895. BAIL_ON_FAILURE(hr);
  1896. }
  1897. hr = SafeArrayAccessData( aList, (void HUGEP * FAR *) &pArray );
  1898. BAIL_ON_FAILURE(hr);
  1899. memcpy( pArray, _ADsValue.pDNWithBinary->lpBinaryValue, aBound.cElements );
  1900. SafeArrayUnaccessData( aList );
  1901. V_VT(&vVar) = VT_ARRAY | VT_UI1;
  1902. V_ARRAY(&vVar) = aList;
  1903. hr = pDNWithBinary->put_BinaryValue(vVar);
  1904. VariantClear(&vVar);
  1905. BAIL_ON_FAILURE(hr);
  1906. hr = pDNWithBinary->QueryInterface(
  1907. IID_IDispatch,
  1908. (void **) ppDispatch
  1909. );
  1910. BAIL_ON_FAILURE(hr);
  1911. error:
  1912. if (pDNWithBinary) {
  1913. pDNWithBinary->Release();
  1914. }
  1915. if (bstrTemp) {
  1916. ADsFreeString(bstrTemp);
  1917. }
  1918. RRETURN(hr);
  1919. }
  1920. STDMETHODIMP
  1921. CPropertyValue::putDNWithBinary(THIS_ IDispatch * pDNWithBinary)
  1922. {
  1923. HRESULT hr = S_OK;
  1924. IADsDNWithBinary * pDNBinary = NULL;
  1925. PADS_DN_WITH_BINARY pDNBin = NULL;
  1926. VARIANT vBinary;
  1927. DWORD dwSUBound = 0;
  1928. DWORD dwSLBound = 0;
  1929. DWORD dwLength = 0;
  1930. BSTR bstrDN = NULL;
  1931. LPBYTE lpByte = NULL;
  1932. CHAR HUGEP *pArray = NULL;
  1933. VariantInit(&vBinary);
  1934. ClearData();
  1935. //
  1936. // This qi ensures that this is a security descriptor
  1937. //
  1938. hr = pDNWithBinary->QueryInterface(
  1939. IID_IADsDNWithBinary,
  1940. (void **) &pDNBinary
  1941. );
  1942. BAIL_ON_FAILURE(hr);
  1943. //
  1944. // Convert to ADSVALUE and then to ldap representation.
  1945. // This way the code to and from LDAP lives in one place.
  1946. //
  1947. hr = pDNBinary->get_BinaryValue(&vBinary);
  1948. BAIL_ON_FAILURE(hr);
  1949. if ((vBinary.vt != (VT_ARRAY | VT_UI1))
  1950. && vBinary.vt != VT_EMPTY) {
  1951. BAIL_ON_FAILURE(hr = E_FAIL);
  1952. }
  1953. hr = pDNBinary->get_DNString(&bstrDN);
  1954. BAIL_ON_FAILURE(hr);
  1955. //
  1956. // Get the byte array in a usable format.
  1957. //
  1958. hr = SafeArrayGetLBound(
  1959. V_ARRAY(&vBinary),
  1960. 1,
  1961. (long FAR *) &dwSLBound
  1962. );
  1963. BAIL_ON_FAILURE(hr);
  1964. hr = SafeArrayGetUBound(
  1965. V_ARRAY(&vBinary),
  1966. 1,
  1967. (long FAR *) &dwSUBound
  1968. );
  1969. BAIL_ON_FAILURE(hr);
  1970. dwLength = dwSUBound - dwSLBound + 1;
  1971. lpByte = (LPBYTE) AllocADsMem(dwLength);
  1972. if (dwLength && !lpByte) {
  1973. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1974. }
  1975. hr = SafeArrayAccessData(
  1976. V_ARRAY(&vBinary),
  1977. (void HUGEP * FAR *) &pArray
  1978. );
  1979. BAIL_ON_FAILURE(hr);
  1980. memcpy(lpByte, pArray, dwLength);
  1981. SafeArrayUnaccessData( V_ARRAY(&vBinary) );
  1982. pDNBin = (PADS_DN_WITH_BINARY) AllocADsMem(sizeof(ADS_DN_WITH_BINARY));
  1983. if (!pDNBin) {
  1984. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1985. }
  1986. if (bstrDN) {
  1987. pDNBin->pszDNString = AllocADsStr(bstrDN);
  1988. if (!pDNBin->pszDNString) {
  1989. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1990. }
  1991. }
  1992. _ADsValue.dwType = ADSTYPE_DN_WITH_BINARY;
  1993. _ADsValue.pDNWithBinary = pDNBin;
  1994. _ADsValue.pDNWithBinary->lpBinaryValue = lpByte;
  1995. _ADsValue.pDNWithBinary->dwLength = dwLength;
  1996. error:
  1997. if (pDNBinary) {
  1998. pDNBinary->Release();
  1999. }
  2000. if (FAILED(hr)) {
  2001. if (lpByte) {
  2002. FreeADsMem(lpByte);
  2003. }
  2004. if (pDNBin) {
  2005. if (pDNBin->pszDNString) {
  2006. FreeADsStr(pDNBin->pszDNString);
  2007. }
  2008. FreeADsMem(pDNBin);
  2009. }
  2010. }
  2011. if (bstrDN) {
  2012. ADsFreeString(bstrDN);
  2013. }
  2014. VariantClear(&vBinary);
  2015. RRETURN(hr);
  2016. }
  2017. STDMETHODIMP
  2018. CPropertyValue::putDNWithString(THIS_ IDispatch * pDNWithString)
  2019. {
  2020. HRESULT hr = S_OK;
  2021. IADsDNWithString *pDNString = NULL;
  2022. PADS_DN_WITH_STRING pDNStr = NULL;
  2023. BSTR bstrStringValue = NULL;
  2024. BSTR bstrDN = NULL;
  2025. ClearData();
  2026. hr = pDNWithString->QueryInterface(
  2027. IID_IADsDNWithString,
  2028. (void **)&pDNString
  2029. );
  2030. BAIL_ON_FAILURE(hr);
  2031. hr = pDNString->get_StringValue(&bstrStringValue);
  2032. BAIL_ON_FAILURE(hr);
  2033. hr = pDNString->get_DNString(&bstrDN);
  2034. BAIL_ON_FAILURE(hr);
  2035. _ADsValue.dwType = ADSTYPE_DN_WITH_STRING;
  2036. pDNStr = (PADS_DN_WITH_STRING) AllocADsMem(sizeof(ADS_DN_WITH_STRING));
  2037. if (!pDNStr) {
  2038. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2039. }
  2040. //
  2041. // Put String value in the DNString struct.
  2042. //
  2043. pDNStr->pszStringValue = AllocADsStr(bstrStringValue);
  2044. if (bstrStringValue && !pDNStr->pszStringValue) {
  2045. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2046. }
  2047. pDNStr->pszDNString = AllocADsStr(bstrDN);
  2048. if (bstrDN && !pDNStr->pszDNString) {
  2049. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  2050. }
  2051. _ADsValue.dwType = ADSTYPE_DN_WITH_STRING;
  2052. _ADsValue.pDNWithString = pDNStr;
  2053. error:
  2054. if (pDNString) {
  2055. pDNString->Release();
  2056. }
  2057. if (bstrStringValue) {
  2058. ADsFreeString(bstrStringValue);
  2059. }
  2060. if (bstrDN) {
  2061. ADsFreeString(bstrDN);
  2062. }
  2063. if (pDNStr && FAILED(hr)) {
  2064. if (pDNStr->pszDNString) {
  2065. FreeADsStr(pDNStr->pszDNString);
  2066. }
  2067. if (pDNStr->pszStringValue) {
  2068. FreeADsMem(pDNStr->pszStringValue);
  2069. }
  2070. FreeADsMem(pDNStr);
  2071. }
  2072. RRETURN(hr);
  2073. }
  2074. STDMETHODIMP
  2075. CPropertyValue::getDNWithString(THIS_ IDispatch FAR * FAR * ppDispatch)
  2076. {
  2077. HRESULT hr = S_OK;
  2078. ADSVALUE AdsValue;
  2079. IADsDNWithString *pDNWithString = NULL;
  2080. IDispatch *pDispatch = NULL;
  2081. BSTR bstrStrVal = NULL;
  2082. BSTR bstrDNVal = NULL;
  2083. if (_ADsValue.dwType != ADSTYPE_DN_WITH_STRING) {
  2084. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2085. }
  2086. hr = CoCreateInstance(
  2087. CLSID_DNWithString,
  2088. NULL,
  2089. CLSCTX_INPROC_SERVER,
  2090. IID_IADsDNWithString,
  2091. (void **) &pDNWithString
  2092. );
  2093. BAIL_ON_FAILURE(hr);
  2094. if (_ADsValue.pDNWithString->pszDNString) {
  2095. hr = ADsAllocString(_ADsValue.pDNWithString->pszDNString, &bstrDNVal);
  2096. BAIL_ON_FAILURE(hr);
  2097. hr = pDNWithString->put_DNString(bstrDNVal);
  2098. BAIL_ON_FAILURE(hr);
  2099. }
  2100. if (_ADsValue.pDNWithString->pszStringValue) {
  2101. hr = ADsAllocString(
  2102. _ADsValue.pDNWithString->pszStringValue,
  2103. &bstrStrVal
  2104. );
  2105. BAIL_ON_FAILURE(hr);
  2106. hr = pDNWithString->put_StringValue(bstrStrVal);
  2107. BAIL_ON_FAILURE(hr);
  2108. }
  2109. hr = pDNWithString->QueryInterface(
  2110. IID_IDispatch,
  2111. (void **) ppDispatch
  2112. );
  2113. BAIL_ON_FAILURE(hr);
  2114. error:
  2115. if (pDNWithString) {
  2116. pDNWithString->Release();
  2117. }
  2118. if (bstrDNVal) {
  2119. ADsFreeString(bstrDNVal);
  2120. }
  2121. if (bstrStrVal) {
  2122. ADsFreeString(bstrStrVal);
  2123. }
  2124. RRETURN(hr);
  2125. }
  2126. STDMETHODIMP
  2127. CPropertyValue::getProvSpecific(THIS_ VARIANT FAR *retval )
  2128. {
  2129. HRESULT hr = S_OK;
  2130. SAFEARRAY *aList = NULL;
  2131. SAFEARRAYBOUND aBound;
  2132. CHAR HUGEP *pArray = NULL;
  2133. if (_ADsValue.dwType != ADSTYPE_PROV_SPECIFIC) {
  2134. RRETURN(E_ADS_CANT_CONVERT_DATATYPE);
  2135. }
  2136. aBound.lLbound = 0;
  2137. aBound.cElements = _ADsValue.ProviderSpecific.dwLength;
  2138. aList = SafeArrayCreate( VT_UI1, 1, &aBound );
  2139. if ( aList == NULL )
  2140. {
  2141. hr = E_OUTOFMEMORY;
  2142. BAIL_ON_FAILURE(hr);
  2143. }
  2144. hr = SafeArrayAccessData( aList, (void HUGEP * FAR *) &pArray );
  2145. BAIL_ON_FAILURE(hr);
  2146. memcpy( pArray,
  2147. _ADsValue.ProviderSpecific.lpValue,
  2148. aBound.cElements );
  2149. SafeArrayUnaccessData( aList );
  2150. V_VT(retval) = VT_ARRAY | VT_UI1;
  2151. V_ARRAY(retval) = aList;
  2152. RRETURN(hr);
  2153. error:
  2154. if ( aList ) {
  2155. SafeArrayDestroy( aList );
  2156. }
  2157. RRETURN_EXP_IF_ERR(hr);
  2158. }
  2159. STDMETHODIMP
  2160. CPropertyValue::putProvSpecific(THIS_ VARIANT VarProvSpecific)
  2161. {
  2162. LONG dwSLBound = 0;
  2163. LONG dwSUBound = 0;
  2164. CHAR HUGEP *pArray = NULL;
  2165. HRESULT hr = S_OK;
  2166. ClearData();
  2167. _ADsValue.dwType = ADSTYPE_PROV_SPECIFIC;
  2168. if( VarProvSpecific.vt != (VT_ARRAY | VT_UI1)) {
  2169. RRETURN(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2170. }
  2171. hr = SafeArrayGetLBound(V_ARRAY(&VarProvSpecific),
  2172. 1,
  2173. (long FAR *) &dwSLBound );
  2174. BAIL_ON_FAILURE(hr);
  2175. hr = SafeArrayGetUBound(V_ARRAY(&VarProvSpecific),
  2176. 1,
  2177. (long FAR *) &dwSUBound );
  2178. BAIL_ON_FAILURE(hr);
  2179. _ADsValue.ProviderSpecific.lpValue = (LPBYTE)AllocADsMem(dwSUBound - dwSLBound + 1);
  2180. if ( _ADsValue.ProviderSpecific.lpValue == NULL) {
  2181. hr = E_OUTOFMEMORY;
  2182. BAIL_ON_FAILURE(hr);
  2183. }
  2184. _ADsValue.ProviderSpecific.dwLength = dwSUBound - dwSLBound + 1;
  2185. hr = SafeArrayAccessData( V_ARRAY(&VarProvSpecific),
  2186. (void HUGEP * FAR *) &pArray );
  2187. BAIL_ON_FAILURE(hr);
  2188. memcpy( _ADsValue.ProviderSpecific.lpValue,
  2189. pArray,
  2190. dwSUBound-dwSLBound+1);
  2191. SafeArrayUnaccessData( V_ARRAY(&VarProvSpecific) );
  2192. error:
  2193. RRETURN_EXP_IF_ERR(hr);
  2194. }
  2195. void
  2196. CPropertyValue::ClearData()
  2197. {
  2198. //
  2199. // For all the types - this works even if the adsvalue is null
  2200. // as adsvalue.dwType = 0 ---> invalid_type does nothing !!!
  2201. //
  2202. AdsClear(&_ADsValue);
  2203. if (_pDispatch) {
  2204. switch (_dwDataType) {
  2205. case VAL_IDISPATCH_SECDESC_ONLY:
  2206. case VAL_IDISPATCH_SECDESC_ALL:
  2207. _pDispatch->Release();
  2208. _pDispatch = NULL;
  2209. _dwDataType = VAL_IDISPATCH_UNKNOWN;
  2210. break;
  2211. default:
  2212. ADsAssert(!"Internal incosistency secdesc ptr but bad type.");
  2213. _pDispatch = NULL;
  2214. _dwDataType = VAL_IDISPATCH_UNKNOWN;
  2215. break;
  2216. } // end switch
  2217. }
  2218. }
  2219. //+------------------------------------------------------------------------
  2220. //
  2221. // Function: CPropertyValue::GetObjectProperty
  2222. //
  2223. // Synopsis: Gets the values stored in this PropertyValue object. The
  2224. // value returned is determined by the value requested in lnContorlCode.
  2225. // For now though we will only support ADSTYPE_UNKNOWN in which case we
  2226. // get the info from the object itself. Alternatively the type should match
  2227. // that which is in the object.
  2228. //
  2229. //
  2230. // Arguments: lnControlCode - ADSTYPE_INVALID implies whatever we have
  2231. // - anything else implies we return the type.
  2232. // pvProp - the output value goes into this.
  2233. //
  2234. //
  2235. //-------------------------------------------------------------------------
  2236. STDMETHODIMP
  2237. CPropertyValue::GetObjectProperty(
  2238. THIS_ long *lnControlCode,
  2239. VARIANT *pvProp
  2240. )
  2241. {
  2242. HRESULT hr = S_OK;
  2243. ADSTYPE dwTypeAsked = ADSTYPE_INVALID;
  2244. ADsAssert(pvProp);
  2245. ADsAssert(lnControlCode);
  2246. if (*lnControlCode == ADSTYPE_UNKNOWN) {
  2247. dwTypeAsked = _ADsValue.dwType;
  2248. } else {
  2249. dwTypeAsked = (ADSTYPE)*lnControlCode;
  2250. }
  2251. *lnControlCode = dwTypeAsked;
  2252. switch (dwTypeAsked) {
  2253. case ADSTYPE_INVALID:
  2254. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2255. break;
  2256. case ADSTYPE_DN_STRING :
  2257. pvProp->vt = VT_BSTR;
  2258. hr = get_DNString(&(pvProp->bstrVal));
  2259. break;
  2260. case ADSTYPE_CASE_EXACT_STRING :
  2261. pvProp->vt = VT_BSTR;
  2262. hr = get_CaseExactString(&(pvProp->bstrVal));
  2263. break;
  2264. case ADSTYPE_CASE_IGNORE_STRING :
  2265. pvProp->vt = VT_BSTR;
  2266. hr = get_CaseIgnoreString(&(pvProp->bstrVal));
  2267. break;
  2268. case ADSTYPE_PRINTABLE_STRING :
  2269. pvProp->vt = VT_BSTR;
  2270. hr = get_PrintableString(&(pvProp->bstrVal));
  2271. break;
  2272. case ADSTYPE_NUMERIC_STRING :
  2273. pvProp->vt = VT_BSTR;
  2274. hr = get_NumericString(&(pvProp->bstrVal));
  2275. break;
  2276. case ADSTYPE_BOOLEAN :
  2277. {
  2278. LONG lnVal = 0;
  2279. pvProp->vt = VT_BOOL;
  2280. hr = get_Boolean(&(lnVal));
  2281. if (SUCCEEDED(hr)) {
  2282. pvProp->boolVal = lnVal ? VARIANT_TRUE : VARIANT_FALSE;
  2283. }
  2284. }
  2285. break;
  2286. case ADSTYPE_INTEGER :
  2287. pvProp->vt = VT_I4;
  2288. hr = get_Integer(&(pvProp->lVal));
  2289. break;
  2290. case ADSTYPE_OCTET_STRING :
  2291. hr = get_OctetString(pvProp);
  2292. if (hr == E_ADS_CANT_CONVERT_DATATYPE) {
  2293. //
  2294. // Try and see if it is a SD and convert
  2295. //
  2296. if (_ADsValue.dwType == ADSTYPE_NT_SECURITY_DESCRIPTOR) {
  2297. hr = getOctetStringFromSecDesc(pvProp);
  2298. }
  2299. }
  2300. break;
  2301. case ADSTYPE_PROV_SPECIFIC :
  2302. hr = getProvSpecific(pvProp);
  2303. break;
  2304. case ADSTYPE_UTC_TIME :
  2305. pvProp->vt = VT_DATE;
  2306. hr = get_UTCTime(&(pvProp->date));
  2307. break;
  2308. case ADSTYPE_LARGE_INTEGER :
  2309. pvProp->vt = VT_DISPATCH;
  2310. hr = get_LargeInteger(&(pvProp->pdispVal));
  2311. break;
  2312. case ADSTYPE_OBJECT_CLASS :
  2313. pvProp->vt = VT_DISPATCH;
  2314. hr = E_ADS_CANT_CONVERT_DATATYPE;
  2315. break;
  2316. case ADSTYPE_CASEIGNORE_LIST :
  2317. pvProp->vt = VT_DISPATCH;
  2318. hr = get_CaseIgnoreList(&(pvProp->pdispVal));
  2319. break;
  2320. case ADSTYPE_OCTET_LIST :
  2321. pvProp->vt = VT_DISPATCH;
  2322. hr = get_OctetList(&(pvProp->pdispVal));
  2323. break;
  2324. case ADSTYPE_PATH :
  2325. pvProp->vt = VT_DISPATCH;
  2326. hr = get_Path(&(pvProp->pdispVal));
  2327. break;
  2328. case ADSTYPE_POSTALADDRESS :
  2329. pvProp->vt = VT_DISPATCH;
  2330. hr = get_PostalAddress(&(pvProp->pdispVal));
  2331. break;
  2332. case ADSTYPE_TIMESTAMP :
  2333. pvProp->vt = VT_DISPATCH;
  2334. hr = get_Timestamp(&(pvProp->pdispVal));
  2335. break;
  2336. case ADSTYPE_BACKLINK :
  2337. pvProp->vt = VT_DISPATCH;
  2338. hr = get_BackLink(&(pvProp->pdispVal));
  2339. break;
  2340. case ADSTYPE_TYPEDNAME :
  2341. pvProp->vt = VT_DISPATCH;
  2342. hr = get_TypedName(&(pvProp->pdispVal));
  2343. break;
  2344. case ADSTYPE_HOLD :
  2345. pvProp->vt = VT_DISPATCH;
  2346. hr = get_Hold(&(pvProp->pdispVal));
  2347. break;
  2348. case ADSTYPE_NETADDRESS :
  2349. pvProp->vt = VT_DISPATCH;
  2350. hr = get_NetAddress(&(pvProp->pdispVal));
  2351. break;
  2352. case ADSTYPE_REPLICAPOINTER :
  2353. pvProp->vt = VT_DISPATCH;
  2354. hr = get_ReplicaPointer(&(pvProp->pdispVal));
  2355. break;
  2356. case ADSTYPE_FAXNUMBER :
  2357. pvProp->vt = VT_DISPATCH;
  2358. hr = get_FaxNumber(&(pvProp->pdispVal));
  2359. break;
  2360. case ADSTYPE_EMAIL :
  2361. pvProp->vt = VT_DISPATCH;
  2362. hr = get_Email(&(pvProp->pdispVal));
  2363. break;
  2364. case ADSTYPE_NT_SECURITY_DESCRIPTOR :
  2365. pvProp->vt = VT_DISPATCH;
  2366. hr = get_SecurityDescriptor(&(pvProp->pdispVal));
  2367. if (hr == E_ADS_CANT_CONVERT_DATATYPE) {
  2368. //
  2369. // Try and see if it is an OctetString needed as SecDesc
  2370. //
  2371. if (_ADsValue.dwType == ADSTYPE_OCTET_STRING) {
  2372. hr = getSecurityDescriptorFromOctStr(pvProp);
  2373. }
  2374. }
  2375. break;
  2376. case ADSTYPE_DN_WITH_BINARY:
  2377. pvProp->vt = VT_DISPATCH;
  2378. hr = getDNWithBinary(&(pvProp->pdispVal));
  2379. break;
  2380. case ADSTYPE_DN_WITH_STRING:
  2381. pvProp->vt = VT_DISPATCH;
  2382. hr = getDNWithString(&(pvProp->pdispVal));
  2383. break;
  2384. case ADSTYPE_UNKNOWN :
  2385. hr = E_ADS_CANT_CONVERT_DATATYPE;
  2386. break;
  2387. default:
  2388. // We should never be here
  2389. hr = E_ADS_BAD_PARAMETER;
  2390. break;
  2391. }
  2392. error:
  2393. RRETURN(hr);
  2394. }
  2395. STDMETHODIMP
  2396. CPropertyValue::PutObjectProperty(
  2397. THIS_ long lnControlCode,
  2398. VARIANT varObj
  2399. )
  2400. {
  2401. HRESULT hr = S_OK;
  2402. VARIANT *pvVar = &varObj;
  2403. if (lnControlCode == ADSTYPE_UNKNOWN
  2404. || lnControlCode == ADSTYPE_INVALID) {
  2405. BAIL_ON_FAILURE(hr=E_ADS_BAD_PARAMETER);
  2406. }
  2407. if (V_VT(pvVar) == (VT_BYREF|VT_VARIANT)) {
  2408. //
  2409. // The value is being passed in byref so we need to
  2410. // deref it for vbs stuff to work
  2411. //
  2412. pvVar = V_VARIANTREF(&varObj);
  2413. }
  2414. switch (lnControlCode) {
  2415. case ADSTYPE_INVALID:
  2416. BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER);
  2417. break;
  2418. case ADSTYPE_DN_STRING :
  2419. if (pvVar->vt != VT_BSTR) {
  2420. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2421. }
  2422. hr = put_DNString(pvVar->bstrVal);
  2423. break;
  2424. case ADSTYPE_CASE_EXACT_STRING :
  2425. if (pvVar->vt != VT_BSTR) {
  2426. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2427. }
  2428. hr = put_CaseExactString(pvVar->bstrVal);
  2429. break;
  2430. case ADSTYPE_CASE_IGNORE_STRING :
  2431. if (pvVar->vt != VT_BSTR) {
  2432. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2433. }
  2434. hr = put_CaseIgnoreString(pvVar->bstrVal);
  2435. break;
  2436. case ADSTYPE_PRINTABLE_STRING :
  2437. if (pvVar->vt != VT_BSTR) {
  2438. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2439. }
  2440. hr = put_PrintableString(pvVar->bstrVal);
  2441. break;
  2442. case ADSTYPE_NUMERIC_STRING :
  2443. if (pvVar->vt != VT_BSTR) {
  2444. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2445. }
  2446. hr = put_NumericString(pvVar->bstrVal);
  2447. break;
  2448. case ADSTYPE_BOOLEAN :
  2449. if (pvVar->vt != VT_BOOL) {
  2450. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2451. }
  2452. hr = put_Boolean((pvVar->boolVal == VARIANT_TRUE) ? TRUE : FALSE);
  2453. break;
  2454. case ADSTYPE_INTEGER :
  2455. if (pvVar->vt != VT_I4) {
  2456. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2457. }
  2458. hr = put_Integer(pvVar->lVal);
  2459. break;
  2460. case ADSTYPE_OCTET_STRING :
  2461. hr = put_OctetString(*pvVar);
  2462. break;
  2463. case ADSTYPE_PROV_SPECIFIC :
  2464. hr = putProvSpecific(varObj);
  2465. break;
  2466. case ADSTYPE_UTC_TIME :
  2467. if (pvVar->vt != VT_DATE) {
  2468. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2469. }
  2470. hr = put_UTCTime(pvVar->date);
  2471. break;
  2472. case ADSTYPE_LARGE_INTEGER :
  2473. if (pvVar->vt != VT_DISPATCH) {
  2474. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2475. }
  2476. hr = put_LargeInteger(pvVar->pdispVal);
  2477. break;
  2478. case ADSTYPE_OBJECT_CLASS :
  2479. hr = E_ADS_CANT_CONVERT_DATATYPE;
  2480. break;
  2481. case ADSTYPE_CASEIGNORE_LIST :
  2482. if (pvVar->vt != VT_DISPATCH) {
  2483. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2484. }
  2485. hr = put_CaseIgnoreList(pvVar->pdispVal);
  2486. break;
  2487. case ADSTYPE_OCTET_LIST :
  2488. if (pvVar->vt != VT_DISPATCH) {
  2489. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2490. }
  2491. hr = put_OctetList(pvVar->pdispVal);
  2492. break;
  2493. case ADSTYPE_PATH :
  2494. if (pvVar->vt != VT_DISPATCH) {
  2495. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2496. }
  2497. hr = put_Path(pvVar->pdispVal);
  2498. break;
  2499. case ADSTYPE_POSTALADDRESS :
  2500. if (pvVar->vt != VT_DISPATCH) {
  2501. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2502. }
  2503. hr = put_PostalAddress(pvVar->pdispVal);
  2504. break;
  2505. case ADSTYPE_TIMESTAMP :
  2506. if (pvVar->vt != VT_DISPATCH){
  2507. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2508. }
  2509. hr = put_Timestamp(pvVar->pdispVal);
  2510. break;
  2511. case ADSTYPE_BACKLINK :
  2512. if (pvVar->vt != VT_DISPATCH) {
  2513. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2514. }
  2515. hr = put_BackLink(pvVar->pdispVal);
  2516. break;
  2517. case ADSTYPE_TYPEDNAME :
  2518. if (pvVar->vt != VT_DISPATCH) {
  2519. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2520. }
  2521. hr = put_TypedName(pvVar->pdispVal);
  2522. break;
  2523. case ADSTYPE_HOLD :
  2524. if (pvVar->vt != VT_DISPATCH) {
  2525. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2526. }
  2527. hr = put_Hold(pvVar->pdispVal);
  2528. break;
  2529. case ADSTYPE_NETADDRESS :
  2530. if (pvVar->vt != VT_DISPATCH) {
  2531. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2532. }
  2533. hr = put_NetAddress(pvVar->pdispVal);
  2534. break;
  2535. case ADSTYPE_REPLICAPOINTER :
  2536. if (pvVar->vt != VT_DISPATCH) {
  2537. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2538. }
  2539. hr = put_ReplicaPointer(pvVar->pdispVal);
  2540. break;
  2541. case ADSTYPE_FAXNUMBER :
  2542. if (pvVar->vt != VT_DISPATCH) {
  2543. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2544. }
  2545. hr = put_FaxNumber(pvVar->pdispVal);
  2546. break;
  2547. case ADSTYPE_EMAIL :
  2548. if (pvVar->vt != VT_DISPATCH) {
  2549. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2550. }
  2551. hr = put_Email(pvVar->pdispVal);
  2552. break;
  2553. case ADSTYPE_NT_SECURITY_DESCRIPTOR :
  2554. if (pvVar->vt != VT_DISPATCH) {
  2555. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2556. }
  2557. hr = put_SecurityDescriptor(pvVar->pdispVal);
  2558. break;
  2559. case ADSTYPE_DN_WITH_BINARY :
  2560. if (pvVar->vt != VT_DISPATCH) {
  2561. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2562. }
  2563. hr = putDNWithBinary(pvVar->pdispVal);
  2564. break;
  2565. case ADSTYPE_DN_WITH_STRING :
  2566. if (pvVar->vt != VT_DISPATCH) {
  2567. BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
  2568. }
  2569. hr = putDNWithString(pvVar->pdispVal);
  2570. break;
  2571. case ADSTYPE_UNKNOWN :
  2572. hr = E_ADS_CANT_CONVERT_DATATYPE;
  2573. break;
  2574. default:
  2575. hr = E_ADS_BAD_PARAMETER;
  2576. break;
  2577. }
  2578. error:
  2579. RRETURN (hr);
  2580. }