203 lines
5.1 KiB
C++
203 lines
5.1 KiB
C++
// This is a part of the Active Template Library.
|
|
// Copyright (C) Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Active Template Library Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Active Template Library product.
|
|
|
|
#ifndef __ATLSHAREDSVC_H__
|
|
#define __ATLSHAREDSVC_H__
|
|
|
|
#pragma once
|
|
|
|
#include <atltime.h>
|
|
#include <atlsoap.h>
|
|
#pragma pack(push,_ATL_PACKING)
|
|
namespace ATL{
|
|
|
|
#ifndef ATL_SHAREDBLOBCACHE_TIMEOUT
|
|
#define ATL_SHAREDBLOBCACHE_TIMEOUT 36000000000 // in 100 nano second intervals
|
|
// each entry will be free'd if
|
|
// no access in 1 hour.
|
|
#endif
|
|
|
|
// Interface used by to access the shared blob cache.
|
|
[ uuid("AB4AF9CD-8DB1-4974-A617-CF0449578FB9"), object ]
|
|
__interface ISharedBlobCache
|
|
{
|
|
[id(0)] STDMETHOD(AddItem)([in] BSTR szItemName, [in] BSTR szData);
|
|
[id(1)] STDMETHOD(GetItem)([in] BSTR szItemName, [out,retval] BSTR *szData);
|
|
};
|
|
|
|
class CSharedCache:
|
|
public CBlobCache<CWorkerThread<>, CStdStatClass >,
|
|
public IMemoryCacheClient,
|
|
public ISharedBlobCache
|
|
{
|
|
typedef CBlobCache<CWorkerThread<>, CStdStatClass > basecache;
|
|
public:
|
|
|
|
// IMemoryCacheClient method, frees data in the memory cache.
|
|
STDMETHOD( Free )(const void *pvData)
|
|
{
|
|
if (pvData)
|
|
{
|
|
::SysFreeString((BSTR)pvData);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP AddItem(BSTR szItemName, BSTR szData)
|
|
{
|
|
|
|
HRESULT hr = E_UNEXPECTED;
|
|
|
|
// We make a copy of the BSTR and stick it in the cache.
|
|
// The BSTR will be freed in our IMemoryCacheClient::Free
|
|
// implementation above.
|
|
BSTR szEntry = SysAllocString(szData);
|
|
if(szEntry)
|
|
{
|
|
USES_CONVERSION_EX;
|
|
// create a time span and for the entry
|
|
CFileTime tm = CFileTime::GetCurrentTime();
|
|
CFileTimeSpan span;
|
|
span.SetTimeSpan(ATL_SHAREDBLOBCACHE_TIMEOUT);
|
|
tm += span;
|
|
HCACHEITEM h;
|
|
hr = basecache::Add(OLE2A_EX(szItemName, _ATL_SAFE_ALLOCA_DEF_THRESHOLD), szEntry, sizeof(BSTR),
|
|
&tm, _AtlBaseModule.m_hInst, &h, static_cast<IMemoryCacheClient*>(this));
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
// On successful add, we have to release our
|
|
// reference on the entry.
|
|
basecache::ReleaseEntry(h);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP GetItem(BSTR szItemName, BSTR *szData)
|
|
{
|
|
USES_CONVERSION_EX;
|
|
HRESULT hr = E_UNEXPECTED;
|
|
HCACHEITEM hEntry = NULL;
|
|
|
|
if (!szItemName || !szData)
|
|
return hr;
|
|
|
|
hr = basecache::LookupEntry(OLE2A_EX(szItemName, _ATL_SAFE_ALLOCA_DEF_THRESHOLD), &hEntry);
|
|
if (hr == S_OK)
|
|
{
|
|
void *pData = NULL;
|
|
DWORD dwSize = 0;
|
|
hr = basecache::GetData(hEntry, &pData, &dwSize);
|
|
if (hr == S_OK)
|
|
{
|
|
// make a copy of the string
|
|
*szData = ::SysAllocString((BSTR)pData);
|
|
}
|
|
basecache::ReleaseEntry(hEntry);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
|
|
{
|
|
HRESULT hr = E_NOINTERFACE;
|
|
if (InlineIsEqualGUID(__uuidof(IMemoryCacheClient), riid)||
|
|
InlineIsEqualGUID(__uuidof(IUnknown), riid))
|
|
{
|
|
*ppv = static_cast<void*>(static_cast<IMemoryCacheClient*>(this));
|
|
hr = S_OK;
|
|
}
|
|
else if( InlineIsEqualGUID(__uuidof(ISharedBlobCache), riid))
|
|
{
|
|
*ppv = static_cast<void*>(static_cast<ISharedBlobCache*>(this));
|
|
hr = S_OK;
|
|
}
|
|
return hr;
|
|
}
|
|
ULONG STDMETHODCALLTYPE AddRef()
|
|
{
|
|
return 1;
|
|
}
|
|
ULONG STDMETHODCALLTYPE Release()
|
|
{
|
|
return 1;
|
|
}
|
|
};
|
|
|
|
|
|
// This class implements the SOAP interface for the shared blob cache.
|
|
[
|
|
soap_handler(
|
|
name="SharedBlobCache",
|
|
namespace="http://www.microsoft.com/vc/atlserver/soap/SharedBlobCache",
|
|
protocol="soap"
|
|
),
|
|
request_handler(
|
|
name="SharedBlobCache",
|
|
sdl="GenSharedBlobCacheWSDL"
|
|
)
|
|
]
|
|
class CSharedCacheHandler:
|
|
public ISharedBlobCache
|
|
{
|
|
public:
|
|
[soap_method]
|
|
STDMETHOD(AddItem)(BSTR szItemName, BSTR szData)
|
|
{
|
|
if (!m_spMemCache)
|
|
return E_UNEXPECTED;
|
|
return m_spMemCache->AddItem(szItemName, szData);
|
|
}
|
|
|
|
[soap_method]
|
|
STDMETHOD(GetItem)(BSTR szItemName, BSTR *szData)
|
|
{
|
|
if (!m_spMemCache)
|
|
return E_UNEXPECTED;
|
|
return m_spMemCache->GetItem(szItemName, szData);
|
|
}
|
|
|
|
HTTP_CODE Initialize(IServiceProvider *pProvider)
|
|
{
|
|
ATLASSERT(pProvider); // should never be NULL
|
|
if (!pProvider)
|
|
return HTTP_ERROR(500, ISE_SUBERR_UNEXPECTED);
|
|
|
|
if (m_spMemCache)
|
|
return HTTP_SUCCESS; // already initialized
|
|
|
|
pProvider->QueryService(__uuidof(ISharedBlobCache), &m_spMemCache);
|
|
return m_spMemCache ? HTTP_SUCCESS : HTTP_ERROR(500, ISE_SUBERR_UNEXPECTED);
|
|
}
|
|
|
|
// override HandleRequest to Initialize our m_spServiceProvider
|
|
// and to handle authorizing the client.
|
|
HTTP_CODE HandleRequest(AtlServerRequest *pRequestInfo, IServiceProvider *pProvider)
|
|
{
|
|
HTTP_CODE dwErr = Initialize(pProvider);
|
|
if (dwErr != HTTP_SUCCESS)
|
|
return dwErr;
|
|
|
|
dwErr = CSoapHandler<CSharedCacheHandler>::HandleRequest(pRequestInfo,
|
|
pProvider);
|
|
return dwErr;
|
|
}
|
|
CComPtr<ISharedBlobCache> m_spMemCache;
|
|
};
|
|
|
|
} //ATL
|
|
|
|
#pragma pack(pop)
|
|
|
|
#endif // __ATLSHAREDSVC_H__
|