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.

1087 lines
21 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cggi.cxx
  7. //
  8. // Contents: This file contains the Group Object's
  9. IADsGroup and IADsGroupOperation methods
  10. //
  11. // History: 11-1-95 krishnag Created.
  12. //
  13. //----------------------------------------------------------------------------
  14. #include "nds.hxx"
  15. #pragma hdrstop
  16. BOOL
  17. VerifyIfMember(
  18. BSTR bstrMember,
  19. VARIANT * VariantArray,
  20. ULONG cElementFetched
  21. );
  22. // Class CNDSGroup
  23. STDMETHODIMP CNDSGroup::get_Description(THIS_ BSTR FAR* retval)
  24. {
  25. GET_PROPERTY_BSTR((IADsGroup *)this,Description);
  26. }
  27. STDMETHODIMP CNDSGroup::put_Description(THIS_ BSTR bstrDescription)
  28. {
  29. PUT_PROPERTY_BSTR((IADsGroup *)this,Description);
  30. }
  31. STDMETHODIMP
  32. CNDSGroup::Members(
  33. THIS_ IADsMembers FAR* FAR* ppMembers
  34. )
  35. {
  36. VARIANT varProp;
  37. HRESULT hr = S_OK;
  38. BSTR bstrADsPath = NULL;
  39. if (!ppMembers) {
  40. RRETURN(E_ADS_BAD_PARAMETER);
  41. }
  42. VariantInit(&varProp);
  43. hr = _pADs->GetEx(L"Member", &varProp);
  44. //
  45. // Do not bail out on failure here if you could not find
  46. // any data set for the Members property. You need to
  47. // pass it all the way through and on enumeration
  48. // return nothing.
  49. //
  50. if (hr == E_ADS_PROPERTY_NOT_FOUND) {
  51. SAFEARRAY *aList = NULL;
  52. VariantInit(&varProp);
  53. SAFEARRAYBOUND aBound;
  54. aBound.lLbound = 0;
  55. aBound.cElements = 0;
  56. aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
  57. if ( aList == NULL ) {
  58. hr = E_OUTOFMEMORY;
  59. BAIL_ON_FAILURE(hr);
  60. }
  61. V_VT(&varProp) = VT_ARRAY | VT_VARIANT;
  62. V_ARRAY(&varProp) = aList;
  63. }
  64. else {
  65. BAIL_ON_FAILURE(hr);
  66. }
  67. hr = _pADs->get_ADsPath(&bstrADsPath);
  68. hr = CNDSGroupCollection::CreateGroupCollection(
  69. bstrADsPath,
  70. varProp,
  71. _Credentials,
  72. IID_IADsMembers,
  73. (void **)ppMembers
  74. );
  75. BAIL_ON_FAILURE(hr);
  76. error:
  77. if (bstrADsPath) {
  78. ADsFreeString(bstrADsPath);
  79. }
  80. VariantClear(&varProp);
  81. RRETURN(hr);
  82. }
  83. STDMETHODIMP
  84. CNDSGroup::IsMember(
  85. THIS_ BSTR bstrMember,
  86. VARIANT_BOOL FAR* bMember
  87. )
  88. {
  89. IADsMembers FAR * pMembers = NULL;
  90. IUnknown FAR * pUnknown = NULL;
  91. IEnumVARIANT FAR * pEnumVar = NULL;
  92. DWORD i = 0;
  93. HRESULT hr = S_OK;
  94. VARIANT_BOOL fMember = FALSE;
  95. VARIANT VariantArray[10];
  96. BOOL fContinue = TRUE;
  97. ULONG cElementFetched = 0;
  98. if (!bstrMember) {
  99. RRETURN(E_ADS_BAD_PARAMETER);
  100. }
  101. if (!bMember) {
  102. RRETURN(E_ADS_BAD_PARAMETER);
  103. }
  104. hr = Members(
  105. &pMembers
  106. );
  107. BAIL_ON_FAILURE(hr);
  108. hr = pMembers->get__NewEnum(
  109. &pUnknown
  110. );
  111. //
  112. // If it has no members, we will return FALSE
  113. //
  114. if (hr == E_FAIL) {
  115. hr = S_OK;
  116. goto error;
  117. }
  118. hr = pUnknown->QueryInterface(
  119. IID_IEnumVARIANT,
  120. (void **)&pEnumVar
  121. );
  122. BAIL_ON_FAILURE(hr);
  123. while (fContinue) {
  124. hr = pEnumVar->Next(
  125. 10,
  126. VariantArray,
  127. &cElementFetched
  128. );
  129. if (hr == S_FALSE) {
  130. fContinue = FALSE;
  131. //
  132. // Reset hr to S_OK, we want to return success
  133. //
  134. hr = S_OK;
  135. }
  136. fMember = (VARIANT_BOOL)VerifyIfMember(
  137. bstrMember,
  138. VariantArray,
  139. cElementFetched
  140. );
  141. if (fMember) {
  142. fContinue = FALSE;
  143. }
  144. for (i = 0; i < cElementFetched; i++ ) {
  145. IDispatch *pDispatch = NULL;
  146. pDispatch = VariantArray[i].pdispVal;
  147. pDispatch->Release();
  148. }
  149. memset(VariantArray, 0, sizeof(VARIANT)*10);
  150. }
  151. error:
  152. *bMember = fMember? VARIANT_TRUE: VARIANT_FALSE;
  153. if (pEnumVar) {
  154. pEnumVar->Release();
  155. }
  156. if (pUnknown) {
  157. pUnknown->Release();
  158. }
  159. if (pMembers) {
  160. pMembers->Release();
  161. }
  162. RRETURN(hr);
  163. }
  164. BOOL
  165. VerifyIfMember(
  166. BSTR bstrMember,
  167. VARIANT * VariantArray,
  168. ULONG cElementFetched
  169. )
  170. {
  171. DWORD i = 0;
  172. HRESULT hr = S_OK;
  173. IADs FAR * pObject = NULL;
  174. IDispatch FAR * pDispatch = NULL;
  175. for (i = 0; i < cElementFetched; i++ ) {
  176. IDispatch *pDispatch = NULL;
  177. BSTR bstrName = NULL;
  178. pDispatch = VariantArray[i].pdispVal;
  179. hr = pDispatch->QueryInterface(
  180. IID_IADs,
  181. (VOID **) &pObject
  182. );
  183. BAIL_ON_FAILURE(hr);
  184. hr = pObject->get_ADsPath(&bstrName);
  185. BAIL_ON_FAILURE(hr);
  186. if (!_wcsicmp(bstrName, bstrMember)) {
  187. SysFreeString(bstrName);
  188. bstrName = NULL;
  189. pObject->Release();
  190. return(TRUE);
  191. }
  192. SysFreeString(bstrName);
  193. bstrName = NULL;
  194. pObject->Release();
  195. }
  196. error:
  197. return(FALSE);
  198. }
  199. STDMETHODIMP
  200. CNDSGroup::Add(THIS_ BSTR bstrNewItem)
  201. {
  202. HRESULT hr = S_OK;
  203. WCHAR szNDSUserPathName[MAX_PATH];
  204. WCHAR szNDSUserTreeName[MAX_PATH];
  205. IUnknown * pUnknown = NULL;
  206. IADs * pUser = NULL;
  207. WCHAR szNDSGroupPathName[MAX_PATH];
  208. WCHAR szNDSGroupTreeName[MAX_PATH];
  209. BSTR bstrPathName = NULL;
  210. hr = ::GetObject(
  211. bstrNewItem,
  212. _Credentials,
  213. (void **)&pUnknown
  214. );
  215. BAIL_ON_FAILURE(hr);
  216. hr = pUnknown->QueryInterface(IID_IADs, (void **)&pUser);
  217. BAIL_ON_FAILURE(hr);
  218. hr = BuildNDSPathFromADsPath(
  219. bstrNewItem,
  220. szNDSUserTreeName,
  221. szNDSUserPathName
  222. );
  223. BAIL_ON_FAILURE(hr);
  224. hr = _pADs->get_ADsPath(&bstrPathName);
  225. BAIL_ON_FAILURE(hr);
  226. hr = BuildNDSPathFromADsPath(
  227. bstrPathName,
  228. szNDSGroupTreeName,
  229. szNDSGroupPathName
  230. );
  231. BAIL_ON_FAILURE(hr);
  232. hr = AddEntry(_pADs, L"Member",szNDSUserPathName);
  233. BAIL_ON_FAILURE(hr);
  234. // hr = AddEntry(_pADs, L"Equivalent To Me", szNDSUserPathName);
  235. // BAIL_ON_FAILURE(hr);
  236. hr = AddEntry(pUser, L"Group Membership", szNDSGroupPathName);
  237. BAIL_ON_FAILURE(hr);
  238. error:
  239. if (bstrPathName) {
  240. ADsFreeString(bstrPathName);
  241. }
  242. if (pUnknown) {
  243. pUnknown->Release();
  244. }
  245. if (pUser) {
  246. pUser->Release();
  247. }
  248. RRETURN(hr);
  249. }
  250. STDMETHODIMP
  251. CNDSGroup::Remove(THIS_ BSTR bstrNewItem)
  252. {
  253. HRESULT hr = S_OK;
  254. WCHAR szNDSUserPathName[MAX_PATH];
  255. WCHAR szNDSUserTreeName[MAX_PATH];
  256. IUnknown * pUnknown = NULL;
  257. IADs * pUser = NULL;
  258. WCHAR szNDSGroupPathName[MAX_PATH];
  259. WCHAR szNDSGroupTreeName[MAX_PATH];
  260. BSTR bstrPathName = NULL;
  261. hr = ::GetObject(
  262. bstrNewItem,
  263. _Credentials,
  264. (void **)&pUnknown
  265. );
  266. BAIL_ON_FAILURE(hr);
  267. hr = pUnknown->QueryInterface(IID_IADs, (void **)&pUser);
  268. BAIL_ON_FAILURE(hr);
  269. hr = BuildNDSPathFromADsPath(
  270. bstrNewItem,
  271. szNDSUserTreeName,
  272. szNDSUserPathName
  273. );
  274. BAIL_ON_FAILURE(hr);
  275. hr = _pADs->get_ADsPath(&bstrPathName);
  276. BAIL_ON_FAILURE(hr);
  277. hr = BuildNDSPathFromADsPath(
  278. bstrPathName,
  279. szNDSGroupTreeName,
  280. szNDSGroupPathName
  281. );
  282. BAIL_ON_FAILURE(hr);
  283. hr = RemoveEntry(_pADs, L"Member",szNDSUserPathName);
  284. BAIL_ON_FAILURE(hr);
  285. // hr = RemoveEntry(_pADs, L"Equivalent To Me", szNDSUserPathName);
  286. // BAIL_ON_FAILURE(hr);
  287. hr = RemoveEntry(pUser, L"Group Membership", szNDSGroupPathName);
  288. BAIL_ON_FAILURE(hr);
  289. error:
  290. if (bstrPathName) {
  291. ADsFreeString(bstrPathName);
  292. }
  293. if (pUnknown) {
  294. pUnknown->Release();
  295. }
  296. if (pUser) {
  297. pUser->Release();
  298. }
  299. RRETURN(hr);
  300. }
  301. HRESULT
  302. AddEntry(
  303. IADs * pADs,
  304. LPWSTR pszAttribute,
  305. LPWSTR pszValue
  306. )
  307. {
  308. HRESULT hr = S_OK;
  309. VARIANT vOldValue;
  310. VARIANT vNewValue;
  311. SAFEARRAY * pArray = NULL;
  312. VariantInit(&vOldValue);
  313. VariantInit(&vNewValue);
  314. #if defined(BUILD_FOR_NT40)
  315. hr = pADs->Get(pszAttribute, &vOldValue);
  316. if (hr == E_ADS_PROPERTY_NOT_FOUND) {
  317. VariantInit(&vNewValue);
  318. V_BSTR(&vNewValue) = SysAllocString(pszValue);
  319. V_VT(&vNewValue) = VT_BSTR;
  320. hr = pADs->Put(pszAttribute, vNewValue);
  321. BAIL_ON_FAILURE(hr);
  322. }else{
  323. hr = VarAddEntry(
  324. pszValue,
  325. vOldValue,
  326. &vNewValue
  327. );
  328. BAIL_ON_FAILURE(hr);
  329. hr = pADs->Put(pszAttribute, vNewValue);
  330. BAIL_ON_FAILURE(hr);
  331. }
  332. #else
  333. //
  334. // NT5 supports appending values. So we don't need to read everything.
  335. // append ourselves and write everything
  336. //
  337. SAFEARRAYBOUND sabNewArray;
  338. int i;
  339. VARIANT v;
  340. sabNewArray.cElements = 1;
  341. sabNewArray.lLbound = 0;
  342. pArray = SafeArrayCreate(
  343. VT_VARIANT,
  344. 1,
  345. &sabNewArray
  346. );
  347. if (!pArray) {
  348. hr = E_OUTOFMEMORY;
  349. BAIL_ON_FAILURE(hr);
  350. }
  351. VariantInit(&v);
  352. V_BSTR(&v) = SysAllocString(pszValue);
  353. V_VT(&v) = VT_BSTR;
  354. i = 0;
  355. hr = SafeArrayPutElement(
  356. pArray,
  357. (long *)&i,
  358. (void *)&v
  359. );
  360. VariantClear(&v);
  361. BAIL_ON_FAILURE(hr);
  362. V_VT(&vNewValue) = VT_ARRAY | VT_VARIANT;
  363. V_ARRAY(&vNewValue) = pArray;
  364. hr = pADs->PutEx(ADS_PROPERTY_APPEND, pszAttribute, vNewValue);
  365. BAIL_ON_FAILURE(hr);
  366. #endif
  367. hr = pADs->SetInfo();
  368. BAIL_ON_FAILURE(hr);
  369. error:
  370. VariantClear(&vOldValue);
  371. VariantClear(&vNewValue);
  372. RRETURN(hr);
  373. }
  374. HRESULT
  375. RemoveEntry(
  376. IADs * pADs,
  377. LPWSTR pszAttribute,
  378. LPWSTR pszValue
  379. )
  380. {
  381. HRESULT hr = S_OK;
  382. VARIANT vOldValue;
  383. VARIANT vNewValue;
  384. SAFEARRAY * pArray = NULL;
  385. VariantInit(&vOldValue);
  386. VariantInit(&vNewValue);
  387. #if defined(BUILD_FOR_NT40)
  388. hr = pADs->Get(pszAttribute, &vOldValue);
  389. BAIL_ON_FAILURE(hr);
  390. hr = VarRemoveEntry(
  391. pszValue,
  392. vOldValue,
  393. &vNewValue
  394. );
  395. BAIL_ON_FAILURE(hr);
  396. if (V_VT(&vNewValue) == VT_EMPTY) {
  397. hr = pADs->PutEx(ADS_PROPERTY_CLEAR, pszAttribute, vNewValue);
  398. }else {
  399. hr = pADs->Put(pszAttribute, vNewValue);
  400. }
  401. BAIL_ON_FAILURE(hr);
  402. #else
  403. SAFEARRAYBOUND sabNewArray;
  404. VARIANT v;
  405. int i;
  406. //
  407. // NT5 supports deleting values. So we don't need to read everything.
  408. // delete ourselves and write everything - Very inefficient!
  409. //
  410. sabNewArray.cElements = 1;
  411. sabNewArray.lLbound = 0;
  412. pArray = SafeArrayCreate(
  413. VT_VARIANT,
  414. 1,
  415. &sabNewArray
  416. );
  417. if (!pArray) {
  418. hr = E_OUTOFMEMORY;
  419. BAIL_ON_FAILURE(hr);
  420. }
  421. VariantInit(&v);
  422. V_BSTR(&v) = SysAllocString(pszValue);
  423. V_VT(&v) = VT_BSTR;
  424. i = 0;
  425. hr = SafeArrayPutElement(
  426. pArray,
  427. (long *)&i,
  428. (void *)&v
  429. );
  430. VariantClear(&v);
  431. BAIL_ON_FAILURE(hr);
  432. V_VT(&vNewValue) = VT_ARRAY | VT_VARIANT;
  433. V_ARRAY(&vNewValue) = pArray;
  434. hr = pADs->PutEx(ADS_PROPERTY_DELETE, pszAttribute, vNewValue);
  435. BAIL_ON_FAILURE(hr);
  436. #endif
  437. hr = pADs->SetInfo();
  438. BAIL_ON_FAILURE(hr);
  439. error:
  440. VariantClear(&vOldValue);
  441. VariantClear(&vNewValue);
  442. RRETURN(hr);
  443. }
  444. HRESULT
  445. VarFindEntry(
  446. LPWSTR pszNDSPathName,
  447. VARIANT varMembers
  448. )
  449. {
  450. HRESULT hr = S_OK;
  451. DWORD dwSLBound = 0;
  452. DWORD dwSUBound = 0;
  453. DWORD i = 0;
  454. VARIANT v;
  455. if (!(V_VT(&varMembers) == (VT_VARIANT|VT_ARRAY))) {
  456. return(E_FAIL);
  457. }
  458. //
  459. // Check that there is only one dimension in this array
  460. //
  461. if ((V_ARRAY(&varMembers))->cDims != 1) {
  462. hr = E_FAIL;
  463. BAIL_ON_FAILURE(hr);
  464. }
  465. //
  466. // Check that there is atleast one element in this array
  467. //
  468. if ((V_ARRAY(&varMembers))->rgsabound[0].cElements == 0){
  469. hr = E_FAIL;
  470. BAIL_ON_FAILURE(hr);
  471. }
  472. //
  473. // We know that this is a valid single dimension array
  474. //
  475. hr = SafeArrayGetLBound(V_ARRAY(&varMembers),
  476. 1,
  477. (long FAR *)&dwSLBound
  478. );
  479. BAIL_ON_FAILURE(hr);
  480. hr = SafeArrayGetUBound(V_ARRAY(&varMembers),
  481. 1,
  482. (long FAR *)&dwSUBound
  483. );
  484. BAIL_ON_FAILURE(hr);
  485. for (i = dwSLBound; i <= dwSUBound; i++) {
  486. VariantInit(&v);
  487. hr = SafeArrayGetElement(V_ARRAY(&varMembers),
  488. (long FAR *)&i,
  489. &v
  490. );
  491. if (!_wcsicmp(V_BSTR(&v), pszNDSPathName)) {
  492. VariantClear(&v);
  493. RRETURN(S_OK);
  494. }
  495. VariantClear(&v);
  496. }
  497. error:
  498. RRETURN(E_FAIL);
  499. }
  500. HRESULT
  501. VarMultipleAddEntry(
  502. LPWSTR pszNDSPathName,
  503. VARIANT varMembers,
  504. VARIANT * pvarNewMembers
  505. )
  506. { SAFEARRAYBOUND sabNewArray;
  507. SAFEARRAY * pFilter = NULL;
  508. HRESULT hr = S_OK;
  509. DWORD dwSLBound = 0;
  510. DWORD dwSUBound = 0;
  511. DWORD i = 0;
  512. VARIANT v;
  513. VariantInit(pvarNewMembers);
  514. if (!(V_VT(&varMembers) == (VT_VARIANT|VT_ARRAY))) {
  515. return(E_FAIL);
  516. }
  517. //
  518. // Check that there is only one dimension in this array
  519. //
  520. if ((V_ARRAY(&varMembers))->cDims != 1) {
  521. hr = E_FAIL;
  522. BAIL_ON_FAILURE(hr);
  523. }
  524. //
  525. // Check that there is atleast one element in this array
  526. //
  527. if ((V_ARRAY(&varMembers))->rgsabound[0].cElements == 0){
  528. hr = E_FAIL;
  529. BAIL_ON_FAILURE(hr);
  530. }
  531. //
  532. // We know that this is a valid single dimension array
  533. //
  534. hr = SafeArrayGetLBound(V_ARRAY(&varMembers),
  535. 1,
  536. (long FAR *)&dwSLBound
  537. );
  538. BAIL_ON_FAILURE(hr);
  539. hr = SafeArrayGetUBound(V_ARRAY(&varMembers),
  540. 1,
  541. (long FAR *)&dwSUBound
  542. );
  543. BAIL_ON_FAILURE(hr);
  544. sabNewArray.cElements = (dwSUBound - dwSLBound + 1) + 1;
  545. sabNewArray.lLbound = dwSLBound;
  546. pFilter = SafeArrayCreate(
  547. VT_VARIANT,
  548. 1,
  549. &sabNewArray
  550. );
  551. if (!pFilter) {
  552. hr = E_OUTOFMEMORY;
  553. BAIL_ON_FAILURE(hr);
  554. }
  555. for (i = dwSLBound; i <= dwSUBound; i++) {
  556. VariantInit(&v);
  557. hr = SafeArrayGetElement(
  558. V_ARRAY(&varMembers),
  559. (long FAR *)&i,
  560. &v
  561. );
  562. BAIL_ON_FAILURE(hr);
  563. hr = SafeArrayPutElement(
  564. pFilter,
  565. (long*)&i,
  566. (void *)&v
  567. );
  568. VariantClear(&v);
  569. BAIL_ON_FAILURE(hr);
  570. }
  571. VariantInit(&v);
  572. V_VT(&v) = VT_BSTR;
  573. V_BSTR(&v) = SysAllocString(pszNDSPathName);
  574. hr = SafeArrayPutElement(
  575. pFilter,
  576. (long *)&i,
  577. (void *)&v
  578. );
  579. VariantClear(&v);
  580. BAIL_ON_FAILURE(hr);
  581. V_VT(pvarNewMembers) = VT_ARRAY | VT_VARIANT;
  582. V_ARRAY(pvarNewMembers) = pFilter;
  583. RRETURN(S_OK);
  584. error:
  585. if (pFilter) {
  586. SafeArrayDestroy(pFilter);
  587. }
  588. RRETURN(hr);
  589. }
  590. HRESULT
  591. VarMultipleRemoveEntry(
  592. LPWSTR pszNDSPathName,
  593. VARIANT varMembers,
  594. VARIANT * pvarNewMembers
  595. )
  596. { SAFEARRAYBOUND sabNewArray;
  597. SAFEARRAY * pFilter = NULL;
  598. HRESULT hr = S_OK;
  599. DWORD dwSLBound = 0;
  600. DWORD dwSUBound = 0;
  601. DWORD i = 0;
  602. DWORD dwNewCount = 0;
  603. VARIANT v;
  604. VariantInit(pvarNewMembers);
  605. if(!(V_VT(&varMembers) == (VT_VARIANT|VT_ARRAY))){
  606. return(E_FAIL);
  607. }
  608. //
  609. // Check that there is only one dimension in this array
  610. //
  611. if ((V_ARRAY(&varMembers))->cDims != 1) {
  612. hr = E_FAIL;
  613. BAIL_ON_FAILURE(hr);
  614. }
  615. //
  616. // Check that there is atleast one element in this array
  617. //
  618. if ((V_ARRAY(&varMembers))->rgsabound[0].cElements == 0){
  619. hr = E_FAIL;
  620. BAIL_ON_FAILURE(hr);
  621. }
  622. //
  623. // We know that this is a valid single dimension array
  624. //
  625. hr = SafeArrayGetLBound(V_ARRAY(&varMembers),
  626. 1,
  627. (long FAR *)&dwSLBound
  628. );
  629. BAIL_ON_FAILURE(hr);
  630. hr = SafeArrayGetUBound(V_ARRAY(&varMembers),
  631. 1,
  632. (long FAR *)&dwSUBound
  633. );
  634. BAIL_ON_FAILURE(hr);
  635. sabNewArray.cElements = (dwSUBound - dwSLBound);
  636. sabNewArray.lLbound = dwSLBound;
  637. pFilter = SafeArrayCreate(
  638. VT_VARIANT,
  639. 1,
  640. &sabNewArray
  641. );
  642. if (!pFilter) {
  643. hr = E_OUTOFMEMORY;
  644. BAIL_ON_FAILURE(hr);
  645. }
  646. for (i = dwSLBound, dwNewCount = dwSLBound; i <= dwSUBound; i++) {
  647. VariantInit(&v);
  648. hr = SafeArrayGetElement(
  649. V_ARRAY(&varMembers),
  650. (long FAR *)&i,
  651. &v
  652. );
  653. if (!_wcsicmp(V_BSTR(&v), pszNDSPathName)) {
  654. VariantClear(&v);
  655. //
  656. // skip this entry
  657. //
  658. continue;
  659. }
  660. hr = SafeArrayPutElement(
  661. pFilter,
  662. (long*)&dwNewCount,
  663. (void *)&v
  664. );
  665. VariantClear(&v);
  666. BAIL_ON_FAILURE(hr);
  667. dwNewCount++;
  668. }
  669. V_VT(pvarNewMembers) = VT_ARRAY | VT_VARIANT;
  670. V_ARRAY(pvarNewMembers) = pFilter;
  671. RRETURN(S_OK);
  672. error:
  673. if (pFilter) {
  674. SafeArrayDestroy(pFilter);
  675. }
  676. RRETURN(hr);
  677. }
  678. HRESULT
  679. VarSingleAddEntry(
  680. LPWSTR pszNDSPathName,
  681. VARIANT varMembers,
  682. VARIANT * pvarNewMembers
  683. )
  684. { SAFEARRAYBOUND sabNewArray;
  685. SAFEARRAY * pFilter = NULL;
  686. HRESULT hr = S_OK;
  687. DWORD dwSLBound = 0;
  688. DWORD dwSUBound = 0;
  689. DWORD i = 0;
  690. VARIANT v;
  691. VariantInit(pvarNewMembers);
  692. if(!((V_VT(&varMembers) & VT_TYPEMASK) == VT_BSTR)){
  693. return(E_FAIL);
  694. }
  695. sabNewArray.cElements = (1) + 1;
  696. sabNewArray.lLbound = 0;
  697. pFilter = SafeArrayCreate(
  698. VT_VARIANT,
  699. 1,
  700. &sabNewArray
  701. );
  702. if (!pFilter) {
  703. hr = E_OUTOFMEMORY;
  704. BAIL_ON_FAILURE(hr);
  705. }
  706. i = 0;
  707. hr = SafeArrayPutElement(
  708. pFilter,
  709. (long *)&i,
  710. (void *)&varMembers
  711. );
  712. BAIL_ON_FAILURE(hr);
  713. i++;
  714. VariantInit(&v);
  715. V_VT(&v) = VT_BSTR;
  716. V_BSTR(&v) = SysAllocString(pszNDSPathName);
  717. hr = SafeArrayPutElement(
  718. pFilter,
  719. (long *)&i,
  720. (void *)&v
  721. );
  722. VariantClear(&v);
  723. BAIL_ON_FAILURE(hr);
  724. V_VT(pvarNewMembers) = VT_ARRAY | VT_VARIANT;
  725. V_ARRAY(pvarNewMembers) = pFilter;
  726. RRETURN(S_OK);
  727. error:
  728. if (pFilter) {
  729. SafeArrayDestroy(pFilter);
  730. }
  731. RRETURN(hr);
  732. }
  733. HRESULT
  734. VarSingleRemoveEntry(
  735. LPWSTR pszNDSPathName,
  736. VARIANT varMembers,
  737. VARIANT * pvarNewMembers
  738. )
  739. {
  740. HRESULT hr = S_OK;
  741. VariantInit(pvarNewMembers);
  742. if(!((V_VT(&varMembers) & VT_TYPEMASK) == VT_BSTR)){
  743. return(E_FAIL);
  744. }
  745. V_VT(pvarNewMembers) = VT_EMPTY;
  746. V_BSTR(pvarNewMembers) = NULL;
  747. RRETURN(hr);
  748. }
  749. HRESULT
  750. VarRemoveEntry(
  751. LPWSTR pszNDSPathName,
  752. VARIANT varMembers,
  753. VARIANT * pvarNewMembers
  754. )
  755. {
  756. HRESULT hr = S_OK;
  757. if (V_VT(&varMembers) == (VT_VARIANT|VT_ARRAY)) {
  758. hr = VarMultipleRemoveEntry(
  759. pszNDSPathName,
  760. varMembers,
  761. pvarNewMembers
  762. );
  763. RRETURN(hr);
  764. }else if (V_VT(&varMembers) == VT_BSTR){
  765. hr = VarSingleRemoveEntry(
  766. pszNDSPathName,
  767. varMembers,
  768. pvarNewMembers
  769. );
  770. RRETURN(hr);
  771. }else {
  772. RRETURN(E_FAIL);
  773. }
  774. }
  775. HRESULT
  776. VarAddEntry(
  777. LPWSTR pszNDSPathName,
  778. VARIANT varMembers,
  779. VARIANT * pvarNewMembers
  780. )
  781. {
  782. HRESULT hr = S_OK;
  783. if (V_VT(&varMembers) == (VT_VARIANT|VT_ARRAY)){
  784. hr = VarMultipleAddEntry(
  785. pszNDSPathName,
  786. varMembers,
  787. pvarNewMembers
  788. );
  789. RRETURN(hr);
  790. }else if ((V_VT(&varMembers) & VT_TYPEMASK) == VT_BSTR){
  791. hr = VarSingleAddEntry(
  792. pszNDSPathName,
  793. varMembers,
  794. pvarNewMembers
  795. );
  796. RRETURN(hr);
  797. }else {
  798. RRETURN(E_FAIL);
  799. }
  800. }