Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1815 lines
42 KiB

  1. // CSecStr1.cpp : Implementation of CISecStorApp and DLL registration.
  2. #include <nt.h>
  3. #include <ntrtl.h>
  4. #include <nturtl.h>
  5. #include <windows.h>
  6. #include "dpapiprv.h" // RPC protseq stuff
  7. #include "stdafx.h"
  8. #include "pstorec.h"
  9. #include "cSecStr1.h"
  10. #include "pstrpc.h"
  11. #include <wincrypt.h>
  12. #include "pstdef.h"
  13. #include "crtem.h"
  14. #include "defer.h"
  15. #include "pmacros.h"
  16. #include "debug.h"
  17. #include "unicode.h"
  18. #include "waitsvc.h"
  19. /*********************************************************************/
  20. /* MIDL allocate and free */
  21. /*********************************************************************/
  22. void __RPC_FAR * __RPC_API midl_user_allocate(size_t len)
  23. {
  24. return CoTaskMemAlloc(len);
  25. }
  26. void __RPC_API midl_user_free(void __RPC_FAR * ptr)
  27. {
  28. CoTaskMemFree(ptr);
  29. }
  30. RPC_STATUS BindW(WCHAR **pszBinding, RPC_BINDING_HANDLE *phBind)
  31. {
  32. RPC_STATUS status;
  33. //
  34. // on WinNT5, go to the shared services.exe RPC server
  35. //
  36. status = RpcStringBindingComposeW(
  37. NULL,
  38. (unsigned short*)DPAPI_LOCAL_PROT_SEQ,
  39. NULL,
  40. (unsigned short*)DPAPI_LOCAL_ENDPOINT,
  41. NULL,
  42. (unsigned short * *)pszBinding
  43. );
  44. if (status)
  45. {
  46. return(status);
  47. }
  48. status = RpcBindingFromStringBindingW(*pszBinding, phBind);
  49. return status;
  50. }
  51. RPC_STATUS UnbindW(WCHAR **pszBinding, RPC_BINDING_HANDLE *phBind)
  52. {
  53. RPC_STATUS status;
  54. status = RpcStringFreeW(pszBinding);
  55. if (status)
  56. {
  57. return(status);
  58. }
  59. RpcBindingFree(phBind);
  60. return RPC_S_OK;
  61. }
  62. //
  63. // define an ugly macro that allows us to provide enough context to work-around
  64. // a bug in imagehlp on win95.
  65. //
  66. #define InitCallContext( pCallContext ) \
  67. RealInitCallContext( pCallContext );
  68. BOOL RealInitCallContext(PST_CALL_CONTEXT *pCallContext)
  69. {
  70. HANDLE hCurrentThread;
  71. pCallContext->Handle = (DWORD_PTR)INVALID_HANDLE_VALUE;
  72. pCallContext->Address = GetCurrentProcessId();
  73. //
  74. // duplicate pseudo-current thread handle to real handle to pass to server
  75. //
  76. if(!DuplicateHandle(
  77. GetCurrentProcess(),
  78. GetCurrentThread(),
  79. GetCurrentProcess(),
  80. &hCurrentThread,
  81. 0,
  82. FALSE,
  83. DUPLICATE_SAME_ACCESS
  84. ))
  85. return FALSE;
  86. pCallContext->Handle = (DWORD_PTR)hCurrentThread;
  87. return TRUE;
  88. }
  89. BOOL DeleteCallContext(PST_CALL_CONTEXT* pCallContext)
  90. {
  91. if (pCallContext != NULL)
  92. {
  93. if(pCallContext->Handle != (DWORD_PTR)INVALID_HANDLE_VALUE)
  94. {
  95. CloseHandle((HANDLE)(pCallContext->Handle));
  96. pCallContext->Handle = (DWORD_PTR)INVALID_HANDLE_VALUE;
  97. }
  98. pCallContext->Address = 0;
  99. }
  100. return TRUE;
  101. }
  102. // RPC Binding class
  103. CRPCBinding::CRPCBinding()
  104. {
  105. }
  106. CRPCBinding::~CRPCBinding()
  107. {
  108. PST_CALL_CONTEXT CallContext;
  109. __try
  110. {
  111. InitCallContext(&CallContext);
  112. if (m_fGoodHProv) {
  113. SSReleaseContext(m_hBind, m_hProv, CallContext, 0);
  114. }
  115. if(m_wszStringBinding != NULL && m_hBind != NULL)
  116. UnbindW(&m_wszStringBinding, &m_hBind);
  117. }
  118. __except(EXCEPTION_EXECUTE_HANDLER)
  119. {
  120. // if RPCBinding being destroyed, catch anything RPC might throw
  121. // swallow!
  122. }
  123. DeleteCallContext(&CallContext);
  124. }
  125. static BOOL g_fDone = FALSE;
  126. HRESULT CRPCBinding::Init()
  127. {
  128. HRESULT hr;
  129. m_dwRef = 1;
  130. m_fGoodHProv = FALSE;
  131. m_wszStringBinding = NULL;
  132. m_hBind = NULL;
  133. WaitForCryptService(L"ProtectedStorage", &g_fDone);
  134. if(!IsServiceAvailable())
  135. return PST_E_SERVICE_UNAVAILABLE;
  136. return BindW(&m_wszStringBinding, &m_hBind);
  137. }
  138. HRESULT CRPCBinding::Acquire(
  139. IN PPST_PROVIDERID pProviderID,
  140. IN LPVOID pReserved,
  141. IN DWORD dwFlags
  142. )
  143. {
  144. PST_CALL_CONTEXT CallContext;
  145. HRESULT hr;
  146. __try
  147. {
  148. InitCallContext(&CallContext);
  149. // now we acquire context
  150. hr = SSAcquireContext(m_hBind,
  151. pProviderID,
  152. CallContext,
  153. (DWORD) GetCurrentProcessId(),
  154. &m_hProv,
  155. (DWORD_PTR)pReserved,
  156. dwFlags
  157. );
  158. if(hr != RPC_S_OK)
  159. goto Ret;
  160. m_fGoodHProv = TRUE;
  161. }
  162. __except(EXCEPTION_EXECUTE_HANDLER)
  163. {
  164. // catch anything RPC might throw
  165. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  166. }
  167. Ret:
  168. DeleteCallContext(&CallContext);
  169. return PSTERR_TO_HRESULT(hr);
  170. }
  171. CRPCBinding *CRPCBinding::AddRef()
  172. {
  173. m_dwRef++;
  174. return this;
  175. }
  176. void CRPCBinding::Release()
  177. {
  178. m_dwRef--;
  179. if (0 == m_dwRef)
  180. delete this;
  181. }
  182. /////////////////////////////////////////////////////////////////////////////
  183. //
  184. CPStore::CPStore()
  185. {
  186. }
  187. CPStore::~CPStore()
  188. {
  189. m_pBinding->Release();
  190. }
  191. void CPStore::Init(
  192. CRPCBinding *pBinding
  193. )
  194. {
  195. m_pBinding = pBinding;
  196. m_Index = 0;
  197. }
  198. HRESULT CPStore::CreateObject(
  199. CRPCBinding *pBinding,
  200. IPStore **ppv
  201. )
  202. {
  203. HRESULT hr;
  204. __try
  205. {
  206. typedef CComObject<CPStore> CObject;
  207. CObject* pnew = new CObject;
  208. if(NULL == pnew)
  209. {
  210. hr = E_OUTOFMEMORY;
  211. }
  212. else
  213. {
  214. pnew->Init(pBinding) ;
  215. hr = pnew->QueryInterface(IID_IPStore, (void**)ppv);
  216. }
  217. }
  218. __except(EXCEPTION_EXECUTE_HANDLER)
  219. {
  220. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  221. }
  222. return PSTERR_TO_HRESULT(hr);
  223. }
  224. HRESULT CPStore::CreateObject(
  225. CRPCBinding *pBinding,
  226. IEnumPStoreProviders **ppv
  227. )
  228. {
  229. HRESULT hr;
  230. __try
  231. {
  232. typedef CComObject<CPStore> CObject;
  233. CObject* pnew = new CObject;
  234. if(NULL == pnew)
  235. {
  236. hr = E_OUTOFMEMORY;
  237. }
  238. else
  239. {
  240. pnew->Init(pBinding);
  241. hr = pnew->QueryInterface(IID_IEnumPStoreProviders, (void**)ppv);
  242. }
  243. }
  244. __except(EXCEPTION_EXECUTE_HANDLER)
  245. {
  246. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  247. }
  248. return PSTERR_TO_HRESULT(hr);
  249. }
  250. HRESULT STDMETHODCALLTYPE CPStore::GetInfo(
  251. /* [out] */ PPST_PROVIDERINFO __RPC_FAR *ppProperties)
  252. {
  253. HRESULT hr;
  254. PST_CALL_CONTEXT CallContext;
  255. __try
  256. {
  257. InitCallContext(&CallContext);
  258. *ppProperties = NULL;
  259. if (RPC_S_OK != (hr =
  260. SSGetProvInfo(m_pBinding->m_hBind,
  261. m_pBinding->m_hProv,
  262. CallContext,
  263. ppProperties,
  264. 0)))
  265. goto Ret;
  266. }
  267. __except(EXCEPTION_EXECUTE_HANDLER)
  268. {
  269. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  270. }
  271. Ret:
  272. DeleteCallContext(&CallContext);
  273. return PSTERR_TO_HRESULT(hr);
  274. }
  275. HRESULT STDMETHODCALLTYPE CPStore::GetProvParam(
  276. /* [in] */ DWORD dwParam,
  277. /* [out] */ DWORD __RPC_FAR *pcbData,
  278. /* [out] */ BYTE __RPC_FAR **ppbData,
  279. /* [in] */ DWORD dwFlags)
  280. {
  281. HRESULT hr;
  282. PST_CALL_CONTEXT CallContext;
  283. __try
  284. {
  285. InitCallContext(&CallContext);
  286. *pcbData = 0;
  287. *ppbData = NULL;
  288. if (RPC_S_OK != (hr =
  289. SSGetProvParam(m_pBinding->m_hBind,
  290. m_pBinding->m_hProv,
  291. CallContext,
  292. dwParam,
  293. pcbData,
  294. ppbData,
  295. dwFlags)))
  296. goto Ret;
  297. }
  298. __except(EXCEPTION_EXECUTE_HANDLER)
  299. {
  300. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  301. }
  302. Ret:
  303. DeleteCallContext(&CallContext);
  304. return PSTERR_TO_HRESULT(hr);
  305. }
  306. HRESULT STDMETHODCALLTYPE CPStore::SetProvParam(
  307. /* [in] */ DWORD dwParam,
  308. /* [in] */ DWORD cbData,
  309. /* [in] */ BYTE __RPC_FAR *pbData,
  310. /* [in] */ DWORD dwFlags)
  311. {
  312. HRESULT hr;
  313. PST_CALL_CONTEXT CallContext;
  314. __try
  315. {
  316. InitCallContext(&CallContext);
  317. hr = SSSetProvParam(m_pBinding->m_hBind,
  318. m_pBinding->m_hProv,
  319. CallContext,
  320. dwParam,
  321. cbData,
  322. pbData,
  323. dwFlags);
  324. }
  325. __except(EXCEPTION_EXECUTE_HANDLER)
  326. {
  327. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  328. }
  329. DeleteCallContext(&CallContext);
  330. return PSTERR_TO_HRESULT(hr);
  331. }
  332. HRESULT STDMETHODCALLTYPE CPStore::CreateType(
  333. /* [in] */ PST_KEY Key,
  334. /* [in] */ const GUID __RPC_FAR *pType,
  335. /* [in] */ PPST_TYPEINFO pInfo,
  336. /* [in] */ DWORD dwFlags)
  337. {
  338. // validate inputs
  339. if ((pInfo == NULL) || pInfo->cbSize != sizeof(PST_TYPEINFO))
  340. return E_INVALIDARG;
  341. if ( pInfo->szDisplayName == NULL )
  342. return E_INVALIDARG;
  343. if (pType == NULL)
  344. return E_INVALIDARG;
  345. HRESULT hr;
  346. PST_CALL_CONTEXT CallContext;
  347. __try
  348. {
  349. InitCallContext(&CallContext);
  350. hr = SSCreateType(m_pBinding->m_hBind,
  351. m_pBinding->m_hProv,
  352. CallContext,
  353. Key,
  354. pType,
  355. pInfo,
  356. dwFlags);
  357. }
  358. __except(EXCEPTION_EXECUTE_HANDLER)
  359. {
  360. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  361. }
  362. DeleteCallContext(&CallContext);
  363. return PSTERR_TO_HRESULT(hr);
  364. }
  365. HRESULT STDMETHODCALLTYPE CPStore::GetTypeInfo(
  366. /* [in] */ PST_KEY Key,
  367. /* [in] */ const GUID __RPC_FAR *pType,
  368. /* [out] */ PPST_TYPEINFO __RPC_FAR* ppInfo,
  369. /* [in] */ DWORD dwFlags)
  370. {
  371. HRESULT hr;
  372. PST_CALL_CONTEXT CallContext;
  373. if (pType == NULL)
  374. return E_INVALIDARG;
  375. if (ppInfo == NULL)
  376. return E_INVALIDARG;
  377. __try
  378. {
  379. InitCallContext(&CallContext);
  380. *ppInfo = NULL;
  381. if (RPC_S_OK != (hr =
  382. SSGetTypeInfo(m_pBinding->m_hBind,
  383. m_pBinding->m_hProv,
  384. CallContext,
  385. Key,
  386. pType,
  387. ppInfo,
  388. dwFlags)))
  389. goto Ret;
  390. }
  391. __except(EXCEPTION_EXECUTE_HANDLER)
  392. {
  393. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  394. }
  395. Ret:
  396. DeleteCallContext(&CallContext);
  397. return PSTERR_TO_HRESULT(hr);
  398. }
  399. HRESULT STDMETHODCALLTYPE CPStore::DeleteType(
  400. /* [in] */ PST_KEY Key,
  401. /* [in] */ const GUID __RPC_FAR *pType,
  402. /* [in] */ DWORD dwFlags)
  403. {
  404. if (pType == NULL)
  405. return E_INVALIDARG;
  406. PST_CALL_CONTEXT CallContext;
  407. HRESULT hr;
  408. __try
  409. {
  410. InitCallContext(&CallContext);
  411. hr = SSDeleteType(m_pBinding->m_hBind,
  412. m_pBinding->m_hProv,
  413. CallContext,
  414. Key,
  415. pType,
  416. dwFlags);
  417. }
  418. __except(EXCEPTION_EXECUTE_HANDLER)
  419. {
  420. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  421. }
  422. DeleteCallContext(&CallContext);
  423. return PSTERR_TO_HRESULT(hr);
  424. }
  425. HRESULT STDMETHODCALLTYPE CPStore::CreateSubtype(
  426. /* [in] */ PST_KEY Key,
  427. /* [in] */ const GUID __RPC_FAR *pType,
  428. /* [in] */ const GUID __RPC_FAR *pSubtype,
  429. /* [in] */ PPST_TYPEINFO pInfo,
  430. /* [in] */ PPST_ACCESSRULESET pRules,
  431. /* [in] */ DWORD dwFlags)
  432. {
  433. if ((pType == NULL) || (pSubtype == NULL))
  434. return E_INVALIDARG;
  435. if ( (pInfo == NULL) || (pInfo->cbSize != sizeof(PST_TYPEINFO)) )
  436. return E_INVALIDARG;
  437. // validate inputs
  438. if (pInfo->szDisplayName == NULL)
  439. return E_INVALIDARG;
  440. HRESULT hr;
  441. PST_CALL_CONTEXT CallContext;
  442. PST_ACCESSRULESET sNullRuleset = {sizeof(PST_ACCESSRULESET), 0, NULL};
  443. __try
  444. {
  445. InitCallContext(&CallContext);
  446. hr = SSCreateSubtype(m_pBinding->m_hBind,
  447. m_pBinding->m_hProv,
  448. CallContext,
  449. Key,
  450. pType,
  451. pSubtype,
  452. pInfo,
  453. &sNullRuleset, // always pass NullRuleset.
  454. dwFlags);
  455. }
  456. __except(EXCEPTION_EXECUTE_HANDLER)
  457. {
  458. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  459. }
  460. DeleteCallContext(&CallContext);
  461. return PSTERR_TO_HRESULT(hr);
  462. }
  463. HRESULT STDMETHODCALLTYPE CPStore::GetSubtypeInfo(
  464. /* [in] */ PST_KEY Key,
  465. /* [in] */ const GUID __RPC_FAR *pType,
  466. /* [in] */ const GUID __RPC_FAR *pSubtype,
  467. /* [out] */ PPST_TYPEINFO __RPC_FAR* ppInfo,
  468. /* [in] */ DWORD dwFlags)
  469. {
  470. if ((pType == NULL) || (pSubtype == NULL))
  471. return E_INVALIDARG;
  472. if (ppInfo == NULL)
  473. return E_INVALIDARG;
  474. HRESULT hr;
  475. PST_CALL_CONTEXT CallContext;
  476. __try
  477. {
  478. InitCallContext(&CallContext);
  479. *ppInfo = NULL;
  480. if (RPC_S_OK != (hr =
  481. SSGetSubtypeInfo(m_pBinding->m_hBind,
  482. m_pBinding->m_hProv,
  483. CallContext,
  484. Key,
  485. pType,
  486. pSubtype,
  487. ppInfo,
  488. dwFlags)))
  489. goto Ret;
  490. hr = S_OK;
  491. }
  492. __except(EXCEPTION_EXECUTE_HANDLER)
  493. {
  494. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  495. }
  496. Ret:
  497. DeleteCallContext(&CallContext);
  498. return PSTERR_TO_HRESULT(hr);
  499. }
  500. HRESULT STDMETHODCALLTYPE CPStore::DeleteSubtype(
  501. /* [in] */ PST_KEY Key,
  502. /* [in] */ const GUID __RPC_FAR *pType,
  503. /* [in] */ const GUID __RPC_FAR *pSubtype,
  504. /* [in] */ DWORD dwFlags)
  505. {
  506. if ((pType == NULL) || (pSubtype == NULL))
  507. return E_INVALIDARG;
  508. PST_CALL_CONTEXT CallContext;
  509. HRESULT hr;
  510. __try
  511. {
  512. InitCallContext(&CallContext);
  513. hr = SSDeleteSubtype(m_pBinding->m_hBind,
  514. m_pBinding->m_hProv,
  515. CallContext,
  516. Key,
  517. pType,
  518. pSubtype,
  519. dwFlags);
  520. }
  521. __except(EXCEPTION_EXECUTE_HANDLER)
  522. {
  523. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  524. }
  525. DeleteCallContext(&CallContext);
  526. return PSTERR_TO_HRESULT(hr);
  527. }
  528. HRESULT STDMETHODCALLTYPE CPStore::ReadAccessRuleset(
  529. /* [in] */ PST_KEY Key,
  530. /* [in] */ const GUID __RPC_FAR *pType,
  531. /* [in] */ const GUID __RPC_FAR *pSubtype,
  532. /* [out] */ PPST_ACCESSRULESET __RPC_FAR *ppRules,
  533. /* [in] */ DWORD dwFlags)
  534. {
  535. return PSTERR_TO_HRESULT(ERROR_NOT_SUPPORTED);
  536. }
  537. HRESULT STDMETHODCALLTYPE CPStore::WriteAccessRuleset(
  538. /* [in] */ PST_KEY Key,
  539. /* [in] */ const GUID __RPC_FAR *pType,
  540. /* [in] */ const GUID __RPC_FAR *pSubtype,
  541. /* [in] */ PPST_ACCESSRULESET pRules,
  542. /* [in] */ DWORD dwFlags)
  543. {
  544. return PSTERR_TO_HRESULT(ERROR_NOT_SUPPORTED);
  545. }
  546. HRESULT STDMETHODCALLTYPE CPStore::EnumTypes(
  547. /* [in] */ PST_KEY Key,
  548. /* [in] */ DWORD dwFlags,
  549. /* [in] */ IEnumPStoreTypes __RPC_FAR *__RPC_FAR *ppenum
  550. )
  551. {
  552. HRESULT hr;
  553. __try
  554. {
  555. hr = CEnumTypes::CreateObject(m_pBinding->AddRef(), Key, NULL, dwFlags, ppenum);
  556. }
  557. __except(EXCEPTION_EXECUTE_HANDLER)
  558. {
  559. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  560. }
  561. return PSTERR_TO_HRESULT(hr);
  562. }
  563. HRESULT STDMETHODCALLTYPE CPStore::EnumSubtypes(
  564. /* [in] */ PST_KEY Key,
  565. /* [in] */ const GUID __RPC_FAR *pType,
  566. /* [in] */ DWORD dwFlags,
  567. /* [in] */ IEnumPStoreTypes __RPC_FAR *__RPC_FAR *ppenum
  568. )
  569. {
  570. if (pType == NULL)
  571. return E_INVALIDARG;
  572. HRESULT hr;
  573. __try
  574. {
  575. hr = CEnumTypes::CreateObject(m_pBinding->AddRef(), Key, pType, dwFlags, ppenum);
  576. }
  577. __except(EXCEPTION_EXECUTE_HANDLER)
  578. {
  579. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  580. }
  581. return PSTERR_TO_HRESULT(hr);
  582. }
  583. HRESULT STDMETHODCALLTYPE CPStore::DeleteItem(
  584. /* [in] */ PST_KEY Key,
  585. /* [in] */ const GUID __RPC_FAR *pItemType,
  586. /* [in] */ const GUID __RPC_FAR *pItemSubtype,
  587. /* [in] */ LPCWSTR szItemName,
  588. /* [in] */ PPST_PROMPTINFO pPromptInfo,
  589. /* [in] */ DWORD dwFlags)
  590. {
  591. if ((pItemType == NULL) || (pItemSubtype == NULL) || (szItemName == NULL))
  592. return E_INVALIDARG;
  593. // if it exists, is it valid?
  594. if ((pPromptInfo) && (pPromptInfo->cbSize != sizeof(PST_PROMPTINFO)))
  595. return E_INVALIDARG;
  596. PST_CALL_CONTEXT CallContext;
  597. HRESULT hr;
  598. __try
  599. {
  600. PST_PROMPTINFO sNullPrompt = {sizeof(PST_PROMPTINFO), 0, NULL, L""};
  601. // deal with NULL pPromptInfo
  602. if (pPromptInfo == NULL)
  603. pPromptInfo = &sNullPrompt;
  604. InitCallContext(&CallContext);
  605. hr = SSDeleteItem(m_pBinding->m_hBind,
  606. m_pBinding->m_hProv,
  607. CallContext,
  608. Key,
  609. pItemType,
  610. pItemSubtype,
  611. szItemName,
  612. pPromptInfo,
  613. dwFlags);
  614. }
  615. __except(EXCEPTION_EXECUTE_HANDLER)
  616. {
  617. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  618. }
  619. DeleteCallContext(&CallContext);
  620. return PSTERR_TO_HRESULT(hr);
  621. }
  622. HRESULT STDMETHODCALLTYPE CPStore::ReadItem(
  623. /* [in] */ PST_KEY Key,
  624. /* [in] */ const GUID __RPC_FAR *pItemType,
  625. /* [in] */ const GUID __RPC_FAR *pItemSubtype,
  626. /* [in] */ LPCWSTR szItemName,
  627. /* [out][in] */ DWORD __RPC_FAR *pcbData,
  628. /* [out][size_is] */ BYTE __RPC_FAR *__RPC_FAR *ppbData,
  629. /* [in] */ PPST_PROMPTINFO pPromptInfo,
  630. /* [in] */ DWORD dwFlags)
  631. {
  632. if ((pItemType == NULL) || (pItemSubtype == NULL) || (szItemName == NULL))
  633. return E_INVALIDARG;
  634. // if exists, is it valid?
  635. if ((pPromptInfo) && (pPromptInfo->cbSize != sizeof(PST_PROMPTINFO)))
  636. return E_INVALIDARG;
  637. HRESULT hr;
  638. PST_CALL_CONTEXT CallContext;
  639. __try
  640. {
  641. PST_PROMPTINFO sNullPrompt = {sizeof(PST_PROMPTINFO), 0, NULL, L""};
  642. // deal with NULL pPromptInfo
  643. if (pPromptInfo == NULL)
  644. pPromptInfo = &sNullPrompt;
  645. InitCallContext(&CallContext);
  646. *pcbData = 0;
  647. *ppbData = NULL;
  648. // get the information
  649. if (RPC_S_OK != (hr =
  650. SSReadItem(m_pBinding->m_hBind,
  651. m_pBinding->m_hProv,
  652. CallContext,
  653. Key,
  654. pItemType,
  655. pItemSubtype,
  656. szItemName,
  657. pcbData,
  658. ppbData,
  659. pPromptInfo,
  660. dwFlags)))
  661. goto Ret;
  662. hr = S_OK;
  663. }
  664. __except(EXCEPTION_EXECUTE_HANDLER)
  665. {
  666. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  667. }
  668. Ret:
  669. DeleteCallContext(&CallContext);
  670. return PSTERR_TO_HRESULT(hr);
  671. }
  672. HRESULT STDMETHODCALLTYPE CPStore::WriteItem(
  673. /* [in] */ PST_KEY Key,
  674. /* [in] */ const GUID __RPC_FAR *pItemType,
  675. /* [in] */ const GUID __RPC_FAR *pItemSubtype,
  676. /* [in] */ LPCWSTR szItemName,
  677. /* [in] */ DWORD cbData,
  678. /* [in][size_is] */ BYTE __RPC_FAR *pbData,
  679. /* [in] */ PPST_PROMPTINFO pPromptInfo,
  680. /* [in] */ DWORD dwDefaultConfirmationStyle,
  681. /* [in] */ DWORD dwFlags)
  682. {
  683. if ((pItemType == NULL) || (pItemSubtype == NULL))
  684. return E_INVALIDARG;
  685. if (szItemName == NULL)
  686. return E_INVALIDARG;
  687. if ((pPromptInfo) && (pPromptInfo->cbSize != sizeof(PST_PROMPTINFO)))
  688. return E_INVALIDARG;
  689. PST_CALL_CONTEXT CallContext;
  690. HRESULT hr;
  691. __try
  692. {
  693. PST_PROMPTINFO sNullPrompt = {sizeof(PST_PROMPTINFO), 0, NULL, L""};
  694. // deal with NULL pPromptInfo
  695. if (pPromptInfo == NULL)
  696. pPromptInfo = &sNullPrompt;
  697. InitCallContext(&CallContext);
  698. hr = SSWriteItem(m_pBinding->m_hBind,
  699. m_pBinding->m_hProv,
  700. CallContext,
  701. Key,
  702. pItemType,
  703. pItemSubtype,
  704. szItemName,
  705. cbData,
  706. pbData,
  707. pPromptInfo,
  708. dwDefaultConfirmationStyle,
  709. dwFlags);
  710. }
  711. __except(EXCEPTION_EXECUTE_HANDLER)
  712. {
  713. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  714. }
  715. DeleteCallContext(&CallContext);
  716. return PSTERR_TO_HRESULT(hr);
  717. }
  718. HRESULT STDMETHODCALLTYPE CPStore::OpenItem(
  719. /* [in] */ PST_KEY Key,
  720. /* [in] */ const GUID __RPC_FAR *pItemType,
  721. /* [in] */ const GUID __RPC_FAR *pItemSubtype,
  722. /* [in] */ LPCWSTR szItemName,
  723. /* [in] */ PST_ACCESSMODE ModeFlags,
  724. /* [in] */ PPST_PROMPTINFO pPromptInfo,
  725. /* [in] */ DWORD dwFlags)
  726. {
  727. if ((pItemType == NULL) || (pItemSubtype == NULL) || (szItemName == NULL))
  728. return E_INVALIDARG;
  729. // if exists, is it valid?
  730. if ((pPromptInfo) && (pPromptInfo->cbSize != sizeof(PST_PROMPTINFO)))
  731. return E_INVALIDARG;
  732. PST_CALL_CONTEXT CallContext;
  733. HRESULT hr;
  734. __try
  735. {
  736. PST_PROMPTINFO sNullPrompt = {sizeof(PST_PROMPTINFO), 0, NULL, L""};
  737. // deal with NULL pPromptInfo
  738. if (pPromptInfo == NULL)
  739. pPromptInfo = &sNullPrompt;
  740. InitCallContext(&CallContext);
  741. // get the information
  742. if (RPC_S_OK != (hr =
  743. SSOpenItem(m_pBinding->m_hBind,
  744. m_pBinding->m_hProv,
  745. CallContext,
  746. Key,
  747. pItemType,
  748. pItemSubtype,
  749. szItemName,
  750. ModeFlags,
  751. pPromptInfo,
  752. dwFlags)))
  753. goto Ret;
  754. hr = S_OK;
  755. }
  756. __except(EXCEPTION_EXECUTE_HANDLER)
  757. {
  758. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  759. }
  760. Ret:
  761. DeleteCallContext(&CallContext);
  762. return PSTERR_TO_HRESULT(hr);
  763. }
  764. HRESULT STDMETHODCALLTYPE CPStore::CloseItem(
  765. /* [in] */ PST_KEY Key,
  766. /* [in] */ const GUID __RPC_FAR *pItemType,
  767. /* [in] */ const GUID __RPC_FAR *pItemSubtype,
  768. /* [in] */ LPCWSTR szItemName,
  769. /* [in] */ DWORD dwFlags)
  770. {
  771. if ((pItemType == NULL) || (pItemSubtype == NULL) || (szItemName == NULL))
  772. return E_INVALIDARG;
  773. HRESULT hr;
  774. PST_CALL_CONTEXT CallContext;
  775. __try
  776. {
  777. InitCallContext(&CallContext);
  778. // get the information
  779. if (RPC_S_OK != (hr =
  780. SSCloseItem(m_pBinding->m_hBind,
  781. m_pBinding->m_hProv,
  782. CallContext,
  783. Key,
  784. pItemType,
  785. pItemSubtype,
  786. szItemName,
  787. dwFlags)))
  788. goto Ret;
  789. hr = S_OK;
  790. }
  791. __except(EXCEPTION_EXECUTE_HANDLER)
  792. {
  793. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  794. }
  795. Ret:
  796. DeleteCallContext(&CallContext);
  797. return PSTERR_TO_HRESULT(hr);
  798. }
  799. HRESULT STDMETHODCALLTYPE CPStore::EnumItems(
  800. /* [in] */ PST_KEY Key,
  801. /* [in] */ const GUID __RPC_FAR *pItemType,
  802. /* [in] */ const GUID __RPC_FAR *pItemSubtype,
  803. /* [in] */ DWORD dwFlags,
  804. /* [in] */ IEnumPStoreItems __RPC_FAR *__RPC_FAR *ppenum
  805. )
  806. {
  807. if ((pItemType == NULL) || (pItemSubtype == NULL))
  808. return E_INVALIDARG;
  809. HRESULT hr;
  810. __try
  811. {
  812. hr = CEnumItems::CreateObject(m_pBinding->AddRef(),
  813. Key,
  814. pItemType,
  815. pItemSubtype,
  816. dwFlags,
  817. ppenum);
  818. }
  819. __except(EXCEPTION_EXECUTE_HANDLER)
  820. {
  821. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  822. }
  823. return PSTERR_TO_HRESULT(hr);
  824. }
  825. HRESULT STDMETHODCALLTYPE CPStore::Next(
  826. /* [in] */ DWORD celt,
  827. /* [out][size_is] */ PST_PROVIDERINFO __RPC_FAR *__RPC_FAR *rgelt,
  828. /* [out][in] */ DWORD __RPC_FAR *pceltFetched)
  829. {
  830. if ((pceltFetched == NULL) && (celt != 1))
  831. return E_INVALIDARG;
  832. DWORD i = 0;
  833. HRESULT hr = S_OK;
  834. PST_CALL_CONTEXT CallContext;
  835. __try
  836. {
  837. InitCallContext(&CallContext);
  838. for (i=0;i<celt;i++)
  839. {
  840. // clean the destination
  841. rgelt[i] = NULL;
  842. if (RPC_S_OK != (hr =
  843. SSPStoreEnumProviders(
  844. m_pBinding->m_hBind,
  845. CallContext,
  846. &(rgelt[i]),
  847. m_Index,
  848. 0)))
  849. goto Ret;
  850. m_Index++;
  851. }
  852. }
  853. __except(EXCEPTION_EXECUTE_HANDLER)
  854. {
  855. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  856. }
  857. Ret:
  858. __try
  859. {
  860. // if non-null, fill in
  861. if (pceltFetched)
  862. *pceltFetched = i;
  863. }
  864. __except(EXCEPTION_EXECUTE_HANDLER)
  865. {
  866. // don't stomp err code
  867. if (hr == PST_E_OK)
  868. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  869. }
  870. DeleteCallContext(&CallContext);
  871. return PSTERR_TO_HRESULT(hr);
  872. }
  873. HRESULT STDMETHODCALLTYPE CPStore::Skip(
  874. /* [in] */ DWORD celt)
  875. {
  876. HRESULT hr = S_OK;
  877. __try
  878. {
  879. PST_PROVIDERINFO* pProvInfo;
  880. // loop (breaks if end reached)
  881. for (DWORD dw=0; dw<celt; dw++)
  882. {
  883. if(S_OK != (hr = this->Next(1, &pProvInfo, NULL)))
  884. break;
  885. // free the Info struct
  886. midl_user_free(pProvInfo);
  887. }
  888. }
  889. __except(EXCEPTION_EXECUTE_HANDLER)
  890. {
  891. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  892. }
  893. return PSTERR_TO_HRESULT(hr);
  894. }
  895. HRESULT STDMETHODCALLTYPE CPStore::Reset( void)
  896. {
  897. HRESULT hr;
  898. __try
  899. {
  900. m_Index = 0;
  901. hr = S_OK;
  902. }
  903. __except(EXCEPTION_EXECUTE_HANDLER)
  904. {
  905. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  906. }
  907. return PSTERR_TO_HRESULT(hr);
  908. }
  909. HRESULT STDMETHODCALLTYPE CPStore::Clone(
  910. /* [out] */ IEnumPStoreProviders __RPC_FAR *__RPC_FAR *ppenum)
  911. {
  912. if (ppenum == NULL)
  913. return E_INVALIDARG;
  914. HRESULT hr;
  915. __try
  916. {
  917. // get an ISecStor interface
  918. hr = CreateObject(m_pBinding->AddRef(), ppenum);
  919. }
  920. __except(EXCEPTION_EXECUTE_HANDLER)
  921. {
  922. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  923. }
  924. return PSTERR_TO_HRESULT(hr);
  925. }
  926. // IEnumPStoreItems
  927. CEnumItems::CEnumItems()
  928. {
  929. }
  930. CEnumItems::~CEnumItems()
  931. {
  932. m_pBinding->Release();
  933. }
  934. void CEnumItems::Init(
  935. CRPCBinding *pBinding,
  936. PST_KEY Key,
  937. const GUID *pType,
  938. const GUID *pSubtype,
  939. DWORD dwFlags
  940. )
  941. {
  942. m_pBinding = pBinding;
  943. m_Key = Key;
  944. CopyMemory(&m_Type, pType, sizeof(GUID));
  945. CopyMemory(&m_Subtype, pSubtype, sizeof(GUID));
  946. m_dwFlags = dwFlags;
  947. m_Index = 0;
  948. }
  949. HRESULT CEnumItems::CreateObject(
  950. CRPCBinding *pBinding,
  951. PST_KEY Key,
  952. const GUID *pType,
  953. const GUID *pSubtype,
  954. DWORD dwFlags,
  955. IEnumPStoreItems **ppv
  956. )
  957. {
  958. if ((pType == NULL) || (pSubtype == NULL))
  959. return E_INVALIDARG;
  960. HRESULT hr;
  961. __try
  962. {
  963. typedef CComObject<CEnumItems> CObject;
  964. CObject* pnew = new CObject;
  965. if(NULL == pnew)
  966. {
  967. hr = E_OUTOFMEMORY;
  968. }
  969. else
  970. {
  971. pnew->Init(pBinding, Key, pType, pSubtype, dwFlags);
  972. hr = pnew->QueryInterface(IID_IEnumPStoreItems, (void**)ppv);
  973. }
  974. }
  975. __except(EXCEPTION_EXECUTE_HANDLER)
  976. {
  977. // don't stomp err code
  978. if (hr == PST_E_OK)
  979. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  980. }
  981. return PSTERR_TO_HRESULT(hr);
  982. }
  983. HRESULT STDMETHODCALLTYPE CEnumItems::Next(
  984. /* [in] */ DWORD celt,
  985. /* [out][size_is] */ LPWSTR __RPC_FAR *rgelt,
  986. /* [out][in] */ DWORD __RPC_FAR *pceltFetched)
  987. {
  988. if ((pceltFetched == NULL) && (celt != 1))
  989. return E_INVALIDARG;
  990. DWORD i = 0;
  991. HRESULT hr = S_OK;
  992. PST_CALL_CONTEXT CallContext;
  993. __try
  994. {
  995. InitCallContext(&CallContext);
  996. for (i=0;i<celt;i++)
  997. {
  998. rgelt[i] = NULL;
  999. //
  1000. // TODO: during an enumeration of multiple items, we may fault/fail.
  1001. // in this scenario, it may be useful to free any allocated entries
  1002. // in the enumeration array. This would entail invalidating all the
  1003. // array entries prior to enumeration, and then looping+freeing on
  1004. // error.
  1005. //
  1006. if (RPC_S_OK != (hr =
  1007. SSEnumItems(
  1008. m_pBinding->m_hBind,
  1009. m_pBinding->m_hProv,
  1010. CallContext,
  1011. m_Key,
  1012. &m_Type,
  1013. &m_Subtype,
  1014. &(rgelt[i]),
  1015. m_Index,
  1016. m_dwFlags)))
  1017. goto Ret;
  1018. m_Index++;
  1019. }
  1020. }
  1021. __except(EXCEPTION_EXECUTE_HANDLER)
  1022. {
  1023. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1024. }
  1025. Ret:
  1026. __try
  1027. {
  1028. // fill in if non-null
  1029. if (pceltFetched)
  1030. *pceltFetched = i;
  1031. }
  1032. __except(EXCEPTION_EXECUTE_HANDLER)
  1033. {
  1034. // don't stomp err code
  1035. if (hr == PST_E_OK)
  1036. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1037. }
  1038. DeleteCallContext(&CallContext);
  1039. return PSTERR_TO_HRESULT(hr);
  1040. }
  1041. HRESULT STDMETHODCALLTYPE CEnumItems::Skip(
  1042. /* [in] */ DWORD celt)
  1043. {
  1044. LPWSTR szName = NULL;
  1045. DWORD i;
  1046. HRESULT hr = S_OK;
  1047. PST_CALL_CONTEXT CallContext;
  1048. __try
  1049. {
  1050. InitCallContext(&CallContext);
  1051. for (i=0;i<celt;i++)
  1052. {
  1053. if (RPC_S_OK != (hr =
  1054. SSEnumItems(
  1055. m_pBinding->m_hBind,
  1056. m_pBinding->m_hProv,
  1057. CallContext,
  1058. m_Key,
  1059. &m_Type,
  1060. &m_Subtype,
  1061. &szName,
  1062. m_Index,
  1063. m_dwFlags)))
  1064. goto Ret;
  1065. midl_user_free(szName);
  1066. szName = NULL;
  1067. m_Index++;
  1068. }
  1069. }
  1070. __except(EXCEPTION_EXECUTE_HANDLER)
  1071. {
  1072. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1073. }
  1074. Ret:
  1075. __try
  1076. {
  1077. if (szName)
  1078. midl_user_free(szName);
  1079. }
  1080. __except(EXCEPTION_EXECUTE_HANDLER)
  1081. {
  1082. // don't stomp err code
  1083. if (hr == PST_E_OK)
  1084. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1085. }
  1086. DeleteCallContext(&CallContext);
  1087. return PSTERR_TO_HRESULT(hr);
  1088. }
  1089. HRESULT STDMETHODCALLTYPE CEnumItems::Reset( void)
  1090. {
  1091. HRESULT hr;
  1092. __try
  1093. {
  1094. m_Index = 0;
  1095. hr = S_OK;
  1096. }
  1097. __except(EXCEPTION_EXECUTE_HANDLER)
  1098. {
  1099. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1100. }
  1101. return PSTERR_TO_HRESULT(hr);
  1102. }
  1103. HRESULT STDMETHODCALLTYPE CEnumItems::Clone(
  1104. /* [out] */ IEnumPStoreItems __RPC_FAR *__RPC_FAR *ppenum)
  1105. {
  1106. if (ppenum == NULL)
  1107. return E_INVALIDARG;
  1108. HRESULT hr;
  1109. __try
  1110. {
  1111. hr = CEnumItems::CreateObject(m_pBinding->AddRef(),
  1112. m_Key,
  1113. &m_Type,
  1114. &m_Subtype,
  1115. m_dwFlags,
  1116. ppenum);
  1117. }
  1118. __except(EXCEPTION_EXECUTE_HANDLER)
  1119. {
  1120. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1121. }
  1122. return PSTERR_TO_HRESULT(hr);
  1123. }
  1124. // IEnumPStoreTypes
  1125. CEnumTypes::CEnumTypes()
  1126. {
  1127. }
  1128. CEnumTypes::~CEnumTypes()
  1129. {
  1130. m_pBinding->Release();
  1131. }
  1132. void CEnumTypes::Init(
  1133. CRPCBinding *pBinding,
  1134. PST_KEY Key,
  1135. const GUID *pType,
  1136. DWORD dwFlags
  1137. )
  1138. {
  1139. m_pBinding = pBinding;
  1140. m_Key = Key;
  1141. if (NULL != pType)
  1142. {
  1143. CopyMemory(&m_Type, pType, sizeof(GUID));
  1144. m_fEnumSubtypes = TRUE;
  1145. }
  1146. else
  1147. m_fEnumSubtypes = FALSE;
  1148. m_Index = 0;
  1149. m_dwFlags = dwFlags;
  1150. }
  1151. HRESULT CEnumTypes::CreateObject(
  1152. CRPCBinding *pBinding,
  1153. PST_KEY Key,
  1154. const GUID *pType,
  1155. DWORD dwFlags,
  1156. IEnumPStoreTypes **ppv
  1157. )
  1158. {
  1159. HRESULT hr;
  1160. __try
  1161. {
  1162. typedef CComObject<CEnumTypes> CObject;
  1163. CObject* pnew = new CObject;
  1164. if(NULL == pnew)
  1165. {
  1166. hr = E_OUTOFMEMORY;
  1167. }
  1168. else
  1169. {
  1170. pnew->Init(pBinding, Key, pType, dwFlags);
  1171. hr = pnew->QueryInterface(IID_IEnumPStoreTypes, (void**)ppv);
  1172. }
  1173. }
  1174. __except(EXCEPTION_EXECUTE_HANDLER)
  1175. {
  1176. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1177. }
  1178. return PSTERR_TO_HRESULT(hr);
  1179. }
  1180. HRESULT STDMETHODCALLTYPE EnumTypesNext(
  1181. /* [in] */ CEnumTypes *pEnumType,
  1182. /* [in] */ DWORD celt,
  1183. /* [out][size_is] */ GUID __RPC_FAR *rgelt,
  1184. /* [out][in] */ DWORD __RPC_FAR *pceltFetched)
  1185. {
  1186. if ((pceltFetched == NULL) && (celt != 1))
  1187. return E_INVALIDARG;
  1188. DWORD i;
  1189. PST_CALL_CONTEXT CallContext;
  1190. HRESULT hr = S_OK;
  1191. __try
  1192. {
  1193. InitCallContext(&CallContext);
  1194. for (i=0;i<celt;i++)
  1195. {
  1196. if (RPC_S_OK != (hr =
  1197. SSEnumTypes(
  1198. pEnumType->m_pBinding->m_hBind,
  1199. pEnumType->m_pBinding->m_hProv,
  1200. CallContext,
  1201. pEnumType->m_Key,
  1202. &(rgelt[i]),
  1203. pEnumType->m_Index,
  1204. pEnumType->m_dwFlags)))
  1205. goto Ret;
  1206. pEnumType->m_Index++;
  1207. }
  1208. }
  1209. __except(EXCEPTION_EXECUTE_HANDLER)
  1210. {
  1211. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1212. }
  1213. Ret:
  1214. __try
  1215. {
  1216. if (pceltFetched != NULL)
  1217. *pceltFetched = i;
  1218. }
  1219. __except(EXCEPTION_EXECUTE_HANDLER)
  1220. {
  1221. // don't stomp err code
  1222. if (hr == PST_E_OK)
  1223. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1224. }
  1225. DeleteCallContext(&CallContext);
  1226. return PSTERR_TO_HRESULT(hr);
  1227. }
  1228. HRESULT STDMETHODCALLTYPE EnumSubtypesNext(
  1229. /* [in] */ CEnumTypes *pEnumType,
  1230. /* [in] */ DWORD celt,
  1231. /* [out][size_is] */ GUID __RPC_FAR *rgelt,
  1232. /* [out][in] */ DWORD __RPC_FAR *pceltFetched)
  1233. {
  1234. if ((pceltFetched == NULL) && (celt != 1))
  1235. return E_INVALIDARG;
  1236. DWORD i = 0;
  1237. PST_CALL_CONTEXT CallContext;
  1238. HRESULT hr = S_OK;
  1239. __try
  1240. {
  1241. InitCallContext(&CallContext);
  1242. for (i=0;i<celt;i++)
  1243. {
  1244. if (RPC_S_OK != (hr =
  1245. SSEnumSubtypes(
  1246. pEnumType->m_pBinding->m_hBind,
  1247. pEnumType->m_pBinding->m_hProv,
  1248. CallContext,
  1249. pEnumType->m_Key,
  1250. &pEnumType->m_Type,
  1251. &(rgelt[i]),
  1252. pEnumType->m_Index,
  1253. pEnumType->m_dwFlags)))
  1254. goto Ret;
  1255. pEnumType->m_Index++;
  1256. }
  1257. }
  1258. __except(EXCEPTION_EXECUTE_HANDLER)
  1259. {
  1260. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1261. }
  1262. Ret:
  1263. __try
  1264. {
  1265. if (pceltFetched != NULL)
  1266. *pceltFetched = i;
  1267. }
  1268. __except(EXCEPTION_EXECUTE_HANDLER)
  1269. {
  1270. // don't stomp hr
  1271. if (hr == PST_E_OK)
  1272. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1273. }
  1274. DeleteCallContext(&CallContext);
  1275. return PSTERR_TO_HRESULT(hr);
  1276. }
  1277. HRESULT STDMETHODCALLTYPE CEnumTypes::Next(
  1278. /* [in] */ DWORD celt,
  1279. /* [out][in][size_is] */ GUID __RPC_FAR *rgelt,
  1280. /* [out][in] */ DWORD __RPC_FAR *pceltFetched)
  1281. {
  1282. HRESULT hr;
  1283. __try
  1284. {
  1285. if (m_fEnumSubtypes)
  1286. hr = EnumSubtypesNext(this, celt, rgelt, pceltFetched);
  1287. else
  1288. hr = EnumTypesNext(this, celt, rgelt, pceltFetched);
  1289. }
  1290. __except(EXCEPTION_EXECUTE_HANDLER)
  1291. {
  1292. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1293. }
  1294. return PSTERR_TO_HRESULT(hr);
  1295. }
  1296. HRESULT STDMETHODCALLTYPE CEnumTypes::Skip(
  1297. /* [in] */ DWORD celt
  1298. )
  1299. {
  1300. GUID Guid;
  1301. DWORD i;
  1302. PST_CALL_CONTEXT CallContext;
  1303. HRESULT hr = S_OK;
  1304. __try
  1305. {
  1306. InitCallContext(&CallContext);
  1307. for (i=0;i<celt;i++)
  1308. {
  1309. if (m_fEnumSubtypes)
  1310. {
  1311. if (RPC_S_OK != (hr = SSEnumTypes(
  1312. m_pBinding->m_hBind,
  1313. m_pBinding->m_hProv,
  1314. CallContext,
  1315. m_Key,
  1316. &Guid,
  1317. m_Index,
  1318. m_dwFlags)))
  1319. {
  1320. goto Ret;
  1321. }
  1322. }
  1323. else
  1324. {
  1325. if (RPC_S_OK != (hr = SSEnumSubtypes(
  1326. m_pBinding->m_hBind,
  1327. m_pBinding->m_hProv,
  1328. CallContext,
  1329. m_Key,
  1330. &m_Type,
  1331. &Guid,
  1332. m_Index++,
  1333. m_dwFlags)))
  1334. {
  1335. goto Ret;
  1336. }
  1337. }
  1338. m_Index++;
  1339. }
  1340. }
  1341. __except(EXCEPTION_EXECUTE_HANDLER)
  1342. {
  1343. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1344. }
  1345. Ret:
  1346. DeleteCallContext(&CallContext);
  1347. return PSTERR_TO_HRESULT(hr);
  1348. }
  1349. HRESULT STDMETHODCALLTYPE CEnumTypes::Reset( void)
  1350. {
  1351. HRESULT hr;
  1352. __try
  1353. {
  1354. m_Index = 0;
  1355. hr = S_OK;
  1356. }
  1357. __except(EXCEPTION_EXECUTE_HANDLER)
  1358. {
  1359. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1360. }
  1361. return PSTERR_TO_HRESULT(hr);
  1362. }
  1363. HRESULT STDMETHODCALLTYPE CEnumTypes::Clone(
  1364. /* [out] */ IEnumPStoreTypes __RPC_FAR *__RPC_FAR *ppenum)
  1365. {
  1366. if (ppenum == NULL)
  1367. return E_INVALIDARG;
  1368. GUID *pType = NULL;
  1369. HRESULT hr;
  1370. __try
  1371. {
  1372. if (m_fEnumSubtypes)
  1373. pType = &m_Type;
  1374. hr = CEnumTypes::CreateObject(m_pBinding->AddRef(), m_Key, pType, m_dwFlags, ppenum);
  1375. }
  1376. __except(EXCEPTION_EXECUTE_HANDLER)
  1377. {
  1378. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1379. }
  1380. return PSTERR_TO_HRESULT(hr);
  1381. }
  1382. // functions exported from the DLL
  1383. // PStoreCreateInstance - allows caller to get provider interface
  1384. HRESULT
  1385. WINAPI
  1386. PStoreCreateInstance(
  1387. OUT IPStore **ppProvider,
  1388. IN PST_PROVIDERID* pProviderID,
  1389. IN void* pReserved,
  1390. DWORD dwFlags)
  1391. {
  1392. if (ppProvider == NULL)
  1393. return E_INVALIDARG;
  1394. // pProviderID can be NULL, defaults to base provider
  1395. HRESULT hr = PST_E_FAIL;
  1396. CRPCBinding *pBinding = NULL;
  1397. __try
  1398. {
  1399. GUID IDBaseProvider = MS_BASE_PSTPROVIDER_ID;
  1400. if (0 != dwFlags)
  1401. {
  1402. hr = PST_E_BAD_FLAGS;
  1403. goto Ret;
  1404. }
  1405. // if passed in null, asking for (hardcoded) base provider
  1406. if (pProviderID == NULL)
  1407. pProviderID = &IDBaseProvider;
  1408. pBinding = new CRPCBinding;
  1409. if(NULL == pBinding)
  1410. {
  1411. hr = E_OUTOFMEMORY;
  1412. goto Ret;
  1413. }
  1414. if (RPC_S_OK != (hr = pBinding->Init()))
  1415. goto Ret;
  1416. if (RPC_S_OK != (hr = pBinding->Acquire(pProviderID, pReserved, dwFlags)))
  1417. goto Ret;
  1418. // get an ISecStor interface
  1419. if (S_OK != (hr =
  1420. CPStore::CreateObject(pBinding, ppProvider)) )
  1421. goto Ret;
  1422. hr = PST_E_OK;
  1423. }
  1424. __except(EXCEPTION_EXECUTE_HANDLER)
  1425. {
  1426. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1427. }
  1428. Ret:
  1429. __try
  1430. {
  1431. // on err, release binding
  1432. if (hr != PST_E_OK)
  1433. {
  1434. if (pBinding)
  1435. pBinding->Release();
  1436. }
  1437. }
  1438. __except(EXCEPTION_EXECUTE_HANDLER)
  1439. {
  1440. // don't stomp code
  1441. if (hr == PST_E_OK)
  1442. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1443. }
  1444. return PSTERR_TO_HRESULT(hr);
  1445. }
  1446. // PStoreEnumProviders - returns an interface for enumerating providers
  1447. HRESULT
  1448. WINAPI
  1449. PStoreEnumProviders(
  1450. DWORD dwFlags,
  1451. IEnumPStoreProviders **ppenum)
  1452. {
  1453. HRESULT hr = PST_E_FAIL;
  1454. CRPCBinding *pBinding = NULL;
  1455. __try
  1456. {
  1457. pBinding = new CRPCBinding;
  1458. if(NULL == pBinding)
  1459. {
  1460. hr = E_OUTOFMEMORY;
  1461. goto Ret;
  1462. }
  1463. if (S_OK != (hr = pBinding->Init()) )
  1464. goto Ret;
  1465. // get an ISecStor interface
  1466. if (S_OK != (hr = CPStore::CreateObject(pBinding, ppenum)) )
  1467. goto Ret;
  1468. hr = PST_E_OK;
  1469. }
  1470. __except(EXCEPTION_EXECUTE_HANDLER)
  1471. {
  1472. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1473. }
  1474. Ret:
  1475. __try
  1476. {
  1477. // on error, release binding
  1478. if (hr != PST_E_OK)
  1479. {
  1480. if (pBinding)
  1481. pBinding->Release();
  1482. }
  1483. }
  1484. __except(EXCEPTION_EXECUTE_HANDLER)
  1485. {
  1486. // don't stomp code
  1487. if (hr == PST_E_OK)
  1488. hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
  1489. }
  1490. return PSTERR_TO_HRESULT(hr);
  1491. }