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

// CSecStr1.cpp : Implementation of CISecStorApp and DLL registration.
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include "dpapiprv.h" // RPC protseq stuff
#include "stdafx.h"
#include "pstorec.h"
#include "cSecStr1.h"
#include "pstrpc.h"
#include <wincrypt.h>
#include "pstdef.h"
#include "crtem.h"
#include "defer.h"
#include "pmacros.h"
#include "debug.h"
#include "unicode.h"
#include "waitsvc.h"
/*********************************************************************/
/* MIDL allocate and free */
/*********************************************************************/
void __RPC_FAR * __RPC_API midl_user_allocate(size_t len)
{
return CoTaskMemAlloc(len);
}
void __RPC_API midl_user_free(void __RPC_FAR * ptr)
{
CoTaskMemFree(ptr);
}
RPC_STATUS BindW(WCHAR **pszBinding, RPC_BINDING_HANDLE *phBind)
{
RPC_STATUS status;
//
// on WinNT5, go to the shared services.exe RPC server
//
status = RpcStringBindingComposeW(
NULL,
(unsigned short*)DPAPI_LOCAL_PROT_SEQ,
NULL,
(unsigned short*)DPAPI_LOCAL_ENDPOINT,
NULL,
(unsigned short * *)pszBinding
);
if (status)
{
return(status);
}
status = RpcBindingFromStringBindingW(*pszBinding, phBind);
return status;
}
RPC_STATUS UnbindW(WCHAR **pszBinding, RPC_BINDING_HANDLE *phBind)
{
RPC_STATUS status;
status = RpcStringFreeW(pszBinding);
if (status)
{
return(status);
}
RpcBindingFree(phBind);
return RPC_S_OK;
}
//
// define an ugly macro that allows us to provide enough context to work-around
// a bug in imagehlp on win95.
//
#define InitCallContext( pCallContext ) \
RealInitCallContext( pCallContext );
BOOL RealInitCallContext(PST_CALL_CONTEXT *pCallContext)
{
HANDLE hCurrentThread;
pCallContext->Handle = (DWORD_PTR)INVALID_HANDLE_VALUE;
pCallContext->Address = GetCurrentProcessId();
//
// duplicate pseudo-current thread handle to real handle to pass to server
//
if(!DuplicateHandle(
GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(),
&hCurrentThread,
0,
FALSE,
DUPLICATE_SAME_ACCESS
))
return FALSE;
pCallContext->Handle = (DWORD_PTR)hCurrentThread;
return TRUE;
}
BOOL DeleteCallContext(PST_CALL_CONTEXT* pCallContext)
{
if (pCallContext != NULL)
{
if(pCallContext->Handle != (DWORD_PTR)INVALID_HANDLE_VALUE)
{
CloseHandle((HANDLE)(pCallContext->Handle));
pCallContext->Handle = (DWORD_PTR)INVALID_HANDLE_VALUE;
}
pCallContext->Address = 0;
}
return TRUE;
}
// RPC Binding class
CRPCBinding::CRPCBinding()
{
}
CRPCBinding::~CRPCBinding()
{
PST_CALL_CONTEXT CallContext;
__try
{
InitCallContext(&CallContext);
if (m_fGoodHProv) {
SSReleaseContext(m_hBind, m_hProv, CallContext, 0);
}
if(m_wszStringBinding != NULL && m_hBind != NULL)
UnbindW(&m_wszStringBinding, &m_hBind);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// if RPCBinding being destroyed, catch anything RPC might throw
// swallow!
}
DeleteCallContext(&CallContext);
}
static BOOL g_fDone = FALSE;
HRESULT CRPCBinding::Init()
{
HRESULT hr;
m_dwRef = 1;
m_fGoodHProv = FALSE;
m_wszStringBinding = NULL;
m_hBind = NULL;
WaitForCryptService(L"ProtectedStorage", &g_fDone);
if(!IsServiceAvailable())
return PST_E_SERVICE_UNAVAILABLE;
return BindW(&m_wszStringBinding, &m_hBind);
}
HRESULT CRPCBinding::Acquire(
IN PPST_PROVIDERID pProviderID,
IN LPVOID pReserved,
IN DWORD dwFlags
)
{
PST_CALL_CONTEXT CallContext;
HRESULT hr;
__try
{
InitCallContext(&CallContext);
// now we acquire context
hr = SSAcquireContext(m_hBind,
pProviderID,
CallContext,
(DWORD) GetCurrentProcessId(),
&m_hProv,
(DWORD_PTR)pReserved,
dwFlags
);
if(hr != RPC_S_OK)
goto Ret;
m_fGoodHProv = TRUE;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// catch anything RPC might throw
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
CRPCBinding *CRPCBinding::AddRef()
{
m_dwRef++;
return this;
}
void CRPCBinding::Release()
{
m_dwRef--;
if (0 == m_dwRef)
delete this;
}
/////////////////////////////////////////////////////////////////////////////
//
CPStore::CPStore()
{
}
CPStore::~CPStore()
{
m_pBinding->Release();
}
void CPStore::Init(
CRPCBinding *pBinding
)
{
m_pBinding = pBinding;
m_Index = 0;
}
HRESULT CPStore::CreateObject(
CRPCBinding *pBinding,
IPStore **ppv
)
{
HRESULT hr;
__try
{
typedef CComObject<CPStore> CObject;
CObject* pnew = new CObject;
if(NULL == pnew)
{
hr = E_OUTOFMEMORY;
}
else
{
pnew->Init(pBinding) ;
hr = pnew->QueryInterface(IID_IPStore, (void**)ppv);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT CPStore::CreateObject(
CRPCBinding *pBinding,
IEnumPStoreProviders **ppv
)
{
HRESULT hr;
__try
{
typedef CComObject<CPStore> CObject;
CObject* pnew = new CObject;
if(NULL == pnew)
{
hr = E_OUTOFMEMORY;
}
else
{
pnew->Init(pBinding);
hr = pnew->QueryInterface(IID_IEnumPStoreProviders, (void**)ppv);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::GetInfo(
/* [out] */ PPST_PROVIDERINFO __RPC_FAR *ppProperties)
{
HRESULT hr;
PST_CALL_CONTEXT CallContext;
__try
{
InitCallContext(&CallContext);
*ppProperties = NULL;
if (RPC_S_OK != (hr =
SSGetProvInfo(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
ppProperties,
0)))
goto Ret;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::GetProvParam(
/* [in] */ DWORD dwParam,
/* [out] */ DWORD __RPC_FAR *pcbData,
/* [out] */ BYTE __RPC_FAR **ppbData,
/* [in] */ DWORD dwFlags)
{
HRESULT hr;
PST_CALL_CONTEXT CallContext;
__try
{
InitCallContext(&CallContext);
*pcbData = 0;
*ppbData = NULL;
if (RPC_S_OK != (hr =
SSGetProvParam(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
dwParam,
pcbData,
ppbData,
dwFlags)))
goto Ret;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::SetProvParam(
/* [in] */ DWORD dwParam,
/* [in] */ DWORD cbData,
/* [in] */ BYTE __RPC_FAR *pbData,
/* [in] */ DWORD dwFlags)
{
HRESULT hr;
PST_CALL_CONTEXT CallContext;
__try
{
InitCallContext(&CallContext);
hr = SSSetProvParam(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
dwParam,
cbData,
pbData,
dwFlags);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::CreateType(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pType,
/* [in] */ PPST_TYPEINFO pInfo,
/* [in] */ DWORD dwFlags)
{
// validate inputs
if ((pInfo == NULL) || pInfo->cbSize != sizeof(PST_TYPEINFO))
return E_INVALIDARG;
if ( pInfo->szDisplayName == NULL )
return E_INVALIDARG;
if (pType == NULL)
return E_INVALIDARG;
HRESULT hr;
PST_CALL_CONTEXT CallContext;
__try
{
InitCallContext(&CallContext);
hr = SSCreateType(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pType,
pInfo,
dwFlags);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::GetTypeInfo(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pType,
/* [out] */ PPST_TYPEINFO __RPC_FAR* ppInfo,
/* [in] */ DWORD dwFlags)
{
HRESULT hr;
PST_CALL_CONTEXT CallContext;
if (pType == NULL)
return E_INVALIDARG;
if (ppInfo == NULL)
return E_INVALIDARG;
__try
{
InitCallContext(&CallContext);
*ppInfo = NULL;
if (RPC_S_OK != (hr =
SSGetTypeInfo(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pType,
ppInfo,
dwFlags)))
goto Ret;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::DeleteType(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pType,
/* [in] */ DWORD dwFlags)
{
if (pType == NULL)
return E_INVALIDARG;
PST_CALL_CONTEXT CallContext;
HRESULT hr;
__try
{
InitCallContext(&CallContext);
hr = SSDeleteType(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pType,
dwFlags);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::CreateSubtype(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pType,
/* [in] */ const GUID __RPC_FAR *pSubtype,
/* [in] */ PPST_TYPEINFO pInfo,
/* [in] */ PPST_ACCESSRULESET pRules,
/* [in] */ DWORD dwFlags)
{
if ((pType == NULL) || (pSubtype == NULL))
return E_INVALIDARG;
if ( (pInfo == NULL) || (pInfo->cbSize != sizeof(PST_TYPEINFO)) )
return E_INVALIDARG;
// validate inputs
if (pInfo->szDisplayName == NULL)
return E_INVALIDARG;
HRESULT hr;
PST_CALL_CONTEXT CallContext;
PST_ACCESSRULESET sNullRuleset = {sizeof(PST_ACCESSRULESET), 0, NULL};
__try
{
InitCallContext(&CallContext);
hr = SSCreateSubtype(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pType,
pSubtype,
pInfo,
&sNullRuleset, // always pass NullRuleset.
dwFlags);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::GetSubtypeInfo(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pType,
/* [in] */ const GUID __RPC_FAR *pSubtype,
/* [out] */ PPST_TYPEINFO __RPC_FAR* ppInfo,
/* [in] */ DWORD dwFlags)
{
if ((pType == NULL) || (pSubtype == NULL))
return E_INVALIDARG;
if (ppInfo == NULL)
return E_INVALIDARG;
HRESULT hr;
PST_CALL_CONTEXT CallContext;
__try
{
InitCallContext(&CallContext);
*ppInfo = NULL;
if (RPC_S_OK != (hr =
SSGetSubtypeInfo(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pType,
pSubtype,
ppInfo,
dwFlags)))
goto Ret;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::DeleteSubtype(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pType,
/* [in] */ const GUID __RPC_FAR *pSubtype,
/* [in] */ DWORD dwFlags)
{
if ((pType == NULL) || (pSubtype == NULL))
return E_INVALIDARG;
PST_CALL_CONTEXT CallContext;
HRESULT hr;
__try
{
InitCallContext(&CallContext);
hr = SSDeleteSubtype(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pType,
pSubtype,
dwFlags);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::ReadAccessRuleset(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pType,
/* [in] */ const GUID __RPC_FAR *pSubtype,
/* [out] */ PPST_ACCESSRULESET __RPC_FAR *ppRules,
/* [in] */ DWORD dwFlags)
{
return PSTERR_TO_HRESULT(ERROR_NOT_SUPPORTED);
}
HRESULT STDMETHODCALLTYPE CPStore::WriteAccessRuleset(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pType,
/* [in] */ const GUID __RPC_FAR *pSubtype,
/* [in] */ PPST_ACCESSRULESET pRules,
/* [in] */ DWORD dwFlags)
{
return PSTERR_TO_HRESULT(ERROR_NOT_SUPPORTED);
}
HRESULT STDMETHODCALLTYPE CPStore::EnumTypes(
/* [in] */ PST_KEY Key,
/* [in] */ DWORD dwFlags,
/* [in] */ IEnumPStoreTypes __RPC_FAR *__RPC_FAR *ppenum
)
{
HRESULT hr;
__try
{
hr = CEnumTypes::CreateObject(m_pBinding->AddRef(), Key, NULL, dwFlags, ppenum);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::EnumSubtypes(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pType,
/* [in] */ DWORD dwFlags,
/* [in] */ IEnumPStoreTypes __RPC_FAR *__RPC_FAR *ppenum
)
{
if (pType == NULL)
return E_INVALIDARG;
HRESULT hr;
__try
{
hr = CEnumTypes::CreateObject(m_pBinding->AddRef(), Key, pType, dwFlags, ppenum);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::DeleteItem(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pItemType,
/* [in] */ const GUID __RPC_FAR *pItemSubtype,
/* [in] */ LPCWSTR szItemName,
/* [in] */ PPST_PROMPTINFO pPromptInfo,
/* [in] */ DWORD dwFlags)
{
if ((pItemType == NULL) || (pItemSubtype == NULL) || (szItemName == NULL))
return E_INVALIDARG;
// if it exists, is it valid?
if ((pPromptInfo) && (pPromptInfo->cbSize != sizeof(PST_PROMPTINFO)))
return E_INVALIDARG;
PST_CALL_CONTEXT CallContext;
HRESULT hr;
__try
{
PST_PROMPTINFO sNullPrompt = {sizeof(PST_PROMPTINFO), 0, NULL, L""};
// deal with NULL pPromptInfo
if (pPromptInfo == NULL)
pPromptInfo = &sNullPrompt;
InitCallContext(&CallContext);
hr = SSDeleteItem(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pItemType,
pItemSubtype,
szItemName,
pPromptInfo,
dwFlags);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::ReadItem(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pItemType,
/* [in] */ const GUID __RPC_FAR *pItemSubtype,
/* [in] */ LPCWSTR szItemName,
/* [out][in] */ DWORD __RPC_FAR *pcbData,
/* [out][size_is] */ BYTE __RPC_FAR *__RPC_FAR *ppbData,
/* [in] */ PPST_PROMPTINFO pPromptInfo,
/* [in] */ DWORD dwFlags)
{
if ((pItemType == NULL) || (pItemSubtype == NULL) || (szItemName == NULL))
return E_INVALIDARG;
// if exists, is it valid?
if ((pPromptInfo) && (pPromptInfo->cbSize != sizeof(PST_PROMPTINFO)))
return E_INVALIDARG;
HRESULT hr;
PST_CALL_CONTEXT CallContext;
__try
{
PST_PROMPTINFO sNullPrompt = {sizeof(PST_PROMPTINFO), 0, NULL, L""};
// deal with NULL pPromptInfo
if (pPromptInfo == NULL)
pPromptInfo = &sNullPrompt;
InitCallContext(&CallContext);
*pcbData = 0;
*ppbData = NULL;
// get the information
if (RPC_S_OK != (hr =
SSReadItem(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pItemType,
pItemSubtype,
szItemName,
pcbData,
ppbData,
pPromptInfo,
dwFlags)))
goto Ret;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::WriteItem(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pItemType,
/* [in] */ const GUID __RPC_FAR *pItemSubtype,
/* [in] */ LPCWSTR szItemName,
/* [in] */ DWORD cbData,
/* [in][size_is] */ BYTE __RPC_FAR *pbData,
/* [in] */ PPST_PROMPTINFO pPromptInfo,
/* [in] */ DWORD dwDefaultConfirmationStyle,
/* [in] */ DWORD dwFlags)
{
if ((pItemType == NULL) || (pItemSubtype == NULL))
return E_INVALIDARG;
if (szItemName == NULL)
return E_INVALIDARG;
if ((pPromptInfo) && (pPromptInfo->cbSize != sizeof(PST_PROMPTINFO)))
return E_INVALIDARG;
PST_CALL_CONTEXT CallContext;
HRESULT hr;
__try
{
PST_PROMPTINFO sNullPrompt = {sizeof(PST_PROMPTINFO), 0, NULL, L""};
// deal with NULL pPromptInfo
if (pPromptInfo == NULL)
pPromptInfo = &sNullPrompt;
InitCallContext(&CallContext);
hr = SSWriteItem(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pItemType,
pItemSubtype,
szItemName,
cbData,
pbData,
pPromptInfo,
dwDefaultConfirmationStyle,
dwFlags);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::OpenItem(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pItemType,
/* [in] */ const GUID __RPC_FAR *pItemSubtype,
/* [in] */ LPCWSTR szItemName,
/* [in] */ PST_ACCESSMODE ModeFlags,
/* [in] */ PPST_PROMPTINFO pPromptInfo,
/* [in] */ DWORD dwFlags)
{
if ((pItemType == NULL) || (pItemSubtype == NULL) || (szItemName == NULL))
return E_INVALIDARG;
// if exists, is it valid?
if ((pPromptInfo) && (pPromptInfo->cbSize != sizeof(PST_PROMPTINFO)))
return E_INVALIDARG;
PST_CALL_CONTEXT CallContext;
HRESULT hr;
__try
{
PST_PROMPTINFO sNullPrompt = {sizeof(PST_PROMPTINFO), 0, NULL, L""};
// deal with NULL pPromptInfo
if (pPromptInfo == NULL)
pPromptInfo = &sNullPrompt;
InitCallContext(&CallContext);
// get the information
if (RPC_S_OK != (hr =
SSOpenItem(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pItemType,
pItemSubtype,
szItemName,
ModeFlags,
pPromptInfo,
dwFlags)))
goto Ret;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::CloseItem(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pItemType,
/* [in] */ const GUID __RPC_FAR *pItemSubtype,
/* [in] */ LPCWSTR szItemName,
/* [in] */ DWORD dwFlags)
{
if ((pItemType == NULL) || (pItemSubtype == NULL) || (szItemName == NULL))
return E_INVALIDARG;
HRESULT hr;
PST_CALL_CONTEXT CallContext;
__try
{
InitCallContext(&CallContext);
// get the information
if (RPC_S_OK != (hr =
SSCloseItem(m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
Key,
pItemType,
pItemSubtype,
szItemName,
dwFlags)))
goto Ret;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::EnumItems(
/* [in] */ PST_KEY Key,
/* [in] */ const GUID __RPC_FAR *pItemType,
/* [in] */ const GUID __RPC_FAR *pItemSubtype,
/* [in] */ DWORD dwFlags,
/* [in] */ IEnumPStoreItems __RPC_FAR *__RPC_FAR *ppenum
)
{
if ((pItemType == NULL) || (pItemSubtype == NULL))
return E_INVALIDARG;
HRESULT hr;
__try
{
hr = CEnumItems::CreateObject(m_pBinding->AddRef(),
Key,
pItemType,
pItemSubtype,
dwFlags,
ppenum);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::Next(
/* [in] */ DWORD celt,
/* [out][size_is] */ PST_PROVIDERINFO __RPC_FAR *__RPC_FAR *rgelt,
/* [out][in] */ DWORD __RPC_FAR *pceltFetched)
{
if ((pceltFetched == NULL) && (celt != 1))
return E_INVALIDARG;
DWORD i = 0;
HRESULT hr = S_OK;
PST_CALL_CONTEXT CallContext;
__try
{
InitCallContext(&CallContext);
for (i=0;i<celt;i++)
{
// clean the destination
rgelt[i] = NULL;
if (RPC_S_OK != (hr =
SSPStoreEnumProviders(
m_pBinding->m_hBind,
CallContext,
&(rgelt[i]),
m_Index,
0)))
goto Ret;
m_Index++;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
__try
{
// if non-null, fill in
if (pceltFetched)
*pceltFetched = i;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// don't stomp err code
if (hr == PST_E_OK)
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::Skip(
/* [in] */ DWORD celt)
{
HRESULT hr = S_OK;
__try
{
PST_PROVIDERINFO* pProvInfo;
// loop (breaks if end reached)
for (DWORD dw=0; dw<celt; dw++)
{
if(S_OK != (hr = this->Next(1, &pProvInfo, NULL)))
break;
// free the Info struct
midl_user_free(pProvInfo);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::Reset( void)
{
HRESULT hr;
__try
{
m_Index = 0;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CPStore::Clone(
/* [out] */ IEnumPStoreProviders __RPC_FAR *__RPC_FAR *ppenum)
{
if (ppenum == NULL)
return E_INVALIDARG;
HRESULT hr;
__try
{
// get an ISecStor interface
hr = CreateObject(m_pBinding->AddRef(), ppenum);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
// IEnumPStoreItems
CEnumItems::CEnumItems()
{
}
CEnumItems::~CEnumItems()
{
m_pBinding->Release();
}
void CEnumItems::Init(
CRPCBinding *pBinding,
PST_KEY Key,
const GUID *pType,
const GUID *pSubtype,
DWORD dwFlags
)
{
m_pBinding = pBinding;
m_Key = Key;
CopyMemory(&m_Type, pType, sizeof(GUID));
CopyMemory(&m_Subtype, pSubtype, sizeof(GUID));
m_dwFlags = dwFlags;
m_Index = 0;
}
HRESULT CEnumItems::CreateObject(
CRPCBinding *pBinding,
PST_KEY Key,
const GUID *pType,
const GUID *pSubtype,
DWORD dwFlags,
IEnumPStoreItems **ppv
)
{
if ((pType == NULL) || (pSubtype == NULL))
return E_INVALIDARG;
HRESULT hr;
__try
{
typedef CComObject<CEnumItems> CObject;
CObject* pnew = new CObject;
if(NULL == pnew)
{
hr = E_OUTOFMEMORY;
}
else
{
pnew->Init(pBinding, Key, pType, pSubtype, dwFlags);
hr = pnew->QueryInterface(IID_IEnumPStoreItems, (void**)ppv);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// don't stomp err code
if (hr == PST_E_OK)
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CEnumItems::Next(
/* [in] */ DWORD celt,
/* [out][size_is] */ LPWSTR __RPC_FAR *rgelt,
/* [out][in] */ DWORD __RPC_FAR *pceltFetched)
{
if ((pceltFetched == NULL) && (celt != 1))
return E_INVALIDARG;
DWORD i = 0;
HRESULT hr = S_OK;
PST_CALL_CONTEXT CallContext;
__try
{
InitCallContext(&CallContext);
for (i=0;i<celt;i++)
{
rgelt[i] = NULL;
//
// TODO: during an enumeration of multiple items, we may fault/fail.
// in this scenario, it may be useful to free any allocated entries
// in the enumeration array. This would entail invalidating all the
// array entries prior to enumeration, and then looping+freeing on
// error.
//
if (RPC_S_OK != (hr =
SSEnumItems(
m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
m_Key,
&m_Type,
&m_Subtype,
&(rgelt[i]),
m_Index,
m_dwFlags)))
goto Ret;
m_Index++;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
__try
{
// fill in if non-null
if (pceltFetched)
*pceltFetched = i;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// don't stomp err code
if (hr == PST_E_OK)
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CEnumItems::Skip(
/* [in] */ DWORD celt)
{
LPWSTR szName = NULL;
DWORD i;
HRESULT hr = S_OK;
PST_CALL_CONTEXT CallContext;
__try
{
InitCallContext(&CallContext);
for (i=0;i<celt;i++)
{
if (RPC_S_OK != (hr =
SSEnumItems(
m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
m_Key,
&m_Type,
&m_Subtype,
&szName,
m_Index,
m_dwFlags)))
goto Ret;
midl_user_free(szName);
szName = NULL;
m_Index++;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
__try
{
if (szName)
midl_user_free(szName);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// don't stomp err code
if (hr == PST_E_OK)
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CEnumItems::Reset( void)
{
HRESULT hr;
__try
{
m_Index = 0;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CEnumItems::Clone(
/* [out] */ IEnumPStoreItems __RPC_FAR *__RPC_FAR *ppenum)
{
if (ppenum == NULL)
return E_INVALIDARG;
HRESULT hr;
__try
{
hr = CEnumItems::CreateObject(m_pBinding->AddRef(),
m_Key,
&m_Type,
&m_Subtype,
m_dwFlags,
ppenum);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
// IEnumPStoreTypes
CEnumTypes::CEnumTypes()
{
}
CEnumTypes::~CEnumTypes()
{
m_pBinding->Release();
}
void CEnumTypes::Init(
CRPCBinding *pBinding,
PST_KEY Key,
const GUID *pType,
DWORD dwFlags
)
{
m_pBinding = pBinding;
m_Key = Key;
if (NULL != pType)
{
CopyMemory(&m_Type, pType, sizeof(GUID));
m_fEnumSubtypes = TRUE;
}
else
m_fEnumSubtypes = FALSE;
m_Index = 0;
m_dwFlags = dwFlags;
}
HRESULT CEnumTypes::CreateObject(
CRPCBinding *pBinding,
PST_KEY Key,
const GUID *pType,
DWORD dwFlags,
IEnumPStoreTypes **ppv
)
{
HRESULT hr;
__try
{
typedef CComObject<CEnumTypes> CObject;
CObject* pnew = new CObject;
if(NULL == pnew)
{
hr = E_OUTOFMEMORY;
}
else
{
pnew->Init(pBinding, Key, pType, dwFlags);
hr = pnew->QueryInterface(IID_IEnumPStoreTypes, (void**)ppv);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE EnumTypesNext(
/* [in] */ CEnumTypes *pEnumType,
/* [in] */ DWORD celt,
/* [out][size_is] */ GUID __RPC_FAR *rgelt,
/* [out][in] */ DWORD __RPC_FAR *pceltFetched)
{
if ((pceltFetched == NULL) && (celt != 1))
return E_INVALIDARG;
DWORD i;
PST_CALL_CONTEXT CallContext;
HRESULT hr = S_OK;
__try
{
InitCallContext(&CallContext);
for (i=0;i<celt;i++)
{
if (RPC_S_OK != (hr =
SSEnumTypes(
pEnumType->m_pBinding->m_hBind,
pEnumType->m_pBinding->m_hProv,
CallContext,
pEnumType->m_Key,
&(rgelt[i]),
pEnumType->m_Index,
pEnumType->m_dwFlags)))
goto Ret;
pEnumType->m_Index++;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
__try
{
if (pceltFetched != NULL)
*pceltFetched = i;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// don't stomp err code
if (hr == PST_E_OK)
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE EnumSubtypesNext(
/* [in] */ CEnumTypes *pEnumType,
/* [in] */ DWORD celt,
/* [out][size_is] */ GUID __RPC_FAR *rgelt,
/* [out][in] */ DWORD __RPC_FAR *pceltFetched)
{
if ((pceltFetched == NULL) && (celt != 1))
return E_INVALIDARG;
DWORD i = 0;
PST_CALL_CONTEXT CallContext;
HRESULT hr = S_OK;
__try
{
InitCallContext(&CallContext);
for (i=0;i<celt;i++)
{
if (RPC_S_OK != (hr =
SSEnumSubtypes(
pEnumType->m_pBinding->m_hBind,
pEnumType->m_pBinding->m_hProv,
CallContext,
pEnumType->m_Key,
&pEnumType->m_Type,
&(rgelt[i]),
pEnumType->m_Index,
pEnumType->m_dwFlags)))
goto Ret;
pEnumType->m_Index++;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
__try
{
if (pceltFetched != NULL)
*pceltFetched = i;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// don't stomp hr
if (hr == PST_E_OK)
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CEnumTypes::Next(
/* [in] */ DWORD celt,
/* [out][in][size_is] */ GUID __RPC_FAR *rgelt,
/* [out][in] */ DWORD __RPC_FAR *pceltFetched)
{
HRESULT hr;
__try
{
if (m_fEnumSubtypes)
hr = EnumSubtypesNext(this, celt, rgelt, pceltFetched);
else
hr = EnumTypesNext(this, celt, rgelt, pceltFetched);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CEnumTypes::Skip(
/* [in] */ DWORD celt
)
{
GUID Guid;
DWORD i;
PST_CALL_CONTEXT CallContext;
HRESULT hr = S_OK;
__try
{
InitCallContext(&CallContext);
for (i=0;i<celt;i++)
{
if (m_fEnumSubtypes)
{
if (RPC_S_OK != (hr = SSEnumTypes(
m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
m_Key,
&Guid,
m_Index,
m_dwFlags)))
{
goto Ret;
}
}
else
{
if (RPC_S_OK != (hr = SSEnumSubtypes(
m_pBinding->m_hBind,
m_pBinding->m_hProv,
CallContext,
m_Key,
&m_Type,
&Guid,
m_Index++,
m_dwFlags)))
{
goto Ret;
}
}
m_Index++;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
DeleteCallContext(&CallContext);
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CEnumTypes::Reset( void)
{
HRESULT hr;
__try
{
m_Index = 0;
hr = S_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
HRESULT STDMETHODCALLTYPE CEnumTypes::Clone(
/* [out] */ IEnumPStoreTypes __RPC_FAR *__RPC_FAR *ppenum)
{
if (ppenum == NULL)
return E_INVALIDARG;
GUID *pType = NULL;
HRESULT hr;
__try
{
if (m_fEnumSubtypes)
pType = &m_Type;
hr = CEnumTypes::CreateObject(m_pBinding->AddRef(), m_Key, pType, m_dwFlags, ppenum);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
// functions exported from the DLL
// PStoreCreateInstance - allows caller to get provider interface
HRESULT
WINAPI
PStoreCreateInstance(
OUT IPStore **ppProvider,
IN PST_PROVIDERID* pProviderID,
IN void* pReserved,
DWORD dwFlags)
{
if (ppProvider == NULL)
return E_INVALIDARG;
// pProviderID can be NULL, defaults to base provider
HRESULT hr = PST_E_FAIL;
CRPCBinding *pBinding = NULL;
__try
{
GUID IDBaseProvider = MS_BASE_PSTPROVIDER_ID;
if (0 != dwFlags)
{
hr = PST_E_BAD_FLAGS;
goto Ret;
}
// if passed in null, asking for (hardcoded) base provider
if (pProviderID == NULL)
pProviderID = &IDBaseProvider;
pBinding = new CRPCBinding;
if(NULL == pBinding)
{
hr = E_OUTOFMEMORY;
goto Ret;
}
if (RPC_S_OK != (hr = pBinding->Init()))
goto Ret;
if (RPC_S_OK != (hr = pBinding->Acquire(pProviderID, pReserved, dwFlags)))
goto Ret;
// get an ISecStor interface
if (S_OK != (hr =
CPStore::CreateObject(pBinding, ppProvider)) )
goto Ret;
hr = PST_E_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
__try
{
// on err, release binding
if (hr != PST_E_OK)
{
if (pBinding)
pBinding->Release();
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// don't stomp code
if (hr == PST_E_OK)
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}
// PStoreEnumProviders - returns an interface for enumerating providers
HRESULT
WINAPI
PStoreEnumProviders(
DWORD dwFlags,
IEnumPStoreProviders **ppenum)
{
HRESULT hr = PST_E_FAIL;
CRPCBinding *pBinding = NULL;
__try
{
pBinding = new CRPCBinding;
if(NULL == pBinding)
{
hr = E_OUTOFMEMORY;
goto Ret;
}
if (S_OK != (hr = pBinding->Init()) )
goto Ret;
// get an ISecStor interface
if (S_OK != (hr = CPStore::CreateObject(pBinding, ppenum)) )
goto Ret;
hr = PST_E_OK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
Ret:
__try
{
// on error, release binding
if (hr != PST_E_OK)
{
if (pBinding)
pBinding->Release();
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// don't stomp code
if (hr == PST_E_OK)
hr = PSTMAP_EXCEPTION_TO_ERROR(GetExceptionCode());
}
return PSTERR_TO_HRESULT(hr);
}