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.

1376 lines
29 KiB

  1. /*
  2. File sdowrap.cpp
  3. Implements a wrapper for the sdo server class based on
  4. weijiang's rasuser.dll code.
  5. Paul Mayfield, 6/8/98
  6. */
  7. #include <nt.h>
  8. #include <ntrtl.h>
  9. #include <nturtl.h>
  10. #include <windows.h>
  11. #include <objbase.h>
  12. #include "sdoias.h"
  13. #include "sdolib.h"
  14. #include "sdowrap.h"
  15. #include "hashtab.h"
  16. //
  17. // Structure defines data returned as a profile
  18. //
  19. typedef struct _SDO_PROFILE
  20. {
  21. ISdo * pSdo; // sdo of profile
  22. ISdoCollection * pCollection; // attributes
  23. ISdoDictionaryOld * pDictionary; // associated dictionary
  24. ISdoServiceControl * pServiceControl; // associated ias service
  25. HANDLE hMap; // attribute map
  26. } SDO_PROFILE;
  27. //
  28. // Structure maps sdo object to an id
  29. //
  30. typedef struct _SDO_TO_ID {
  31. ISdo * pSdo;
  32. ULONG ulId;
  33. } SDO_TO_ID;
  34. //
  35. // Size of hash tables we'll use
  36. //
  37. #define SDO_HASH_SIZE 13
  38. //
  39. // External function prototypes
  40. //
  41. extern "C"
  42. {
  43. DWORD SdoTraceEx (DWORD dwErr, LPSTR pszTrace, ...);
  44. PVOID SdoAlloc (
  45. IN DWORD dwSize,
  46. IN BOOL bZero);
  47. VOID SdoFree (
  48. IN PVOID pvData);
  49. }
  50. HRESULT
  51. SdoCollectionGetNext(
  52. IEnumVARIANT* pEnum,
  53. ISdo** ppSdo);
  54. ULONG SdoHashId (
  55. IN HANDLE hId);
  56. int SdoCompIds (
  57. IN HANDLE hId,
  58. IN HANDLE hSdoNode);
  59. VOID SdoCleanupElement (
  60. IN HANDLE hSdoNode);
  61. DWORD
  62. SdoCreateIdMap(
  63. IN ISdoCollection * pCollection,
  64. OUT PHANDLE phMap);
  65. HRESULT
  66. SdoProfileSetAttribute(
  67. IN SDO_PROFILE* pProf,
  68. IN VARIANT* pVar,
  69. IN ULONG ulId);
  70. //
  71. // Strings
  72. //
  73. static const WCHAR pszIasService[] = L"IAS";
  74. static const WCHAR pszRemoteAccessService[] = L"RemoteAccess";
  75. //
  76. // Macros
  77. //
  78. #define SDO_RELEASE(_x) {if (_x) ((_x)->Release());}
  79. //
  80. // Define a class to act as a wrapper for sdo
  81. // server functionality.
  82. //
  83. class SdoMachine {
  84. public:
  85. // Construction/destruction
  86. //
  87. SdoMachine();
  88. SdoMachine(BOOL bLocal);
  89. ~SdoMachine();
  90. // Server connection
  91. //
  92. HRESULT Attach(
  93. BSTR pszMachine);
  94. // Get the machine sdo
  95. //
  96. ISdoMachine * GetMachine();
  97. // Get the dictionary sdo
  98. //
  99. ISdoDictionaryOld * GetDictionary();
  100. // Returns the ias service object
  101. IUnknown * GetIasService();
  102. IUnknown * GetRemoteAccessService();
  103. // Obtain user objects
  104. HRESULT GetUserSdo(
  105. BSTR bstrUserName,
  106. ISdo** ppUserSdo);
  107. // Obtain profiles
  108. HRESULT GetDefaultProfile(
  109. ISdo ** ppProfileSdo);
  110. protected:
  111. // Returns the datastore that should be
  112. // used for this machine
  113. IASDATASTORE GetDataStore();
  114. // Protected data
  115. ISdoMachine * m_pMachine;
  116. BOOL m_bDataStoreInitailzed;
  117. BOOL m_bLocal;
  118. IASDATASTORE m_IasDataStore;
  119. };
  120. //
  121. // Construct a server
  122. //
  123. SdoMachine::SdoMachine() {
  124. m_pMachine = NULL;
  125. m_bDataStoreInitailzed = FALSE;
  126. m_bLocal = TRUE;
  127. m_IasDataStore = DATA_STORE_LOCAL;
  128. }
  129. //
  130. // Construct a server
  131. //
  132. SdoMachine::SdoMachine(BOOL bLocal) {
  133. m_pMachine = NULL;
  134. m_bDataStoreInitailzed = FALSE;
  135. m_bLocal = bLocal;
  136. m_IasDataStore = (bLocal) ? DATA_STORE_LOCAL : DATA_STORE_DIRECTORY;
  137. }
  138. //
  139. // Cleanup a server
  140. //
  141. SdoMachine::~SdoMachine() {
  142. if (m_pMachine)
  143. m_pMachine->Release();
  144. }
  145. //
  146. // Attach to an SdoServer
  147. //
  148. HRESULT SdoMachine::Attach(
  149. IN BSTR pszMachine)
  150. {
  151. HRESULT hr = S_OK;
  152. VARIANT var;
  153. VariantInit(&var);
  154. do {
  155. // CoCreate the instance
  156. hr = CoCreateInstance(
  157. CLSID_SdoMachine,
  158. NULL,
  159. CLSCTX_INPROC_SERVER,
  160. IID_ISdoMachine,
  161. (void**)&m_pMachine);
  162. if (FAILED (hr))
  163. {
  164. SdoTraceEx(0, "CoCreateInstance SdoMachine failed %x\n", hr);
  165. break;
  166. }
  167. // Connect
  168. hr = m_pMachine->Attach(pszMachine);
  169. if (FAILED (hr))
  170. {
  171. SdoTraceEx(0, "SdoMachine::Attach failed %x\n", hr);
  172. break;
  173. }
  174. } while (FALSE);
  175. // Cleanup
  176. {
  177. VariantClear(&var);
  178. if ((FAILED(hr)) && (m_pMachine != NULL))
  179. {
  180. m_pMachine->Release();
  181. m_pMachine = NULL;
  182. }
  183. }
  184. return hr;
  185. }
  186. //
  187. // Returns the machine sdo for this machine
  188. //
  189. ISdoMachine* SdoMachine::GetMachine() {
  190. return m_pMachine;
  191. }
  192. //
  193. // Returns dictionary associated with this machine
  194. //
  195. ISdoDictionaryOld * SdoMachine::GetDictionary()
  196. {
  197. ISdoDictionaryOld * pRet = NULL;
  198. IUnknown * pUnk = NULL;
  199. HRESULT hr;
  200. do
  201. {
  202. hr = m_pMachine->GetDictionarySDO(&pUnk);
  203. if (FAILED (hr))
  204. {
  205. SetLastError(hr);
  206. break;
  207. }
  208. hr = pUnk->QueryInterface(IID_ISdoDictionaryOld, (VOID**)&pRet);
  209. if (FAILED (hr))
  210. {
  211. SetLastError(hr);
  212. break;
  213. }
  214. pRet->AddRef();
  215. } while (FALSE);
  216. // Cleanup
  217. {
  218. SDO_RELEASE(pUnk);
  219. SDO_RELEASE(pRet);
  220. }
  221. return pRet;
  222. }
  223. IUnknown * SdoMachine::GetIasService()
  224. {
  225. IUnknown * pRet = NULL;
  226. HRESULT hr = S_OK;
  227. BSTR bstrService = SysAllocString(pszIasService);
  228. do
  229. {
  230. if (bstrService == NULL)
  231. {
  232. break;
  233. }
  234. hr = m_pMachine->GetServiceSDO(
  235. GetDataStore(),
  236. bstrService,
  237. &pRet);
  238. if (FAILED (hr))
  239. {
  240. SetLastError(hr);
  241. break;
  242. }
  243. } while (FALSE);
  244. // Cleanup
  245. {
  246. if (FAILED (hr))
  247. {
  248. SDO_RELEASE(pRet);
  249. }
  250. if (bstrService)
  251. {
  252. SysFreeString(bstrService);
  253. }
  254. }
  255. return pRet;
  256. }
  257. IUnknown * SdoMachine::GetRemoteAccessService()
  258. {
  259. IUnknown * pRet = NULL;
  260. HRESULT hr = S_OK;
  261. BSTR bstrService = SysAllocString(pszRemoteAccessService);
  262. do
  263. {
  264. if (bstrService == NULL)
  265. {
  266. break;
  267. }
  268. hr = m_pMachine->GetServiceSDO(
  269. GetDataStore(),
  270. bstrService,
  271. &pRet);
  272. if (FAILED (hr))
  273. {
  274. SetLastError(hr);
  275. break;
  276. }
  277. } while (FALSE);
  278. // Cleanup
  279. {
  280. if (FAILED (hr))
  281. {
  282. SDO_RELEASE(pRet);
  283. }
  284. if (bstrService)
  285. {
  286. SysFreeString(bstrService);
  287. }
  288. }
  289. return pRet;
  290. }
  291. //
  292. // Get a reference to the given user from the
  293. // sdo server
  294. //
  295. HRESULT SdoMachine::GetUserSdo(
  296. IN BSTR bstrUserName,
  297. OUT ISdo** ppUserSdo)
  298. {
  299. HRESULT hr = S_OK;
  300. IUnknown* pUnkn = NULL;
  301. // Validate parameters
  302. if(!ppUserSdo)
  303. {
  304. return E_INVALIDARG;
  305. }
  306. if (! m_pMachine)
  307. {
  308. return E_POINTER;
  309. }
  310. do {
  311. // Get the user from the machine
  312. hr = m_pMachine->GetUserSDO(GetDataStore(), bstrUserName, &pUnkn);
  313. if (FAILED (hr))
  314. {
  315. SdoTraceEx (0,"GetUserSdo failed %x\n", hr);
  316. break;
  317. }
  318. // Get the required interface
  319. hr = pUnkn->QueryInterface(IID_ISdo, (void**)ppUserSdo);
  320. if (FAILED (hr))
  321. {
  322. SdoTraceEx (0,"User has no SDO interface %x\n", hr);
  323. break;
  324. }
  325. } while (FALSE);
  326. // Cleanup
  327. {
  328. if (pUnkn)
  329. pUnkn->Release();
  330. }
  331. return hr;
  332. }
  333. //
  334. // Obtains default profile from the sdo
  335. //
  336. HRESULT
  337. SdoMachine::GetDefaultProfile(
  338. ISdo ** ppProfileSdo)
  339. {
  340. IDispatch* pDisp = NULL;
  341. IEnumVARIANT* pEnum = NULL;
  342. ISdo * pSdo = NULL;
  343. IUnknown * pUnkn = NULL;
  344. IUnknown *pUnknEnum = NULL;
  345. ISdoCollection * pCollection = NULL;
  346. PWCHAR bstrService = NULL;
  347. VARIANT var;
  348. HRESULT hr = S_OK;
  349. INT iCmp;
  350. // Make sure we're ready to go
  351. if(! ppProfileSdo)
  352. return E_INVALIDARG;
  353. if (! m_pMachine)
  354. return E_FAIL;
  355. VariantInit(&var);
  356. do {
  357. // Initialize the service name
  358. bstrService = SysAllocString(pszIasService);
  359. if (bstrService == NULL)
  360. {
  361. SdoTraceEx (0, "GetProfile: unable to alloc service name\n");
  362. hr = E_OUTOFMEMORY;
  363. break;
  364. }
  365. // Get the service SDO
  366. pUnkn = GetRemoteAccessService();
  367. if (pUnkn == NULL)
  368. {
  369. hr = GetLastError();
  370. break;
  371. }
  372. // Get an SDO reference to the service object
  373. hr = pUnkn->QueryInterface(IID_ISdo, (VOID**)&pSdo);
  374. if (FAILED (hr))
  375. {
  376. SdoTraceEx (0,"GetProfile: no service sdo %x\n", hr);
  377. break;
  378. }
  379. // Get the profiles collection for the service
  380. hr = pSdo->GetProperty(
  381. PROPERTY_IAS_PROFILES_COLLECTION,
  382. &var);
  383. if (FAILED (hr))
  384. {
  385. SdoTraceEx (0,"GetProfile: no profiles collection %x\n", hr);
  386. break;
  387. }
  388. // We're done with the service sdo
  389. pSdo->Release();
  390. pSdo = NULL;
  391. // Get the collection interface to the profiles collection
  392. hr = (V_DISPATCH(&var))->QueryInterface(
  393. IID_ISdoCollection,
  394. (VOID**)&pCollection);
  395. if (FAILED (hr))
  396. {
  397. SdoTraceEx (0,"GetProfile: collec interface %x\n", hr);
  398. break;
  399. }
  400. // Get an enumerator for the profiles collection
  401. hr = pCollection->get__NewEnum(&pUnknEnum);
  402. if (FAILED (hr))
  403. {
  404. SdoTraceEx (0,"GetProfile: no collec enumerator %x\n", hr);
  405. break;
  406. }
  407. // Get the variant enumerator interface of the profiles collection
  408. hr = pUnknEnum->QueryInterface(
  409. IID_IEnumVARIANT,
  410. (VOID**)&pEnum);
  411. // Get the first profile
  412. pEnum->Reset();
  413. hr = SdoCollectionGetNext(pEnum, &pSdo);
  414. if (hr != S_OK)
  415. {
  416. SdoTraceEx (0,"GetProfile: no profile %x\n", hr);
  417. hr = DISP_E_MEMBERNOTFOUND;
  418. break;
  419. }
  420. // Make sure there is only one profile
  421. //
  422. {
  423. ISdo* pSdo2 = NULL;
  424. HRESULT hr2 = S_OK;
  425. hr2 = SdoCollectionGetNext(pEnum, &pSdo2);
  426. SDO_RELEASE(pSdo2);
  427. if (hr2 == S_OK)
  428. {
  429. SdoTraceEx(0, "GetProfile: multiple found, returning error\n");
  430. hr = DISP_E_MEMBERNOTFOUND;
  431. break;
  432. }
  433. }
  434. // Done
  435. *ppProfileSdo = pSdo;
  436. pSdo = NULL;
  437. } while (FALSE);
  438. // Cleanup
  439. {
  440. SDO_RELEASE (pDisp);
  441. SDO_RELEASE (pSdo);
  442. SDO_RELEASE (pEnum);
  443. SDO_RELEASE (pUnkn);
  444. SDO_RELEASE (pUnknEnum);
  445. SDO_RELEASE (pCollection);
  446. VariantClear(&var);
  447. if (bstrService)
  448. SysFreeString(bstrService);
  449. }
  450. return hr;
  451. }
  452. //
  453. // Get the data store for this machine
  454. //
  455. IASDATASTORE SdoMachine::GetDataStore() {
  456. VARIANT_BOOL vbDirectory = VARIANT_FALSE;
  457. HRESULT hr;
  458. if (! m_bDataStoreInitailzed)
  459. {
  460. do {
  461. // Determine whether a local verses directory user should
  462. // be loaded.
  463. hr = m_pMachine->IsDirectoryAvailable(&vbDirectory);
  464. if (FAILED (hr))
  465. {
  466. SdoTraceEx (0,"IsDirectoryAvailable failed %x\n", hr);
  467. break;
  468. }
  469. // If the user wants a local user, it's always ok to
  470. // attempt to get it.
  471. if (m_bLocal)
  472. {
  473. m_IasDataStore = DATA_STORE_LOCAL;
  474. }
  475. // Otherwise, a directory user is being requested
  476. else
  477. {
  478. // Directory is available, go to the ds
  479. if (vbDirectory == VARIANT_TRUE)
  480. {
  481. m_IasDataStore = DATA_STORE_DIRECTORY;
  482. }
  483. // Directory's not available, exit with error
  484. else if (vbDirectory == VARIANT_FALSE)
  485. {
  486. m_IasDataStore = DATA_STORE_LOCAL;
  487. SdoTraceEx(0, "GetUserSdo: DS user but no DS %x\n", hr);
  488. break;
  489. }
  490. }
  491. } while (FALSE);
  492. // Remember that we've already calculated the data store
  493. m_bDataStoreInitailzed = TRUE;
  494. }
  495. return m_IasDataStore;
  496. }
  497. //
  498. // Opens an sdo server and connects to it.
  499. //
  500. HRESULT WINAPI
  501. SdoWrapOpenServer(
  502. IN BSTR pszMachine,
  503. IN BOOL bLocal,
  504. OUT HANDLE* phSdoSrv)
  505. {
  506. HRESULT hr;
  507. if(! phSdoSrv)
  508. return E_INVALIDARG;
  509. *phSdoSrv = NULL;
  510. // Build the machine wrapper for the given
  511. // machine
  512. SdoMachine* pSdoSrv = new SdoMachine(bLocal);
  513. if(! pSdoSrv)
  514. return E_OUTOFMEMORY;
  515. // Attach the wrapper to the desired macine
  516. hr = pSdoSrv->Attach(
  517. pszMachine);
  518. if(S_OK == hr)
  519. *phSdoSrv = (HANDLE)pSdoSrv;
  520. else
  521. delete pSdoSrv;
  522. return hr;
  523. }
  524. //
  525. // Closes out an open sdo server object
  526. //
  527. HRESULT WINAPI
  528. SdoWrapCloseServer(
  529. IN HANDLE hSdoSrv)
  530. {
  531. SdoMachine* pSdoSrv;
  532. pSdoSrv = (SdoMachine*)hSdoSrv;
  533. if (pSdoSrv)
  534. delete pSdoSrv;
  535. return S_OK;
  536. }
  537. //
  538. // Get a reference to a user in the sdo object
  539. //
  540. // returns S_OK, or error message from SDO
  541. //
  542. HRESULT WINAPI
  543. SdoWrapOpenUser(
  544. IN HANDLE hSdoSrv,
  545. IN BSTR pszUser,
  546. OUT HANDLE* phSdoObj)
  547. {
  548. SdoMachine* pSdoSrv = (SdoMachine*)hSdoSrv;
  549. HRESULT hr = S_OK;
  550. ISdo* pSdo = NULL;
  551. if(!hSdoSrv || !phSdoObj)
  552. return E_INVALIDARG;
  553. // Get the user object
  554. hr = pSdoSrv->GetUserSdo(pszUser, &pSdo);
  555. if(! FAILED(hr))
  556. {
  557. *phSdoObj = (HANDLE)pSdo;
  558. }
  559. return hr;
  560. }
  561. //
  562. // Retrieves the default profile object
  563. //
  564. HRESULT WINAPI
  565. SdoWrapOpenDefaultProfile (
  566. IN HANDLE hSdoSrv,
  567. OUT PHANDLE phProfile)
  568. {
  569. SdoMachine* pMachine = (SdoMachine*)hSdoSrv;
  570. HRESULT hr = S_OK;
  571. ISdo* pSdo = NULL;
  572. ISdoCollection * pCollection = NULL;
  573. ISdoDictionaryOld * pDictionary = NULL;
  574. IUnknown * pUnkn = NULL;
  575. ISdoServiceControl * pServiceControl = NULL;
  576. HANDLE hMap = NULL;
  577. SDO_PROFILE * pProf = NULL;
  578. VARIANT var;
  579. // Validate parameters
  580. if ((pMachine == NULL) || (phProfile == NULL))
  581. {
  582. return E_INVALIDARG;
  583. }
  584. VariantInit(&var);
  585. do
  586. {
  587. // Initialize a structure to hold the profile
  588. pProf = (SDO_PROFILE*) SdoAlloc(sizeof(SDO_PROFILE), TRUE);
  589. if (pProf == NULL)
  590. {
  591. hr = ERROR_NOT_ENOUGH_MEMORY;
  592. break;
  593. }
  594. // Get the sdo reference to the default profile
  595. // from the server
  596. hr = pMachine->GetDefaultProfile(&pSdo);
  597. if (FAILED (hr))
  598. {
  599. break;
  600. }
  601. if (pSdo == NULL)
  602. {
  603. hr = E_FAIL;
  604. break;
  605. }
  606. // Get the collection of attributes
  607. hr = pSdo->GetProperty(
  608. PROPERTY_PROFILE_ATTRIBUTES_COLLECTION,
  609. &var);
  610. if (FAILED (hr))
  611. {
  612. break;
  613. }
  614. // Get a reference to the IsdoCollection
  615. hr = V_DISPATCH(&var)->QueryInterface(
  616. IID_ISdoCollection,
  617. (VOID**)&pCollection);
  618. if (FAILED (hr))
  619. {
  620. break;
  621. }
  622. // Load the attributes for the profile
  623. hr = SdoCreateIdMap(pCollection, &hMap);
  624. if (hr != NO_ERROR)
  625. {
  626. break;
  627. }
  628. // Get the dictionary for the profile
  629. pDictionary = pMachine->GetDictionary();
  630. if (pDictionary == NULL)
  631. {
  632. hr = GetLastError();
  633. break;
  634. }
  635. // Get the service for the profile
  636. pUnkn = pMachine->GetRemoteAccessService();
  637. if (pUnkn == NULL)
  638. {
  639. hr = GetLastError();
  640. break;
  641. }
  642. // If this call fails, pServiceControl
  643. // will be silently NULL which is what
  644. // we want (it's not required).
  645. pUnkn->QueryInterface(
  646. IID_ISdoServiceControl,
  647. (VOID**)&pServiceControl);
  648. // Initialize the sdo control block.
  649. pProf->pSdo = pSdo;
  650. pProf->pCollection = pCollection;
  651. pProf->pDictionary = pDictionary;
  652. pProf->pServiceControl = pServiceControl;
  653. pProf->hMap = hMap;
  654. *phProfile = (HANDLE)pProf;
  655. } while (FALSE);
  656. // Cleanup
  657. {
  658. if (FAILED (hr))
  659. {
  660. HashTabCleanup(hMap);
  661. SDO_RELEASE(pSdo);
  662. SDO_RELEASE(pCollection);
  663. SDO_RELEASE(pDictionary);
  664. SDO_RELEASE(pServiceControl);
  665. SdoFree(pProf);
  666. }
  667. SDO_RELEASE(pUnkn);
  668. VariantClear(&var);
  669. }
  670. return hr;
  671. }
  672. //
  673. // Closes an open sdo object
  674. //
  675. HRESULT WINAPI
  676. SdoWrapClose(
  677. IN HANDLE hSdoObj)
  678. {
  679. ISdo* pSdo = (ISdo*)hSdoObj;
  680. if (pSdo)
  681. pSdo->Release();
  682. return S_OK;
  683. }
  684. //
  685. // Closes an open sdo profile
  686. //
  687. HRESULT WINAPI
  688. SdoWrapCloseProfile(
  689. IN HANDLE hProfile)
  690. {
  691. SDO_PROFILE* pProf = (SDO_PROFILE*)hProfile;
  692. if (pProf)
  693. {
  694. // Cleanup the hashtab of values
  695. if (pProf->hMap)
  696. {
  697. HashTabCleanup(pProf->hMap);
  698. }
  699. SDO_RELEASE(pProf->pSdo);
  700. SDO_RELEASE(pProf->pCollection);
  701. SDO_RELEASE(pProf->pDictionary);
  702. SDO_RELEASE(pProf->pServiceControl);
  703. SdoFree(pProf);
  704. }
  705. return S_OK;
  706. }
  707. //
  708. // Commits an sdo object
  709. //
  710. // bCommitChanges -- TRUE, all changes are saved,
  711. // FALSE restore to previous commit
  712. // returns S_OK or error message from SDO
  713. //
  714. HRESULT WINAPI
  715. SdoWrapCommit(
  716. IN HANDLE hSdoObj,
  717. IN BOOL bCommitChanges)
  718. {
  719. ISdo* pSdo = (ISdo*)hSdoObj;
  720. if (! bCommitChanges)
  721. return pSdo->Restore();
  722. return pSdo->Apply();
  723. }
  724. //
  725. // Get's an sdo attribute
  726. //
  727. // when attribute is absent,
  728. // V_VT(pVar) = VT_ERROR;
  729. // V_ERROR(pVar) = DISP_E_PARAMNOTFOUND;
  730. //
  731. // returns S_OK or error message from SDO
  732. //
  733. HRESULT WINAPI
  734. SdoWrapGetAttr(
  735. IN HANDLE hSdoObj,
  736. IN ULONG ulPropId,
  737. OUT VARIANT* pVar)
  738. {
  739. ISdo* pSdo = (ISdo*)hSdoObj;
  740. return pSdo->GetProperty(ulPropId, pVar);
  741. }
  742. //
  743. // Puts an sdo attribute
  744. //
  745. // returns S_OK or error message from SDO
  746. //
  747. HRESULT WINAPI
  748. SdoWrapPutAttr(
  749. IN HANDLE hSdoObj,
  750. IN ULONG ulPropId,
  751. OUT VARIANT* pVar)
  752. {
  753. ISdo* pSdo = (ISdo*)hSdoObj;
  754. return pSdo->PutProperty(ulPropId, pVar);
  755. }
  756. //
  757. // Remove an attribute
  758. //
  759. // returns S_OK or error message from SDO
  760. //
  761. HRESULT WINAPI
  762. SdoWrapRemoveAttr(
  763. IN HANDLE hSdoObj,
  764. IN ULONG ulPropId)
  765. {
  766. ISdo* pSdo = (ISdo*)hSdoObj;
  767. VARIANT var;
  768. VariantInit(&var);
  769. V_VT(&var) = VT_EMPTY;
  770. return pSdo->PutProperty(ulPropId, &var);
  771. }
  772. //
  773. // Reads in the set of profile values that we're interested
  774. // in.
  775. //
  776. HRESULT
  777. SdoWrapGetProfileValues(
  778. IN HANDLE hProfile,
  779. OUT VARIANT* pvarEp,
  780. OUT VARIANT* pvarEt,
  781. OUT VARIANT* pvarAt)
  782. {
  783. SDO_TO_ID * pNode = NULL;
  784. SDO_PROFILE * pProf = (SDO_PROFILE*)hProfile;
  785. // Validate
  786. if (pProf == NULL)
  787. {
  788. return E_INVALIDARG;
  789. }
  790. // Initialize
  791. V_VT(pvarEp) = VT_EMPTY;
  792. V_VT(pvarEt) = VT_EMPTY;
  793. V_VT(pvarAt) = VT_EMPTY;
  794. // Read in the enc policy
  795. pNode = NULL;
  796. HashTabFind(
  797. pProf->hMap,
  798. (HANDLE)RAS_ATTRIBUTE_ENCRYPTION_POLICY,
  799. (HANDLE*)&pNode);
  800. if (pNode)
  801. {
  802. pNode->pSdo->GetProperty(PROPERTY_ATTRIBUTE_VALUE, pvarEp);
  803. }
  804. // Read in the enc type
  805. pNode = NULL;
  806. HashTabFind(
  807. pProf->hMap,
  808. (HANDLE)RAS_ATTRIBUTE_ENCRYPTION_TYPE,
  809. (HANDLE*)&pNode);
  810. if (pNode)
  811. {
  812. pNode->pSdo->GetProperty(PROPERTY_ATTRIBUTE_VALUE, pvarEt);
  813. }
  814. // Read in the auth type
  815. pNode = NULL;
  816. HashTabFind(
  817. pProf->hMap,
  818. (HANDLE)IAS_ATTRIBUTE_NP_AUTHENTICATION_TYPE,
  819. (HANDLE*)&pNode);
  820. if (pNode)
  821. {
  822. pNode->pSdo->GetProperty(PROPERTY_ATTRIBUTE_VALUE, pvarAt);
  823. }
  824. return S_OK;
  825. }
  826. //
  827. // Writes out the set of profile values that we're interested
  828. // in.
  829. //
  830. HRESULT
  831. SdoWrapSetProfileValues(
  832. IN HANDLE hProfile,
  833. IN VARIANT* pvarEp OPTIONAL,
  834. IN VARIANT* pvarEt OPTIONAL,
  835. IN VARIANT* pvarAt OPTIONAL)
  836. {
  837. SDO_PROFILE * pProf = (SDO_PROFILE*)hProfile;
  838. HRESULT hr = S_OK;
  839. // Validate
  840. if (pProf == NULL)
  841. {
  842. return E_INVALIDARG;
  843. }
  844. do
  845. {
  846. // Write out the values
  847. if (pvarEp)
  848. {
  849. hr = SdoProfileSetAttribute(
  850. pProf,
  851. pvarEp,
  852. RAS_ATTRIBUTE_ENCRYPTION_POLICY);
  853. if (FAILED (hr))
  854. {
  855. break;
  856. }
  857. }
  858. if (pvarEt)
  859. {
  860. hr = SdoProfileSetAttribute(
  861. pProf,
  862. pvarEt,
  863. RAS_ATTRIBUTE_ENCRYPTION_TYPE);
  864. if (FAILED (hr))
  865. {
  866. break;
  867. }
  868. }
  869. if (pvarAt)
  870. {
  871. hr = SdoProfileSetAttribute(
  872. pProf,
  873. pvarAt,
  874. IAS_ATTRIBUTE_NP_AUTHENTICATION_TYPE);
  875. if (FAILED (hr))
  876. {
  877. break;
  878. }
  879. }
  880. // Commit the values
  881. hr = pProf->pSdo->Apply();
  882. if (FAILED (hr))
  883. {
  884. break;
  885. }
  886. // Tell the service to restart so it reads in the
  887. // new profile values we've set.
  888. if (pProf->pServiceControl)
  889. {
  890. hr = pProf->pServiceControl->ResetService();
  891. SdoTraceEx(0, "ResetService returned: %x!\n", hr);
  892. hr = S_OK;
  893. //if (FAILED (hr))
  894. //{
  895. // break;
  896. //}
  897. }
  898. else
  899. {
  900. SdoTraceEx(0, "NO SERVICE CONTROL INTERFACE!\n");
  901. }
  902. } while (FALSE);
  903. // Cleanup
  904. {
  905. }
  906. return hr;
  907. }
  908. //
  909. // Retrieves the next item from a collection
  910. //
  911. HRESULT
  912. SdoCollectionGetNext(
  913. IEnumVARIANT* pEnum,
  914. ISdo** ppSdo)
  915. {
  916. HRESULT hr;
  917. DWORD dwRetrieved = 1;
  918. VARIANT var;
  919. // Get the next value
  920. VariantInit(&var);
  921. hr = pEnum->Next(1, &var, &dwRetrieved);
  922. if ( S_OK == hr ) {
  923. hr = V_DISPATCH(&var)->QueryInterface(
  924. IID_ISdo,
  925. (void**)ppSdo);
  926. }
  927. VariantClear(&var);
  928. return hr;
  929. }
  930. //
  931. // Hash table functions that take advantage of
  932. // SDO_TO_ID structures
  933. //
  934. ULONG SdoHashId (HANDLE hId) {
  935. ULONG ulId = PtrToUlong(hId);
  936. return (ulId % SDO_HASH_SIZE);
  937. }
  938. //
  939. // Compare two ids
  940. //
  941. int SdoCompIds (HANDLE hId, HANDLE hSdoNode) {
  942. ULONG ulId = PtrToUlong(hId);
  943. SDO_TO_ID * pSdoNode = (SDO_TO_ID*)hSdoNode;
  944. if (ulId == pSdoNode->ulId)
  945. {
  946. return 0;
  947. }
  948. else if (ulId > pSdoNode->ulId)
  949. {
  950. return 1;
  951. }
  952. return -1;
  953. }
  954. //
  955. // Cleanup data in the hash table
  956. //
  957. VOID SdoCleanupElement (HANDLE hSdoNode) {
  958. SDO_TO_ID * pSdoNode = (SDO_TO_ID*)hSdoNode;
  959. if (pSdoNode) {
  960. SDO_RELEASE(pSdoNode->pSdo);
  961. delete pSdoNode;
  962. }
  963. }
  964. //
  965. // Creates an attribute to id map given a collection
  966. //
  967. DWORD
  968. SdoCreateIdMap(
  969. IN ISdoCollection * pCollection,
  970. OUT PHANDLE phMap)
  971. {
  972. HRESULT hr;
  973. SDO_TO_ID * pMapNode = NULL;
  974. VARIANT var, *pVar = NULL;
  975. ULONG ulCount;
  976. IUnknown * pUnk = NULL;
  977. IEnumVARIANT * pEnum = NULL;
  978. DWORD i;
  979. do
  980. {
  981. // Get the count to see if there are any attributes
  982. hr = pCollection->get_Count((long*)&ulCount);
  983. if (FAILED (hr))
  984. {
  985. break;
  986. }
  987. if (ulCount == 0)
  988. {
  989. hr = S_OK;
  990. break;
  991. }
  992. // Create the map
  993. hr = HashTabCreate(
  994. SDO_HASH_SIZE,
  995. SdoHashId,
  996. SdoCompIds,
  997. NULL,
  998. NULL,
  999. SdoCleanupElement,
  1000. phMap);
  1001. if (hr != NO_ERROR)
  1002. {
  1003. break;
  1004. }
  1005. // Get an attribute enumerator
  1006. hr = pCollection->get__NewEnum(&pUnk);
  1007. if (FAILED (hr))
  1008. {
  1009. break;
  1010. }
  1011. // Get the enum variant interface for the enumerator
  1012. hr = pUnk->QueryInterface(IID_IEnumVARIANT, (void**)&pEnum);
  1013. if (FAILED (hr))
  1014. {
  1015. break;
  1016. }
  1017. // Create a buffer large enough to hold the result
  1018. // of the enumeration.
  1019. pVar = new VARIANT[ulCount];
  1020. if(!pVar)
  1021. {
  1022. return E_OUTOFMEMORY;
  1023. }
  1024. // Initialize the buffer
  1025. for(i = 0; i < ulCount; i++)
  1026. {
  1027. VariantInit(pVar + i);
  1028. }
  1029. // Enumerate
  1030. hr = pEnum->Reset();
  1031. if (FAILED (hr))
  1032. {
  1033. return hr;
  1034. }
  1035. hr = pEnum->Next(ulCount, pVar, &ulCount);
  1036. if (FAILED (hr))
  1037. {
  1038. return hr;
  1039. }
  1040. // Fill in the map
  1041. for(i = 0; i < ulCount; i++)
  1042. {
  1043. VariantInit(&var);
  1044. // Initialize the node in the map
  1045. pMapNode = new SDO_TO_ID;
  1046. if (! pMapNode)
  1047. {
  1048. hr = E_OUTOFMEMORY;
  1049. break;
  1050. }
  1051. // Get the current attribute
  1052. hr = V_DISPATCH(pVar + i)->QueryInterface(
  1053. IID_ISdo,
  1054. (void**)&(pMapNode->pSdo));
  1055. if (FAILED (hr))
  1056. {
  1057. delete pMapNode;
  1058. continue;
  1059. }
  1060. // Get it's id
  1061. hr = pMapNode->pSdo->GetProperty(
  1062. PROPERTY_ATTRIBUTE_ID,
  1063. &var);
  1064. if (FAILED (hr))
  1065. {
  1066. delete pMapNode;
  1067. continue;
  1068. }
  1069. // Map it
  1070. pMapNode->ulId = V_I4(&var);
  1071. HashTabInsert (
  1072. *phMap,
  1073. (HANDLE)UlongToPtr(pMapNode->ulId),
  1074. (HANDLE)pMapNode);
  1075. VariantClear(&var);
  1076. }
  1077. } while (FALSE);
  1078. // Cleanup
  1079. {
  1080. if (pVar)
  1081. {
  1082. for(i = 0; i < ulCount; i++)
  1083. {
  1084. VariantClear(pVar + i);
  1085. }
  1086. delete[] pVar;
  1087. }
  1088. SDO_RELEASE(pUnk);
  1089. SDO_RELEASE(pEnum);
  1090. }
  1091. return hr;
  1092. }
  1093. //
  1094. // Sets a value in an attribute collection, adding it
  1095. // to the collection as needed.
  1096. //
  1097. HRESULT
  1098. SdoProfileSetAttribute(
  1099. IN SDO_PROFILE* pProf,
  1100. IN VARIANT* pVar,
  1101. IN ULONG ulPropId)
  1102. {
  1103. SDO_TO_ID * pNode = NULL;
  1104. ISdo * pSdo = NULL;
  1105. IDispatch * pDispatch = NULL;
  1106. HRESULT hr = S_OK;
  1107. do
  1108. {
  1109. // Search for the given attribute in the
  1110. // table.
  1111. pNode = NULL;
  1112. HashTabFind(
  1113. pProf->hMap,
  1114. (HANDLE)UlongToPtr(ulPropId),
  1115. (HANDLE*)&pNode);
  1116. // If attribute is found, then we have the sdo interface
  1117. // we need
  1118. if (pNode)
  1119. {
  1120. pSdo = pNode->pSdo;
  1121. }
  1122. // Otherwise, we need to add the value to the collection
  1123. else
  1124. {
  1125. // Create the attribute using the dictionary
  1126. hr = pProf->pDictionary->CreateAttribute(
  1127. (ATTRIBUTEID)ulPropId,
  1128. &pDispatch);
  1129. if (FAILED (hr))
  1130. {
  1131. break;
  1132. }
  1133. // Add to the collection
  1134. hr = pProf->pCollection->Add(NULL, &pDispatch);
  1135. if (FAILED (hr))
  1136. {
  1137. break;
  1138. }
  1139. // Get the sdo interface
  1140. hr = pDispatch->QueryInterface(IID_ISdo, (VOID**)&pSdo);
  1141. if (FAILED(hr))
  1142. {
  1143. break;
  1144. }
  1145. // Update the hash table
  1146. pNode = new SDO_TO_ID;
  1147. if (!pNode)
  1148. {
  1149. hr = E_OUTOFMEMORY;
  1150. break;
  1151. }
  1152. // Add ref so we can track the sdo in the hash table
  1153. pSdo->AddRef();
  1154. pNode->ulId = ulPropId;
  1155. pNode->pSdo = pSdo;
  1156. HashTabInsert (pProf->hMap, (HANDLE)UlongToPtr(ulPropId), (HANDLE)pNode);
  1157. }
  1158. // Set the attribute
  1159. pSdo->PutProperty(PROPERTY_ATTRIBUTE_VALUE, pVar);
  1160. if (FAILED (hr))
  1161. {
  1162. break;
  1163. }
  1164. } while (FALSE);
  1165. // Cleanup
  1166. {
  1167. SDO_RELEASE(pDispatch);
  1168. }
  1169. return hr;
  1170. }