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.

1074 lines
23 KiB

  1. #include "dsbase.hxx"
  2. HRESULT PackGuid2Variant(
  3. GUID guidData,
  4. VARIANT * pvData
  5. )
  6. {
  7. SAFEARRAYBOUND size; // Get rid of 16
  8. SAFEARRAY FAR *psa;
  9. CHAR HUGEP *pArray=NULL;
  10. LONG dwSLBound = 0;
  11. LONG dwSUBound = 0;
  12. HRESULT hr;
  13. size.cElements = sizeof(GUID);
  14. size.lLbound = 0;
  15. if (!pvData) {
  16. return(E_FAIL);
  17. }
  18. psa = SafeArrayCreate(VT_UI1, 1, &size);
  19. if (!psa) {
  20. return(E_OUTOFMEMORY);
  21. }
  22. hr = SafeArrayAccessData( psa, (void HUGEP * FAR *) &pArray );
  23. RETURN_ON_FAILURE(hr);
  24. memcpy( pArray, &guidData, size.cElements );
  25. SafeArrayUnaccessData( psa );
  26. V_VT(pvData) = VT_ARRAY | VT_UI1;
  27. V_ARRAY(pvData) = psa;
  28. return(S_OK);
  29. }
  30. HRESULT PackGuidArray2Variant(
  31. GUID *guidData,
  32. ULONG cguids,
  33. VARIANT * pvData
  34. )
  35. {
  36. SAFEARRAYBOUND size, sizeguid;
  37. SAFEARRAY FAR *psa, *psaOctetString;
  38. CHAR HUGEP *pArray=NULL;
  39. LONG dwSLBound = 0;
  40. LONG dwSUBound = 0;
  41. HRESULT hr;
  42. VARIANT *var;
  43. ULONG i;
  44. if (!pvData) {
  45. return(E_FAIL);
  46. }
  47. var = new VARIANT[cguids];
  48. if (!var)
  49. return E_OUTOFMEMORY;
  50. sizeguid.cElements = cguids;
  51. sizeguid.lLbound = 0;
  52. psa = SafeArrayCreate(VT_VARIANT, 1, &sizeguid);
  53. if (!psa)
  54. return E_OUTOFMEMORY;
  55. size.cElements = sizeof(GUID);
  56. size.lLbound = 0;
  57. for (i = 0; i < cguids; i++) {
  58. psaOctetString = SafeArrayCreate(VT_UI1, 1, &size);
  59. if (!psaOctetString) {
  60. return(E_OUTOFMEMORY);
  61. }
  62. hr = SafeArrayAccessData( psaOctetString, (void HUGEP * FAR *) &pArray );
  63. RETURN_ON_FAILURE(hr);
  64. memcpy( pArray, &(guidData[i]), size.cElements );
  65. SafeArrayUnaccessData( psaOctetString );
  66. V_VT(var+i) = VT_ARRAY | VT_UI1;
  67. V_ARRAY(var+i) = psaOctetString;
  68. SafeArrayPutElement(psa, (LONG *)&i, var+i);
  69. RETURN_ON_FAILURE(hr);
  70. }
  71. V_VT(pvData) = VT_ARRAY | VT_VARIANT;
  72. V_ARRAY(pvData) = psa;
  73. return(S_OK);
  74. }
  75. HRESULT PackDWORDArray2Variant(
  76. DWORD * pdwData,
  77. ULONG cdword,
  78. VARIANT * pvData
  79. )
  80. {
  81. SAFEARRAYBOUND size, sizedword;
  82. SAFEARRAY FAR *psa;
  83. LONG dwSLBound = 0;
  84. LONG dwSUBound = 0;
  85. VARIANT *var = NULL;
  86. ULONG i;
  87. if (!pvData) {
  88. return(E_FAIL);
  89. }
  90. var = new VARIANT[cdword];
  91. if (!var)
  92. return E_OUTOFMEMORY;
  93. sizedword.cElements = cdword;
  94. sizedword.lLbound = 0;
  95. psa = SafeArrayCreate(VT_VARIANT, 1, &sizedword);
  96. if (!psa)
  97. return E_OUTOFMEMORY;
  98. size.cElements = 1;
  99. size.lLbound = 0;
  100. for (i = 0; i < cdword; i++) {
  101. V_VT(var+i) = VT_I4;
  102. var[i].lVal = pdwData[i];
  103. SafeArrayPutElement(psa, (LONG *)&i, var+i);
  104. }
  105. V_VT(pvData) = VT_ARRAY | VT_VARIANT;
  106. V_ARRAY(pvData) = psa;
  107. return(S_OK);
  108. }
  109. HRESULT GetPropertyListAlloc(IADs *pADs,
  110. LPOLESTR pszPropName,
  111. DWORD *pCount,
  112. LPOLESTR **ppList)
  113. {
  114. LONG dwSLBound = 0;
  115. LONG dwSUBound = 0;
  116. VARIANT v;
  117. LONG i;
  118. HRESULT hr = S_OK;
  119. VARIANT var;
  120. *pCount = 0;
  121. *ppList = NULL;
  122. VariantInit(&var);
  123. hr = pADs->Get(pszPropName, &var);
  124. if (hr == E_ADS_PROPERTY_NOT_FOUND)
  125. {
  126. return S_OK;
  127. }
  128. RETURN_ON_FAILURE(hr);
  129. if(!((V_VT(&var) & VT_VARIANT)))
  130. {
  131. return(E_FAIL);
  132. }
  133. //
  134. // The following is a work around
  135. //
  136. if (!V_ISARRAY(&var))
  137. {
  138. (*ppList) = (LPOLESTR *) CoTaskMemAlloc(sizeof(LPOLESTR));
  139. *pCount = 1;
  140. *(*ppList) = (LPOLESTR) CoTaskMemAlloc (sizeof(WCHAR) * (wcslen(var.bstrVal)+1));
  141. wcscpy (*(*ppList), var.bstrVal);
  142. VariantClear(&var);
  143. return S_OK;
  144. }
  145. //
  146. // Check that there is only one dimension in this array
  147. //
  148. if ((V_ARRAY(&var))->cDims != 1)
  149. {
  150. return E_FAIL;
  151. }
  152. //
  153. // Check that there is atleast one element in this array
  154. //
  155. if ((V_ARRAY(&var))->rgsabound[0].cElements == 0)
  156. {
  157. *ppList = NULL;
  158. return S_OK; // was E_FAIL;
  159. }
  160. //
  161. // We know that this is a valid single dimension array
  162. //
  163. hr = SafeArrayGetLBound(V_ARRAY(&var),
  164. 1,
  165. (long FAR *)&dwSLBound
  166. );
  167. RETURN_ON_FAILURE(hr);
  168. hr = SafeArrayGetUBound(V_ARRAY(&var),
  169. 1,
  170. (long FAR *)&dwSUBound
  171. );
  172. RETURN_ON_FAILURE(hr);
  173. (*ppList) = (LPOLESTR *) CoTaskMemAlloc(sizeof(LPOLESTR)*(dwSUBound-dwSLBound+1));
  174. for (i = dwSLBound; i <= dwSUBound; i++)
  175. {
  176. VariantInit(&v);
  177. hr = SafeArrayGetElement(V_ARRAY(&var),
  178. (long FAR *)&i,
  179. &v
  180. );
  181. if (FAILED(hr))
  182. {
  183. continue;
  184. }
  185. if (i <= dwSUBound)
  186. {
  187. (*ppList)[*pCount] = (LPOLESTR) CoTaskMemAlloc
  188. (sizeof (WCHAR) * (wcslen(v.bstrVal) + 1));
  189. wcscpy ((*ppList)[*pCount], v.bstrVal);
  190. VariantClear(&v);
  191. (*pCount)++;
  192. }
  193. }
  194. VariantClear(&var);
  195. return(S_OK);
  196. }
  197. HRESULT SetPropertyGuid (IADs *pADs, LPOLESTR pszPropName, GUID guidPropVal)
  198. {
  199. VARIANT var;
  200. HRESULT hr;
  201. VariantInit(&var);
  202. hr = PackGuid2Variant(guidPropVal, &var);
  203. hr = pADs->Put(pszPropName, var);
  204. VariantClear(&var);
  205. return hr;
  206. }
  207. // replacing ADsBuildVarArrStr b'cos of mem leaks.
  208. HRESULT
  209. BuildVarArrayStr(
  210. LPWSTR *lppPathNames,
  211. DWORD dwPathNames,
  212. VARIANT * pVar
  213. )
  214. {
  215. VARIANT v;
  216. SAFEARRAYBOUND sabNewArray;
  217. DWORD i;
  218. SAFEARRAY *psa = NULL;
  219. HRESULT hr = E_FAIL;
  220. if (!pVar) {
  221. hr = E_ADS_BAD_PARAMETER;
  222. goto Fail;
  223. }
  224. VariantInit(pVar);
  225. sabNewArray.cElements = dwPathNames;
  226. sabNewArray.lLbound = 0;
  227. psa = SafeArrayCreate(VT_VARIANT, 1, &sabNewArray);
  228. if (!psa) {
  229. goto Fail;
  230. }
  231. for (i = 0; i < dwPathNames; i++) {
  232. VariantInit(&v);
  233. V_VT(&v) = VT_BSTR;
  234. V_BSTR(&v) = SysAllocString(*(lppPathNames + i));
  235. hr = SafeArrayPutElement(psa,
  236. (long FAR *)&i,
  237. &v
  238. );
  239. SysFreeString(v.bstrVal);
  240. VariantClear(&v);
  241. if (FAILED(hr)) {
  242. goto Fail;
  243. }
  244. }
  245. V_VT(pVar) = VT_ARRAY | VT_VARIANT;
  246. V_ARRAY(pVar) = psa;
  247. return(ResultFromScode(S_OK));
  248. Fail:
  249. if (psa) {
  250. SafeArrayDestroy(psa);
  251. }
  252. return(E_FAIL);
  253. }
  254. HRESULT SetPropertyList(IADs *pADs, LPWSTR pszPropName, DWORD Count,
  255. LPWSTR *pList)
  256. {
  257. VARIANT Var;
  258. HRESULT hr;
  259. VariantInit(&Var);
  260. hr = BuildVarArrayStr(pList, Count, &Var);
  261. hr = pADs->Put(pszPropName, Var);
  262. VariantClear(&Var);
  263. return hr;
  264. }
  265. HRESULT SetPropertyListMerge(IADs *pADs, LPWSTR pszPropName, DWORD Count,
  266. LPWSTR *pList)
  267. {
  268. HRESULT hr = S_OK;
  269. LPOLESTR *pszProps = NULL, *pszMergedProps = NULL;
  270. DWORD cProps = 0, cMergedProps = 0;
  271. DWORD i, j;
  272. hr = GetPropertyListAlloc(pADs, pszPropName, &cProps, &pszProps);
  273. RETURN_ON_FAILURE(hr);
  274. // get the property already stored.
  275. pszMergedProps = (LPOLESTR *)CoTaskMemAlloc(sizeof(LPOLESTR)*(cProps+Count));
  276. for (i = 0; i < cProps; i++)
  277. pszMergedProps[i] = pszProps[i];
  278. // copy all the prop got.
  279. cMergedProps = cProps;
  280. for (j = 0; j < Count; j++) {
  281. for (i = 0; i < cProps; i++) {
  282. if (wcscmp(pList[j], pszMergedProps[i]) == 0) {
  283. break;
  284. }
  285. }
  286. // if this element was not found already add it.
  287. if (i == cProps)
  288. pszMergedProps[cMergedProps++] = pList[j];
  289. }
  290. hr = SetPropertyList(pADs, pszPropName, cMergedProps, pszMergedProps);
  291. for (i = 0; i < cProps; i++)
  292. CoTaskMemFree(pszProps[i]);
  293. CoTaskMemFree(pszProps);
  294. CoTaskMemFree(pszMergedProps);
  295. return hr;
  296. }
  297. HRESULT GetPropertyGuid(IADs *pADs, LPOLESTR pszPropName, GUID *pguidPropVal)
  298. {
  299. VARIANT varGet;
  300. HRESULT hr;
  301. VariantInit(&varGet);
  302. hr = pADs->Get(pszPropName, &varGet);
  303. RETURN_ON_FAILURE(hr);
  304. hr = UnpackGuidFromVariant(varGet, pguidPropVal);
  305. VariantClear(&varGet);
  306. return hr;
  307. }
  308. HRESULT UnpackGuidFromVariant(VARIANT varGet, GUID *pguidPropVal)
  309. {
  310. HRESULT hr=S_OK;
  311. SAFEARRAY FAR *psa;
  312. CHAR HUGEP *pArray=NULL;
  313. if (V_VT(&varGet) != (VT_ARRAY | VT_UI1))
  314. return E_FAIL;
  315. if ((V_ARRAY(&varGet))->rgsabound[0].cElements != sizeof(GUID))
  316. return E_FAIL;
  317. psa = V_ARRAY(&varGet);
  318. hr = SafeArrayAccessData( psa, (void HUGEP * FAR *) &pArray );
  319. RETURN_ON_FAILURE(hr);
  320. memcpy( pguidPropVal, pArray, sizeof(GUID)); // check for size
  321. SafeArrayUnaccessData( psa );
  322. // BUGBUG:: any more freeing to do ??
  323. return hr;
  324. }
  325. // assumption that this is going to be a variant structure with
  326. HRESULT GetPropertyListAllocGuid(IADs *pADs,
  327. LPOLESTR pszPropName,
  328. DWORD *pCount,
  329. GUID **ppList)
  330. {
  331. LONG dwSLBound = 0;
  332. LONG dwSUBound = 0;
  333. VARIANT v;
  334. LONG i;
  335. HRESULT hr = S_OK;
  336. VARIANT var;
  337. *pCount = 0;
  338. VariantInit(&var);
  339. hr = pADs->Get(pszPropName, &var);
  340. if (hr == E_ADS_PROPERTY_NOT_FOUND)
  341. {
  342. return S_OK;
  343. }
  344. RETURN_ON_FAILURE(hr);
  345. //
  346. // The following is a work around
  347. //
  348. if (V_VT(&var) == (VT_ARRAY | VT_UI1))
  349. {
  350. (*ppList) = (GUID *) CoTaskMemAlloc(sizeof(GUID));
  351. *pCount = 1;
  352. UnpackGuidFromVariant(var, *ppList);
  353. VariantClear(&var);
  354. return S_OK;
  355. }
  356. //
  357. // Check that there is only one dimension in this array
  358. //
  359. if ((V_ARRAY(&var))->cDims != 1)
  360. {
  361. return E_FAIL;
  362. }
  363. //
  364. // Check that there is atleast one element in this array
  365. //
  366. if ((V_ARRAY(&var))->rgsabound[0].cElements == 0)
  367. {
  368. *ppList = NULL;
  369. return S_OK; // was E_FAIL;
  370. }
  371. //
  372. // We know that this is a valid single dimension array
  373. //
  374. hr = SafeArrayGetLBound(V_ARRAY(&var),
  375. 1,
  376. (long FAR *)&dwSLBound
  377. );
  378. RETURN_ON_FAILURE(hr);
  379. hr = SafeArrayGetUBound(V_ARRAY(&var),
  380. 1,
  381. (long FAR *)&dwSUBound
  382. );
  383. RETURN_ON_FAILURE(hr);
  384. (*ppList) = (GUID *) CoTaskMemAlloc(sizeof(GUID)*(dwSUBound-dwSLBound+1));
  385. for (i = dwSLBound; i <= dwSUBound; i++)
  386. {
  387. VariantInit(&v);
  388. hr = SafeArrayGetElement(V_ARRAY(&var),
  389. (long FAR *)&i,
  390. &v
  391. );
  392. if (FAILED(hr))
  393. {
  394. continue;
  395. }
  396. if (i <= dwSUBound)
  397. {
  398. UnpackGuidFromVariant(v, (*ppList)+(*pCount));
  399. VariantClear(&v);
  400. (*pCount)++;
  401. }
  402. }
  403. VariantClear(&var);
  404. return(S_OK);
  405. }
  406. HRESULT SetPropertyListGuid(IADs *pADs, LPOLESTR pszPropName,
  407. DWORD cCount, GUID *ppList)
  408. {
  409. VARIANT Var;
  410. HRESULT hr=S_OK;
  411. VariantInit(&Var);
  412. hr = PackGuidArray2Variant(ppList, cCount, &Var);
  413. RETURN_ON_FAILURE(hr);
  414. hr = pADs->Put(pszPropName, Var);
  415. RETURN_ON_FAILURE(hr);
  416. VariantClear(&Var);
  417. return hr;
  418. }
  419. HRESULT
  420. PackString2Variant(
  421. LPWSTR lpszData,
  422. VARIANT * pvData
  423. )
  424. {
  425. BSTR bstrData = NULL;
  426. if (!lpszData || !*lpszData) {
  427. return(E_FAIL);
  428. }
  429. if (!pvData) {
  430. return(E_FAIL);
  431. }
  432. bstrData = SysAllocString(lpszData);
  433. if (!bstrData) {
  434. return(E_FAIL);
  435. }
  436. pvData->vt = VT_BSTR;
  437. pvData->bstrVal = bstrData;
  438. return(S_OK);
  439. }
  440. HRESULT
  441. PackDWORD2Variant(
  442. DWORD dwData,
  443. VARIANT * pvData
  444. )
  445. {
  446. if (!pvData) {
  447. return(E_FAIL);
  448. }
  449. pvData->vt = VT_I4;
  450. pvData->lVal = dwData;
  451. return(S_OK);
  452. }
  453. HRESULT
  454. PackBOOL2Variant(
  455. BOOL fData,
  456. VARIANT * pvData
  457. )
  458. {
  459. pvData->vt = VT_BOOL;
  460. pvData->boolVal = fData;
  461. return(S_OK);
  462. }
  463. HRESULT GetPropertyList(IADs *pADs,
  464. LPOLESTR pszPropName,
  465. DWORD *pCount,
  466. LPOLESTR *pList)
  467. {
  468. LONG dwSLBound = 0;
  469. LONG dwSUBound = 0;
  470. VARIANT v;
  471. LONG i;
  472. HRESULT hr = S_OK;
  473. VARIANT var;
  474. *pCount = 0;
  475. VariantInit(&var);
  476. hr = pADs->Get(pszPropName, &var);
  477. if (hr == E_ADS_PROPERTY_NOT_FOUND)
  478. {
  479. return S_OK;
  480. }
  481. RETURN_ON_FAILURE(hr);
  482. if(!((V_VT(&var) & VT_VARIANT)))
  483. {
  484. return(E_FAIL);
  485. }
  486. //
  487. // The following is a work around for the package detail field
  488. //
  489. if (!V_ISARRAY(&var))
  490. {
  491. *pCount = 1;
  492. *pList = (LPOLESTR) CoTaskMemAlloc (sizeof(WCHAR) * (wcslen(var.bstrVal)+1));
  493. wcscpy (*pList, var.bstrVal);
  494. VariantClear(&var);
  495. return S_OK;
  496. }
  497. //
  498. // Check that there is only one dimension in this array
  499. //
  500. if ((V_ARRAY(&var))->cDims != 1)
  501. {
  502. return E_FAIL;
  503. }
  504. //
  505. // Check that there is atleast one element in this array
  506. //
  507. if ((V_ARRAY(&var))->rgsabound[0].cElements == 0)
  508. {
  509. return E_FAIL;
  510. }
  511. //
  512. // We know that this is a valid single dimension array
  513. //
  514. hr = SafeArrayGetLBound(V_ARRAY(&var),
  515. 1,
  516. (long FAR *)&dwSLBound
  517. );
  518. RETURN_ON_FAILURE(hr);
  519. hr = SafeArrayGetUBound(V_ARRAY(&var),
  520. 1,
  521. (long FAR *)&dwSUBound
  522. );
  523. RETURN_ON_FAILURE(hr);
  524. for (i = dwSLBound; i <= dwSUBound; i++) {
  525. VariantInit(&v);
  526. hr = SafeArrayGetElement(V_ARRAY(&var),
  527. (long FAR *)&i,
  528. &v
  529. );
  530. if (FAILED(hr)) {
  531. continue;
  532. }
  533. if (i <= dwSUBound)
  534. {
  535. *pList = (LPOLESTR) CoTaskMemAlloc
  536. (sizeof (WCHAR) * (wcslen(v.bstrVal) + 1));
  537. wcscpy (*pList, v.bstrVal);
  538. VariantClear(&v);
  539. (*pCount)++;
  540. ++pList;
  541. }
  542. }
  543. VariantClear(&var);
  544. return(S_OK);
  545. }
  546. HRESULT GetPropertyAlloc (IADs *pADs, LPOLESTR pszPropName, LPOLESTR *ppszPropVal)
  547. {
  548. VARIANT varGet;
  549. HRESULT hr;
  550. if (!ppszPropVal)
  551. return S_OK;
  552. VariantInit(&varGet);
  553. hr = pADs->Get(pszPropName, &varGet);
  554. if (hr == E_ADS_PROPERTY_NOT_FOUND)
  555. {
  556. *ppszPropVal = NULL;
  557. return S_OK;
  558. }
  559. RETURN_ON_FAILURE(hr);
  560. *ppszPropVal = (LPOLESTR) CoTaskMemAlloc (sizeof(WCHAR) * (wcslen(varGet.bstrVal)+1));
  561. wcscpy (*ppszPropVal, varGet.bstrVal);
  562. VariantClear(&varGet);
  563. return hr;
  564. }
  565. HRESULT GetProperty (IADs *pADs, LPOLESTR pszPropName, LPOLESTR pszPropVal)
  566. {
  567. VARIANT varGet;
  568. HRESULT hr;
  569. VariantInit(&varGet);
  570. hr = pADs->Get(pszPropName, &varGet);
  571. if (hr == E_ADS_PROPERTY_NOT_FOUND)
  572. {
  573. pszPropVal[0] = NULL;
  574. return S_OK;
  575. }
  576. RETURN_ON_FAILURE(hr);
  577. wcscpy (pszPropVal, varGet.bstrVal);
  578. VariantClear(&varGet);
  579. return hr;
  580. }
  581. HRESULT GetPropertyDW (IADs *pADs, LPOLESTR pszPropName, DWORD *pdwPropVal)
  582. {
  583. VARIANT varGet;
  584. HRESULT hr;
  585. VariantInit(&varGet);
  586. hr = pADs->Get(pszPropName, &varGet);
  587. if (hr == E_ADS_PROPERTY_NOT_FOUND)
  588. {
  589. *pdwPropVal = 0;
  590. return S_OK;
  591. }
  592. RETURN_ON_FAILURE(hr);
  593. *pdwPropVal = varGet.lVal;
  594. VariantClear(&varGet);
  595. return hr;
  596. }
  597. HRESULT GetPropertyListAllocDW (IADs *pADs, LPOLESTR pszPropName, DWORD *pCount, DWORD **pdwPropVal)
  598. {
  599. LONG dwSLBound = 0;
  600. LONG dwSUBound = 0;
  601. VARIANT v;
  602. LONG i;
  603. HRESULT hr = S_OK;
  604. VARIANT var;
  605. *pCount = 0;
  606. *pdwPropVal = NULL;
  607. VariantInit(&var);
  608. hr = pADs->Get(pszPropName, &var);
  609. if (hr == E_ADS_PROPERTY_NOT_FOUND)
  610. {
  611. return S_OK;
  612. }
  613. RETURN_ON_FAILURE(hr);
  614. if (!V_ISARRAY(&var))
  615. {
  616. *pCount = 1;
  617. *pdwPropVal = (DWORD *) CoTaskMemAlloc (sizeof(DWORD));
  618. (*pdwPropVal)[0] = var.lVal;
  619. VariantClear(&var);
  620. return S_OK;
  621. }
  622. //
  623. // Check that there is only one dimension in this array
  624. //
  625. if ((V_ARRAY(&var))->cDims != 1)
  626. {
  627. return E_FAIL;
  628. }
  629. //
  630. // Check that there is atleast one element in this array
  631. //
  632. if ((V_ARRAY(&var))->rgsabound[0].cElements == 0)
  633. {
  634. return E_FAIL;
  635. }
  636. //
  637. // We know that this is a valid single dimension array
  638. //
  639. hr = SafeArrayGetLBound(V_ARRAY(&var),
  640. 1,
  641. (long FAR *)&dwSLBound
  642. );
  643. RETURN_ON_FAILURE(hr);
  644. hr = SafeArrayGetUBound(V_ARRAY(&var),
  645. 1,
  646. (long FAR *)&dwSUBound
  647. );
  648. RETURN_ON_FAILURE(hr);
  649. *pdwPropVal = (DWORD *)CoTaskMemAlloc(sizeof(DWORD)*
  650. (dwSUBound - dwSLBound + 1));
  651. if (!(*pdwPropVal))
  652. return E_OUTOFMEMORY;
  653. for (i = dwSLBound; i <= dwSUBound; i++) {
  654. VariantInit(&v);
  655. hr = SafeArrayGetElement(V_ARRAY(&var),
  656. (long FAR *)&i,
  657. &v
  658. );
  659. if (FAILED(hr)) {
  660. continue;
  661. }
  662. (*pdwPropVal)[*pCount] = v.lVal;
  663. VariantClear(&v);
  664. (*pCount)++;
  665. }
  666. VariantClear(&var);
  667. return(S_OK);
  668. }
  669. HRESULT SetPropertyListDW (IADs *pADs, LPOLESTR pszPropName, DWORD dwCount, DWORD *pdwPropVal)
  670. {
  671. VARIANT Var;
  672. HRESULT hr = S_OK;
  673. VariantInit(&Var);
  674. // BUGBUG:: THis doesn't seem to work.
  675. // hr = ADsBuildVarArrayInt(pdwPropVal, dwCount, &Var);
  676. hr = PackDWORDArray2Variant(pdwPropVal, dwCount, &Var);
  677. if (SUCCEEDED(hr))
  678. hr = pADs->Put(pszPropName, Var);
  679. VariantClear(&Var);
  680. return hr;
  681. }
  682. HRESULT SetProperty (IADs *pADs, LPOLESTR pszPropName, LPOLESTR pszPropVal)
  683. {
  684. VARIANT var;
  685. HRESULT hr;
  686. if ((pszPropVal == NULL) || (*pszPropVal == NULL))
  687. return S_OK;
  688. VariantInit(&var);
  689. PackString2Variant(pszPropVal, &var);
  690. hr = pADs->Put(pszPropName, var);
  691. SysFreeString(var.bstrVal);
  692. VariantClear(&var);
  693. return hr;
  694. }
  695. HRESULT SetPropertyDW (IADs *pADs, LPOLESTR pszPropName, DWORD dwPropVal)
  696. {
  697. VARIANT var;
  698. HRESULT hr;
  699. VariantInit(&var);
  700. PackDWORD2Variant(dwPropVal, &var);
  701. hr = pADs->Put(pszPropName, var);
  702. VariantClear(&var);
  703. return hr;
  704. }
  705. HRESULT StoreIt (IADs *pADs)
  706. {
  707. HRESULT hr;
  708. hr = pADs->SetInfo();
  709. if (hr == HRESULT_FROM_WIN32(ERROR_EXTENDED_ERROR))
  710. {
  711. DWORD proverr;
  712. hr = ADsGetLastError (&proverr, NULL, 0, NULL, 0);
  713. if (SUCCEEDED(hr)
  714. // && (proverr == LDAP_NO_SUCH_ATTRIBUTE)
  715. )
  716. {
  717. printf ("Ldap Error = %d.\n", proverr);
  718. return E_FAIL;
  719. }
  720. else
  721. return hr; //E_INVALIDARG;
  722. }
  723. return hr;
  724. }
  725. HRESULT GetFromVariant(VARIANT *pVar,
  726. DWORD *pCount, // In, Out
  727. LPOLESTR *rpgList)
  728. {
  729. LONG dwSLBound = 0;
  730. LONG dwSUBound = 0;
  731. LONG j;
  732. HRESULT hr = S_OK;
  733. ULONG cFetch = *pCount;
  734. void HUGEP *pArray;
  735. pArray = NULL;
  736. if( !(pVar->vt & VT_ARRAY))
  737. return E_FAIL;
  738. hr = SafeArrayGetLBound(V_ARRAY(pVar),
  739. 1,
  740. (long FAR *) &dwSLBound );
  741. hr = SafeArrayGetUBound(V_ARRAY(pVar),
  742. 1,
  743. (long FAR *) &dwSUBound );
  744. hr = SafeArrayAccessData( V_ARRAY(pVar), &pArray );
  745. *pCount = 0;
  746. for (j=dwSLBound; (j<=dwSUBound) && (*pCount < cFetch); j++)
  747. {
  748. switch(pVar->vt & ~VT_ARRAY)
  749. {
  750. case VT_BSTR:
  751. *rpgList = (LPOLESTR) CoTaskMemAlloc
  752. (sizeof (WCHAR) * (wcslen(((BSTR *)pArray)[j]) + 1));
  753. wcscpy (*rpgList, ((BSTR *)pArray)[j]);
  754. (*pCount)++;
  755. ++rpgList;
  756. break;
  757. case VT_I4:
  758. *rpgList = (LPOLESTR)(((DWORD *) pArray)[j]);
  759. (*pCount)++;
  760. ++rpgList;
  761. break;
  762. case VT_VARIANT:
  763. VARIANT *pV;
  764. pV = (VARIANT *)pArray + j;
  765. if (pV->vt == (VT_ARRAY | VT_UI1))
  766. { /* binary data, only GUID */
  767. UnpackGuidFromVariant(*pV, (GUID *)rpgList);
  768. }
  769. else if (pV->vt == VT_I4)
  770. {
  771. *rpgList = (LPOLESTR) pV->lVal;
  772. (*pCount)++;
  773. ++rpgList;
  774. }
  775. else
  776. {
  777. *rpgList = (LPOLESTR) CoTaskMemAlloc
  778. (sizeof (WCHAR) * (wcslen(pV->bstrVal)+1));
  779. wcscpy (*rpgList, pV->bstrVal);
  780. (*pCount)++;
  781. ++rpgList;
  782. }
  783. break;
  784. /*
  785. case VT_I8:
  786. wprintf(L"%I64d # ",((__int64 *) pArray)[j]);
  787. break;
  788. */
  789. default:
  790. return E_FAIL;
  791. }
  792. }
  793. SafeArrayUnaccessData( V_ARRAY(pVar) );
  794. return S_OK;
  795. }
  796. HRESULT GetCategoryLocaleDesc(LPOLESTR *pdesc, ULONG cdesc, LCID *plcid,
  797. LPOLESTR szDescription)
  798. {
  799. LCID plgid;
  800. LPOLESTR ptr;
  801. if (!cdesc)
  802. return E_FAIL; // CAT_E_NODESCRIPTION;
  803. // Try locale passed in
  804. if (FindDescription(pdesc, cdesc, plcid, szDescription, 0))
  805. return S_OK;
  806. // Get default sublang local
  807. plgid = PRIMARYLANGID((WORD)*plcid);
  808. *plcid = MAKELCID(MAKELANGID(plgid, SUBLANG_DEFAULT), SORT_DEFAULT);
  809. if (FindDescription(pdesc, cdesc, plcid, szDescription, 0))
  810. return S_OK;
  811. // Get matching lang id
  812. if (FindDescription(pdesc, cdesc, plcid, szDescription, 1))
  813. return S_OK;
  814. // Get User Default
  815. *plcid = GetUserDefaultLCID();
  816. if (FindDescription(pdesc, cdesc, plcid, szDescription, 0))
  817. return S_OK;
  818. // Get System Default
  819. *plcid = GetUserDefaultLCID();
  820. if (FindDescription(pdesc, cdesc, plcid, szDescription, 0))
  821. return S_OK;
  822. // Get the first one
  823. *plcid = wcstoul(pdesc[0], &ptr, 16);
  824. if (szDescription)
  825. wcscpy(szDescription, (ptr+wcslen(CATSEPERATOR)+2));
  826. return S_OK;
  827. }
  828. //-------------------------------------------
  829. // Returns the description corresp. to a LCID
  830. // desc: list of descs+lcid
  831. // cdesc: number of elements.
  832. // plcid: the lcid in/out
  833. // szDescription:description returned.
  834. // GetPrimary: Match only the primary.
  835. //---------------------------------------
  836. ULONG FindDescription(LPOLESTR *desc, ULONG cdesc, LCID *plcid, LPOLESTR szDescription, BOOL GetPrimary)
  837. {
  838. ULONG i;
  839. LCID newlcid;
  840. LPOLESTR ptr;
  841. for (i = 0; i < cdesc; i++)
  842. {
  843. newlcid = wcstoul(desc[i], &ptr, 16); // to be changed
  844. // error to be checked.
  845. if ((newlcid == *plcid) || ((GetPrimary) &&
  846. (PRIMARYLANGID((WORD)*plcid) == PRIMARYLANGID(LANGIDFROMLCID(newlcid)))))
  847. {
  848. if (szDescription)
  849. wcscpy(szDescription, (ptr+wcslen(CATSEPERATOR)+2));
  850. if (GetPrimary)
  851. *plcid = newlcid;
  852. return i+1;
  853. }
  854. }
  855. return 0;
  856. }
  857.