Files
Slnkdwf/ATL90/include/atlextmgmt.h
Jos Groot Lipman 0e37d774d2 Merge SLNKDWF64 branch
svn path=/Slnkdwf/trunk/; revision=23911
2015-01-21 12:09:31 +00:00

1280 lines
32 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 __ATLEXTMGMT_H__
#define __ATLEXTMGMT_H__
#pragma once
#pragma warning(push)
#pragma warning(disable: 4702)
#include <atlsoap.h>
#include <atlutil.h>
#include <atlsrvres.h>
#include <atlsecurity.h>
//
// You can change the local group that is used for authorizing
// site administrators by #define'ing ATL_DEFAULT_AUTH group
// to something else before including this header file. For
// example:
// #define ATL_DEFAULT_AUTHGRP CSid(_T("My Heros"))
// Verify that the logged on user is a member of
// the local group 'My Heros' before allowing them to
// administrate this site.
//
// #define ATL_DEFAULT_AUTHGRP Sids::World
// Allow everyone access
//
// #define ATL_DEFAULT_AUTHGRP Sids::Null
// Allow no one access
//
#ifndef ATL_DEFAULT_AUTHGRP
#define ATL_DEFAULT_AUTHGRP Sids::Admins()
#endif
// If you #define ATL_NO_DEFAULT_AUTHORITY then there will be no authorization
// check before allowing access to management functions. You can also #define
// ATL_NO_DEFAULT_AUTHORITY and then declare you own instance of _Authority
// before #include-ing atlextmgmt.h to use a different authorization scheme.
#ifndef ATL_NO_DEFAULT_AUTHORITY
__declspec(selectany) CDefaultAuth _Authority;
#endif
// You can choose which of the management handlers actually get used by
// #defining the following constants before including this header
// _ATL_THREADPOOL_MANAGEMENT (The thread pool manager web service and web based UI)
// _ATL_STENCILCACHE_MANAGEMENT (The stencil cache manager web service and web based UI)
// _ATL_DLLCACHE_MANAGEMENT (The DLL cache manager service and web based UI)
// You can use the following constants to remove the web based UI if you don't
// want to use it.
// _ATL_THREADPOOL_NOUI (removes the thread pool mgr's stencil handler)
// _ATL_STENCILCACHE_NOUI (removes the stencil cache mgr's stencil handler)
// _ATL_DLLCACHE_NOUI (removes the dll cache mgr's stencil handler)
// You can use the following constants to remove the web service management
// components individually
// _ATL_THREADPOOL_NOWEBSERVICE (removes the thread pool mgr's stencil handler)
// _ATL_STENCILCACHE_NOWEBSERVICE (removes the stencil cache mgr's stencil handler)
// _ATL_DLLCACHE_NOWEBSERVICE (removes the dll cache mgr's stencil handler)
// The following constants declare resource names of stencils included
// as resources in the module that uses this header. These stencils are
// used for the web based UI for the management objects. You can provide
// stencils of your own by including them as resources and redefining these
// constants before including this header.
#ifndef IDR_THREADMGR_SRF
#define IDR_THREADMGR_SRF "THREADMGR.SRF"
#endif
#ifndef IDR_STENCILMGR_SRF
#define IDR_STENCILMGR_SRF "STENCILMGR.SRF"
#endif
#ifndef IDR_DLLMGR_SRF
#define IDR_DLLMGR_SRF "DLLMGR.SRF"
#endif
// A warning so users using the web based UI to manage their extension
// will remember to include the stencil resources in their projects
#if (defined(_ATL_THREADPOOL_MANAGEMENT) && !defined(_ATL_THREADPOOL_NOUI)) || (defined(_ATL_STENCILCACHE_MANAGEMENT) && !defined(_ATL_STENCILCACHE_NOUI)) || (defined(_ATL_DLLCACHE_MANAGEMENT) && !defined(_ATL_DLLCACHE_NOUI))
#ifndef NO_ATL_MGMT_STENCIL_WARNING
#pragma message("*************** Please Note ***************")
#pragma message("Your usage of atlextmgmt.h requires you to include management")
#pragma message("stencil resources in your module's resource file.")
#pragma message("Please make sure you include atlsrv.rc in your resource file.\r\n")
#endif
#endif
// These constants define the names used for the handler objects for the
// various services. You can change the names by redefining these constants
// before including this header
#ifndef ID_THREADMGR_WEBSERVICE_NAME
#define ID_THREADMGR_WEBSERVICE_NAME "ThreadPoolManager"
#endif
#ifndef ID_THREADMGR_WEBSERVICE_URL
#define ID_THREADMGR_WEBSERVICE_URL "http://www.microsoft.com/vc/atlserver/soap/ThreadPoolManager"
#endif
#ifndef ID_THREADMGR_WEBSERVICE_WSDL
#define ID_THREADMGR_WEBSERVICE_WSDL "GenThreadPoolManagerWSDL"
#endif
#ifndef ID_THREADMGR_SRFHANDLER_NAME
#define ID_THREADMGR_SRFHANDLER_NAME "ThreadMgrSrf"
#endif
#ifndef ID_STENCILCACHEMGR_WEBSERVICE_NAME
#define ID_STENCILCACHEMGR_WEBSERVICE_NAME "StencilCacheManager"
#endif
#ifndef ID_STENCILCACHEMGR_WEBSERVICE_URL
#define ID_STENCILCACHEMGR_WEBSERVICE_URL "http://www.microsoft.com/vc/atlserver/soap/StencilCacheManager"
#endif
#ifndef ID_STENCILCACHEMGR_WEBSERVICE_WSDL
#define ID_STENCILCACHEMGR_WEBSERVICE_WSDL "GenStencilCacheManagerWSDL"
#endif
#ifndef ID_STENCILCACHEMGR_SRFHANDLER_NAME
#define ID_STENCILCACHEMGR_SRFHANDLER_NAME "StencilMgrSrf"
#endif
#ifndef ID_DLLCACHEMGR_WEBSERVICE_NAME
#define ID_DLLCACHEMGR_WEBSERVICE_NAME "DllCacheManager"
#endif
#ifndef ID_DLLCACHEMGR_WEBSERVICE_URL
#define ID_DLLCACHEMGR_WEBSERVICE_URL "http://www.microsoft.com/vc/atlserver/soap/DllCacheManager"
#endif
#ifndef ID_DLLCACHEMGR_WEBSERVICE_WSDL
#define ID_DLLCACHEMGR_WEBSERVICE_WSDL "GenDllCacheManagerWSDL"
#endif
#ifndef ID_DLLCACHEMGR_SRFHANDLER_NAME
#define ID_DLLCACHEMGR_SRFHANDLER_NAME "DllMgrSrf"
#endif
#pragma pack(push,_ATL_PACKING)
namespace ATL {
[emitidl(restricted)];
#define ATL_COLOR_TR1 RGB(0xd2, 0xff, 0xff)
#define ATL_COLOR_TR2 RGB(0xd2, 0xff, 0xd2)
#define ATL_COLOR_BODYBG RGB(0xec, 0xf9, 0xec)
// _AtlRedirectToPage builds up a redirect URL from the
// current request plus a Handler= specification and
// redirects the user's browser to that page.
inline HTTP_CODE _AtlRedirectToPage(
IHttpServerContext *pContext,
CHttpRequest& request,
CHttpResponse& response,
const char *szHandler)
{
ATLENSURE(pContext);
CStringA strRedirect("http://");
char buff[ATL_URL_MAX_URL_LENGTH];
DWORD dwLen = static_cast<DWORD>(_countof(buff));
if (!pContext->GetServerVariable("SERVER_NAME", buff, &dwLen))
{
return HTTP_FAIL;
}
buff[_countof(buff)-1]='\0';
strRedirect+=buff;
dwLen = static_cast<DWORD>(_countof(buff));
if (!request.GetUrl(buff, &dwLen))
{
return HTTP_FAIL;
}
buff[_countof(buff)-1]='\0';
strRedirect+=buff;
strRedirect+=szHandler;
if (strRedirect.GetLength() >= ATL_URL_MAX_URL_LENGTH)
{
return HTTP_FAIL;
}
BOOL bOK=response.Redirect(strRedirect.GetString());
return bOK ? HTTP_SUCCESS_NO_PROCESS : HTTP_FAIL;
}
#ifdef _ATL_THREADPOOL_MANAGEMENT
///////////////////////////////////////////////////////////////////////
// Thread pool management
[ uuid("44e9962a-5207-4d2a-a466-5f08a76e0e5d"), object ]
__interface IThreadPoolMgr
{
[id(0)] STDMETHOD(SetSize)([in] int nNumThreads);
[id(1)] STDMETHOD(GetSize)([out,retval] int *pnNumThreads);
};
class CThreadPoolMgrObject
{
public:
CThreadPoolMgrObject() throw()
{
}
HRESULT SetSize(int nNumThreads) throw()
{
if (!m_spThreadPoolConfig)
return E_UNEXPECTED;
CRevertThreadToken revert;
if (!revert.Initialize())
return E_FAIL;
HRESULT hr = m_spThreadPoolConfig->SetSize(nNumThreads);
DWORD dwErr = revert.Restore();
if (dwErr)
return AtlHresultFromWin32(dwErr);
return hr;
}
HRESULT GetSize(int *pnNumThreads) throw()
{
if (!m_spThreadPoolConfig)
return E_UNEXPECTED;
return m_spThreadPoolConfig->GetSize(pnNumThreads);
}
HTTP_CODE Initialize(IServiceProvider *pProvider) throw()
{
ATLASSERT(pProvider); // should never be NULL
if (!pProvider)
return HTTP_ERROR(500, ISE_SUBERR_UNEXPECTED);
if (m_spThreadPoolConfig)
return HTTP_SUCCESS; // already initialized
pProvider->QueryService(__uuidof(IThreadPoolConfig), &m_spThreadPoolConfig);
return m_spThreadPoolConfig ? HTTP_SUCCESS : HTTP_ERROR(500, ISE_SUBERR_UNEXPECTED);
}
private:
CComPtr<IThreadPoolConfig> m_spThreadPoolConfig;
};
#ifndef _ATL_THREADPOOL_NOWEBSERVICE
#pragma warning(push)
#pragma warning(disable:4199)
[
soap_handler(
name= ID_THREADMGR_WEBSERVICE_NAME,
namespace= ID_THREADMGR_WEBSERVICE_URL,
protocol= "soap"
),
request_handler(
name= ID_THREADMGR_WEBSERVICE_NAME,
sdl= ID_THREADMGR_WEBSERVICE_WSDL
)
]
class CThreadPoolManager :
public IThreadPoolMgr
{
#pragma warning(pop)
public:
[soap_method]
STDMETHOD(SetSize)(int nNumThreads)
{
return m_PoolMgr.SetSize(nNumThreads);
}
[soap_method]
STDMETHOD(GetSize)(int *pnNumThreads)
{
return m_PoolMgr.GetSize(pnNumThreads);
}
// override HandleRequest to Initialize our m_spServiceProvider
// and to handle authorizing the client.
HTTP_CODE HandleRequest(AtlServerRequest *pRequestInfo, IServiceProvider *pProvider)
{
HTTP_CODE hcErr = m_PoolMgr.Initialize(pProvider);
if (hcErr != HTTP_SUCCESS)
return hcErr;
// Make sure caller is authorized on this system
__if_exists(_Authority)
{
hcErr = HTTP_FAIL;
ATLTRY(hcErr = _Authority.IsAuthorized(pRequestInfo, ATL_DEFAULT_AUTHGRP))
}
if (hcErr == HTTP_SUCCESS)
{
hcErr = __super::HandleRequest(pRequestInfo, pProvider);
}
return hcErr;
}
private:
CThreadPoolMgrObject m_PoolMgr;
};
#endif //_ATL_THREADPOOL_NOWEBSERVICE
#ifndef _ATL_THREADPOOL_NOUI
#define INVALID_COMMAND_ID -1
#define MAX_COMMAND_ID 64
[request_handler(name=ID_THREADMGR_SRFHANDLER_NAME)]
class CThreadMgrStencil
{
public:
CThreadMgrStencil() :
m_nColor(ATL_COLOR_TR1)
{
}
[tag_name("GetSize")]
HTTP_CODE GetSize()
{
int nSize = 0;
HRESULT hr = m_PoolMgr.GetSize(&nSize);
if (SUCCEEDED(hr))
{
m_HttpResponse << nSize;
}
else
m_HttpResponse << "size not found";
return HTTP_SUCCESS;
}
[tag_name("GetTRColor")]
HTTP_CODE GetTRColor()
{
m_nColor = (m_nColor == ATL_COLOR_TR1) ? ATL_COLOR_TR2 : ATL_COLOR_TR1;
TCHAR cr[8];
if (RGBToHtml(m_nColor, cr, sizeof(cr)))
m_HttpResponse << cr;
return HTTP_SUCCESS;
}
[tag_name("GetBodyColor")]
HTTP_CODE GetBodyColor()
{
TCHAR cr[8];
if (RGBToHtml(ATL_COLOR_BODYBG, cr, sizeof(cr)))
m_HttpResponse << cr;
return HTTP_SUCCESS;
}
HTTP_CODE ValidateAndExchange() throw()
{
_ATLTRY
{
// Initialize the thread pool manager instance. Internally
// the initialize function will only intialize it's data structures
// once.
HTTP_CODE hcErr = m_PoolMgr.Initialize(m_spServiceProvider);
if (hcErr != HTTP_SUCCESS)
return hcErr;
__if_exists(_Authority)
{
// Make sure caller is authorized on this system
hcErr = HTTP_FAIL;
ATLTRY(hcErr = _Authority.IsAuthorized(m_pRequestInfo, ATL_DEFAULT_AUTHGRP))
if (hcErr != HTTP_SUCCESS)
return hcErr;
}
m_HttpResponse.SetContentType("text/html");
CString strHandler, strOptParam;
int nCmdToExec = INVALID_COMMAND_ID;
if (m_HttpRequest.GetMethod() == CHttpRequest::HTTP_METHOD_POST)
{
// check to see if we have a "Method" form variable and can execute a command
DWORD dwErr = m_HttpRequest.FormVars.Exchange("Method", &strHandler);
if (dwErr == VALIDATION_S_OK)
{
if (strHandler == _T("ExecuteCommand"))
{
// get the value of the command parameter so we can execute it
dwErr = m_HttpRequest.FormVars.Validate("command", &nCmdToExec, 0, MAX_COMMAND_ID);
if (dwErr == VALIDATION_S_OK)
{
// get the optional parameter if it's there.
m_HttpRequest.FormVars.Validate("DynValue", &strOptParam, 0, MAX_COMMAND_ID);
hcErr = ExecCommand(nCmdToExec, strOptParam);
return hcErr;
}
}
}
}
// If we had a proper command to execute, we would have done it by now.
// Just handle like it's a normal request to view the thread count.
hcErr = LoadStencilResource(m_hInstHandler, IDR_THREADMGR_SRF);
return hcErr;
}
_ATLCATCHALL()
{
return HTTP_FAIL;
}
}
HTTP_CODE ExecCommand(int nCmdToExec, CString& strOptParam)
{
switch (nCmdToExec)
{
case 0:
TCHAR *pStop = NULL;
int nValue = _tcstoul(strOptParam, &pStop, 10);
m_PoolMgr.SetSize(nValue);
break;
};
return _AtlRedirectToPage(
m_spServerContext,
m_HttpRequest,
m_HttpResponse,
"?Handler=" ID_THREADMGR_SRFHANDLER_NAME
);
}
private:
CThreadPoolMgrObject m_PoolMgr;
long m_nColor;
CString m_strUrl;
};
#endif // _ATL_THREADPOOL_NOUI
#endif // _ATL_THREADPOOL_MANAGEMENT
#ifdef _ATL_STENCILCACHE_MANAGEMENT
//////////////////////////////////////////////////////////////////////
// Stencil cache management
class CStencilCacheMgrObject
{
public:
CStencilCacheMgrObject()
{
}
HRESULT GetCurrentEntryCount(__int64 *pdwSize)
{
ATLASSUME(m_spMemCacheStats);
if (!pdwSize)
return E_INVALIDARG;
DWORD dwValue;
HRESULT hr = m_spMemCacheStats->GetCurrentEntryCount(&dwValue);
if (hr == S_OK)
{
*pdwSize = dwValue;
}
return hr;
}
HRESULT ClearStats()
{
ATLENSURE(m_spMemCacheStats);
return m_spMemCacheStats->ClearStats();
}
HRESULT GetHitCount(__int64 *pdwSize)
{
ATLENSURE(m_spMemCacheStats);
if (!pdwSize)
return E_INVALIDARG;
DWORD dwValue;
HRESULT hr = m_spMemCacheStats->GetHitCount(&dwValue);
if (hr == S_OK)
{
*pdwSize = dwValue;
}
return hr;
}
HRESULT GetMissCount(__int64 *pdwSize)
{
ATLENSURE(m_spMemCacheStats);
if (!pdwSize)
return E_INVALIDARG;
DWORD dwValue;
HRESULT hr = m_spMemCacheStats->GetMissCount(&dwValue);
if (hr == S_OK)
{
*pdwSize = dwValue;
}
return hr;
}
HRESULT GetCurrentAllocSize(__int64 *pdwSize)
{
ATLENSURE(m_spMemCacheStats);
if (!pdwSize)
return E_INVALIDARG;
DWORD dwValue;
HRESULT hr = m_spMemCacheStats->GetCurrentAllocSize(&dwValue);
if (hr == S_OK)
{
*pdwSize = dwValue;
}
return hr;
}
HRESULT GetMaxAllocSize(__int64 *pdwSize)
{
ATLENSURE(m_spMemCacheStats);
if (!pdwSize)
return E_INVALIDARG;
DWORD dwValue;
HRESULT hr = m_spMemCacheStats->GetMaxAllocSize(&dwValue);
if (hr == S_OK)
{
*pdwSize = dwValue;
}
return hr;
}
HRESULT GetMaxEntryCount(__int64 *pdwSize)
{
ATLENSURE(m_spMemCacheStats);
if (!pdwSize)
return E_INVALIDARG;
DWORD dwValue;
HRESULT hr = m_spMemCacheStats->GetMaxEntryCount(&dwValue);
if (hr == S_OK)
{
*pdwSize = dwValue;
}
return hr;
}
HRESULT RemoveStencil(__int64 hStencil)
{
ATLENSURE(m_spStencilCacheControl);
return m_spStencilCacheControl->RemoveStencil((const HCACHEITEM)hStencil);
}
HRESULT RemoveStencilByName(BSTR szStencil) throw()
{
ATLENSURE_RETURN(m_spStencilCacheControl);
return m_spStencilCacheControl->RemoveStencilByName(CW2A(szStencil));
}
HRESULT RemoveAllStencils()
{
ATLENSURE(m_spStencilCacheControl);
return m_spStencilCacheControl->RemoveAllStencils();
}
// we show lifespan in milliseconds in the UI so we have to
// do the conversion to 100ns intervals here.
HRESULT SetDefaultLifespan(unsigned __int64 dwdwLifespan)
{
ATLENSURE(m_spStencilCacheControl);
// convert to 100ns intervals
return m_spStencilCacheControl->SetDefaultLifespan(dwdwLifespan * CFileTime::Millisecond);
}
HRESULT GetDefaultLifespan(unsigned __int64 *pdwdwLifespan)
{
ATLENSURE(m_spStencilCacheControl);
ATLENSURE(pdwdwLifespan!=NULL);
*pdwdwLifespan = 0;
unsigned __int64 dwls = 0;
HRESULT hr = m_spStencilCacheControl->GetDefaultLifespan(&dwls);
// convert to milliseconds
if (SUCCEEDED(hr))
{
dwls /= CFileTime::Millisecond;
*pdwdwLifespan = dwls;
}
return hr;
}
HTTP_CODE Initialize(IServiceProvider *pProvider) throw()
{
ATLASSERT(pProvider); // should never be NULL
if (!pProvider)
return HTTP_ERROR(500, ISE_SUBERR_UNEXPECTED);
if (m_spMemCacheStats && m_spStencilCacheControl)
return HTTP_SUCCESS; // already initialized
CComPtr<IStencilCache> spStencilCache;
pProvider->QueryService(__uuidof(IStencilCache), &spStencilCache);
if (spStencilCache)
{
if (!m_spMemCacheStats)
{
spStencilCache->QueryInterface(__uuidof(IMemoryCacheStats),
(void**)&m_spMemCacheStats);
}
if (!m_spStencilCacheControl)
{
spStencilCache->QueryInterface(__uuidof(IStencilCacheControl),
(void**)&m_spStencilCacheControl);
}
}
return (m_spMemCacheStats && m_spStencilCacheControl)
? HTTP_SUCCESS : HTTP_ERROR(500, ISE_SUBERR_UNEXPECTED);
}
private:
CComPtr<IMemoryCacheStats> m_spMemCacheStats;
CComPtr<IStencilCacheControl> m_spStencilCacheControl;
};
#ifndef _ATL_STENCILCACHE_NOWEBSERVICE
[ uuid("3813895C-4C4C-41df-95F4-12220140B164"), object ]
__interface IStencilCacheMgr
{
// data access
[id(0)] STDMETHOD(GetCurrentEntryCount)([out,retval] __int64 *pdwSize);
[id(1)] STDMETHOD(GetHitCount)([out,retval] __int64 *pdwSize);
[id(2)] STDMETHOD(GetMissCount)([out,retval] __int64 *pdwSize);
[id(3)] STDMETHOD(GetCurrentAllocSize)([out,retval] __int64 *pdwSize);
[id(4)] STDMETHOD(GetMaxAllocSize)([out,retval] __int64 *pdwSize);
[id(5)] STDMETHOD(GetMaxEntryCount)([out,retval] __int64 *pdwSize);
[id(6)] STDMETHOD(GetDefaultLifespan)([out,retval] unsigned __int64 *pdwdwLifespan);
// commands
[id(7)] STDMETHOD(ClearStats)();
[id(8)] STDMETHOD(RemoveStencil)([in] __int64 hStencil);
[id(9)] STDMETHOD(RemoveStencilByName)([in] BSTR szStencil);
[id(10)] STDMETHOD(RemoveAllStencils)();
[id(11)] STDMETHOD(SetDefaultLifespan)([in] unsigned __int64 dwdwLifespan);
};
#pragma warning(push)
#pragma warning(disable:4199)
[
soap_handler( name= ID_STENCILCACHEMGR_WEBSERVICE_NAME,
namespace= ID_STENCILCACHEMGR_WEBSERVICE_URL,
protocol= "soap"
),
request_handler(
name= ID_STENCILCACHEMGR_WEBSERVICE_NAME,
sdl= ID_STENCILCACHEMGR_WEBSERVICE_WSDL )
]
class CStencilCacheManager :
public IStencilCacheMgr
{
#pragma warning(pop)
public:
[ soap_method ]
STDMETHOD(GetCurrentEntryCount)(__int64 *pdwSize)
{
return m_MgrObj.GetCurrentEntryCount(pdwSize);
}
[ soap_method ]
STDMETHOD(ClearStats)()
{
return m_MgrObj.ClearStats();
}
[ soap_method ]
STDMETHOD(GetHitCount)(__int64 *pdwSize)
{
return m_MgrObj.GetHitCount(pdwSize);
}
[ soap_method ]
STDMETHOD(GetMissCount)(__int64 *pdwSize)
{
return m_MgrObj.GetMissCount(pdwSize);
}
[ soap_method ]
STDMETHOD(GetCurrentAllocSize)(__int64 *pdwSize)
{
return m_MgrObj.GetCurrentAllocSize(pdwSize);
}
[ soap_method ]
STDMETHOD(GetMaxAllocSize)(__int64 *pdwSize)
{
return m_MgrObj.GetMaxAllocSize(pdwSize);
}
[ soap_method ]
STDMETHOD(GetMaxEntryCount)(__int64 *pdwSize)
{
return m_MgrObj.GetMaxEntryCount(pdwSize);
}
[ soap_method ]
STDMETHOD(RemoveStencil)(__int64 hStencil)
{
return m_MgrObj.RemoveStencil(hStencil);
}
[ soap_method ]
STDMETHOD(RemoveStencilByName)(BSTR bstrStencil)
{
return m_MgrObj.RemoveStencilByName(bstrStencil);
}
[ soap_method ]
STDMETHOD(RemoveAllStencils)()
{
return m_MgrObj.RemoveAllStencils();
}
// we show lifespan in milliseconds in the UI.
// m_MgrObj handles the conversion to 100ns intervals.
[ soap_method ]
STDMETHOD(SetDefaultLifespan)(unsigned __int64 dwdwLifespan)
{
return m_MgrObj.SetDefaultLifespan(dwdwLifespan);
}
[ soap_method ]
STDMETHOD(GetDefaultLifespan)(unsigned __int64 *pdwdwLifespan)
{
return m_MgrObj.GetDefaultLifespan(pdwdwLifespan);
}
HTTP_CODE HandleRequest(AtlServerRequest *pRequestInfo, IServiceProvider *pProvider)
{
HTTP_CODE hcErr = m_MgrObj.Initialize(pProvider);
if (hcErr != HTTP_SUCCESS)
return hcErr;
__if_exists(_Authority)
{
// Make sure caller is authorized on this system
hcErr = HTTP_FAIL;
ATLTRY(hcErr = _Authority.IsAuthorized(pRequestInfo, ATL_DEFAULT_AUTHGRP))
}
if (hcErr == HTTP_SUCCESS)
{
hcErr = __super::HandleRequest(pRequestInfo, pProvider);
}
return hcErr;
}
private:
CStencilCacheMgrObject m_MgrObj;
};
#endif //_ATL_STENCILCACHE_NOWEBSERVICE
#ifndef _ATL_STENCILCACHE_NOUI
typedef HRESULT (CStencilCacheMgrObject::*PFNGETDATA)(__int64 *pdwSize);
struct CCache_data
{
PFNGETDATA m_pfn;
char m_sz[128];
};
#define INVALID_DATA_PTR ((DWORD_PTR) -1)
#define INVALID_COMMAND_ID -1
#define MAX_COMMAND_ID 64
#define ATL_STENCILCACHECMD_CLEARALLSTATS 0
#define ATL_STENCILCACHECMD_REMOVESTENCIL 1
#define ATL_STENCILCACHECMD_REMOVEALLSTENCILS 2
#define ATL_STENCILCACHECMD_SETDEFLIFESPAN 3
[request_handler(name=ID_STENCILCACHEMGR_SRFHANDLER_NAME)]
class CStencilMgr
{
public:
CStencilMgr()
{
m_pData = (CCache_data*)INVALID_DATA_PTR;
m_nColor = ATL_COLOR_TR1;
}
HTTP_CODE ValidateAndExchange() throw()
{
_ATLTRY
{
HTTP_CODE hcErr = m_MgrObj.Initialize(m_spServiceProvider);
if (hcErr != HTTP_SUCCESS)
return hcErr;
__if_exists(_Authority)
{
// Make sure caller is authorized on this system
hcErr = HTTP_FAIL;
ATLTRY(hcErr = _Authority.IsAuthorized(m_pRequestInfo, ATL_DEFAULT_AUTHGRP))
if (hcErr != HTTP_SUCCESS)
return hcErr;
}
m_HttpResponse.SetContentType("text/html");
// check to see if we have a "Handler" form variable
CString strHandler, strOptParam;
int nCmdToExec;
if (m_HttpRequest.GetMethod() == CHttpRequest::HTTP_METHOD_POST)
{
DWORD dwErr = m_HttpRequest.FormVars.Exchange("Method", &strHandler);
if (dwErr == VALIDATION_S_OK)
{
if (strHandler == _T("ExecuteCommand"))
{
// get the value of the command parameter so we can execute it
dwErr = m_HttpRequest.FormVars.Validate("command", &nCmdToExec, 0, MAX_COMMAND_ID);
if (dwErr == VALIDATION_S_OK)
{
// get the optional parameter if it's there.
m_HttpRequest.FormVars.Validate("DynValue", &strOptParam, 0, MAX_COMMAND_ID);
hcErr = ExecCommand(nCmdToExec, strOptParam);
return hcErr;
}
}
}
}
hcErr = LoadStencilResource(m_hInstHandler, IDR_STENCILMGR_SRF);
return hcErr;
}
_ATLCATCHALL()
{
return HTTP_FAIL;
}
}
HTTP_CODE ExecCommand(int nCmdToExec, CString& strOptParam)
{
switch (nCmdToExec)
{
case ATL_STENCILCACHECMD_CLEARALLSTATS:
m_MgrObj.ClearStats();
break;
case ATL_STENCILCACHECMD_REMOVESTENCIL:
m_MgrObj.RemoveStencilByName(strOptParam.AllocSysString());
break;
case ATL_STENCILCACHECMD_REMOVEALLSTENCILS:
m_MgrObj.RemoveAllStencils();
break;
case ATL_STENCILCACHECMD_SETDEFLIFESPAN:
TCHAR *pStop = NULL;
m_MgrObj.SetDefaultLifespan(_tcstoul(strOptParam, &pStop, 10));
break;
};
return _AtlRedirectToPage(
m_spServerContext,
m_HttpRequest,
m_HttpResponse,
"?Handler=" ID_STENCILCACHEMGR_SRFHANDLER_NAME
);
}
[tag_name("GetNextStencilCacheStats")]
HTTP_CODE GetNextStencilCacheStats()
{
if (m_pData == (CCache_data*)INVALID_DATA_PTR)
{
m_pData = GetCacheData();
return HTTP_SUCCESS;
}
m_pData++;
if (m_pData->m_pfn != NULL)
return HTTP_SUCCESS;
m_pData = (CCache_data*)INVALID_DATA_PTR;
return HTTP_S_FALSE;
}
[tag_name("GetCacheValue")]
HTTP_CODE GetCacheValue()
{
ATLENSURE(m_pData);
ATLENSURE(m_pData != (CCache_data*)INVALID_DATA_PTR);
m_HttpResponse << m_pData->m_sz;
return HTTP_SUCCESS;
}
[tag_name("GetCacheQuantity")]
HTTP_CODE GetCacheQuantity()
{
ATLENSURE(m_pData);
ATLENSURE(m_pData != (CCache_data*)INVALID_DATA_PTR);
__int64 dwValue = 0;
PFNGETDATA pfn = m_pData->m_pfn;
ATLENSURE(pfn);
CStencilCacheMgrObject *pMgr = &m_MgrObj;
(pMgr->*pfn)(&dwValue);
m_HttpResponse << dwValue;
return HTTP_SUCCESS;
}
[tag_name("GetTRColor")]
HTTP_CODE GetTRColor()
{
m_nColor = (m_nColor == ATL_COLOR_TR1) ? ATL_COLOR_TR2 : ATL_COLOR_TR1;
TCHAR cr[8];
if (RGBToHtml(m_nColor, cr, sizeof(cr)))
m_HttpResponse << cr;
return HTTP_SUCCESS;
}
[tag_name("GetBodyColor")]
HTTP_CODE GetBodyColor()
{
TCHAR cr[8];
if (RGBToHtml(ATL_COLOR_BODYBG, cr, sizeof(cr)))
m_HttpResponse << cr;
return HTTP_SUCCESS;
}
private:
static CCache_data* GetCacheData()
{
static CCache_data cache_data[] =
{
{(PFNGETDATA)&CStencilCacheMgrObject::GetCurrentEntryCount, "Current Cache Entry Count(stencils)"},
{(PFNGETDATA)&CStencilCacheMgrObject::GetHitCount, "Cache Hit Count(stencils)"},
{(PFNGETDATA)&CStencilCacheMgrObject::GetMissCount, "Cache Miss Count(stencils)"},
{(PFNGETDATA)&CStencilCacheMgrObject::GetCurrentAllocSize, "Cache memory allocation(bytes)"},
{(PFNGETDATA)&CStencilCacheMgrObject::GetMaxAllocSize, "Cache maximum allocation size(bytes)"},
{(PFNGETDATA)&CStencilCacheMgrObject::GetMaxEntryCount, "Cache maximum entry count(stencils)"},
{(PFNGETDATA)&CStencilCacheMgrObject::GetDefaultLifespan, "Default stencil lifespan(ms)"},
{NULL, NULL}
};
return cache_data;
}
CStencilCacheMgrObject m_MgrObj;
CCache_data *m_pData;
long m_nColor;
};
//__declspec(selectany) CComObjectGlobal<CStencilCacheManager> CStencilMgr::m_cachemgr;
#endif // _ATL_STENCILCACHE_NOUI
#endif // _ATL_STENCILCACHE_MANAGEMENT
//////////////////////////////////////////////////////////////////////
// DLL cache management
#ifdef _ATL_DLLCACHE_MANAGEMENT
#ifndef _ATL_DLLCACHE_NOWEBSERVICE
[export]
#endif
struct _DLL_CACHE_ENTRY
{
DWORD hInstDll;
DWORD dwRefs;
BSTR szDllName;
};
class CDllMgrObject
{
public:
HRESULT GetEntries(DWORD dwCount, _DLL_CACHE_ENTRY *pEntries, DWORD *pdwCopied)
{
ATLASSUME(m_spDllCache);
HRESULT hr = E_FAIL;
DLL_CACHE_ENTRY *pe = NULL;
if (!m_spDllCache)
return E_UNEXPECTED;
if (dwCount != 0 && pEntries == NULL)
return E_UNEXPECTED; // asking for entries but no place to put them
if (!pdwCopied)
return E_POINTER;
*pdwCopied = 0;
if (dwCount)
{
pe = new DLL_CACHE_ENTRY[dwCount];
if (!pe)
return E_OUTOFMEMORY;
}
hr = m_spDllCache->GetEntries(dwCount, pe, pdwCopied);
if (hr == S_OK && dwCount != 0 && pEntries != NULL)
{
// SysAllocString our path strings
for (DWORD i = 0; i<*pdwCopied; i++)
{
pEntries[i].hInstDll = (DWORD)(DWORD_PTR)pe[i].hInstDll;
pEntries[i].dwRefs = pe[i].dwRefs;
pEntries[i].szDllName = ::SysAllocString(CA2W(pe[i].szDllName));
}
}
delete [] pe;
return hr;
}
HRESULT GetEntryCount(DWORD *pdwCount)
{
ATLASSUME(m_spDllCache);
if (!m_spDllCache)
return E_UNEXPECTED;
return m_spDllCache->GetEntries(0, NULL, pdwCount);
}
HTTP_CODE Initialize(IServiceProvider *pProvider)
{
ATLASSERT(pProvider); // should never be NULL
if (!pProvider)
return HTTP_ERROR(500, ISE_SUBERR_UNEXPECTED);
if (m_spDllCache)
return HTTP_SUCCESS; // already initialized
pProvider->QueryService(__uuidof(IDllCache), &m_spDllCache);
return m_spDllCache ? HTTP_SUCCESS : HTTP_ERROR(500, ISE_SUBERR_UNEXPECTED);
}
private:
CComPtr<IDllCache> m_spDllCache;
}; // CDllMgrObject
#ifndef _ATL_DLLCACHE_NOWEBSERVICE
// _DLL_CACHE_ENTRY is our own version of DLL_CACHE_ENTRY(atlcache.h) that
// uses a BSTR instead of a fixed length string for the szDllName for compatiblility
// with our SOAP implementation.
[ uuid("A0C00AF8-CEA5-46b9-97ED-FDEE55B583EF"), object ]
__interface IDllCacheMgr
{
[id(0)] STDMETHOD(GetEntries)([in] DWORD dwCount, [out] _DLL_CACHE_ENTRY *pEntries, [out, retval] DWORD *pdwCopied);
[id(1)] STDMETHOD(GetEntryCount)([out, retval] DWORD *pdwCount);
};
#pragma warning(push)
#pragma warning(disable:4199)
[
soap_handler(
name= ID_DLLCACHEMGR_WEBSERVICE_NAME,
namespace= ID_DLLCACHEMGR_WEBSERVICE_URL,
protocol= "soap"
),
request_handler(
name= ID_DLLCACHEMGR_WEBSERVICE_NAME,
sdl= ID_DLLCACHEMGR_WEBSERVICE_WSDL
)
]
class CDllCacheManager :
public IDllCacheMgr
{
#pragma warning(pop)
public:
[soap_method]
HRESULT GetEntries(DWORD dwCount, _DLL_CACHE_ENTRY *pEntries, DWORD *pdwCopied)
{
return m_MgrObj.GetEntries(dwCount, pEntries, pdwCopied);
}
[soap_method]
STDMETHOD(GetEntryCount)(DWORD *pdwCount)
{
return m_MgrObj.GetEntries(0, NULL, pdwCount);
}
HTTP_CODE HandleRequest(AtlServerRequest *pRequestInfo, IServiceProvider *pProvider)
{
HTTP_CODE hcErr = m_MgrObj.Initialize(pProvider);
if (hcErr != HTTP_SUCCESS)
return hcErr;
__if_exists(_Authority)
{
// Make sure caller is authorized on this system
hcErr = HTTP_FAIL;
ATLTRY(hcErr = _Authority.IsAuthorized(pRequestInfo, ATL_DEFAULT_AUTHGRP))
}
if (hcErr == HTTP_SUCCESS)
{
hcErr = __super::HandleRequest(pRequestInfo, pProvider);
}
return hcErr;
}
protected:
CDllMgrObject m_MgrObj;
};
#endif _ATL_DLLCACHE_NOWEBSERVICE
#ifndef _ATL_DLLCACHE_NOUI
#define INVALID_INDEX -1
[
request_handler(name=ID_DLLCACHEMGR_SRFHANDLER_NAME)
]
class CDllCacheMgr
{
public:
CDllCacheMgr() : m_nColor(ATL_COLOR_TR1),
m_nEnumCount(INVALID_INDEX),
m_nEnumIndex(INVALID_INDEX),
m_pEntries(NULL)
{
}
[tag_name("GetTRColor")]
HTTP_CODE GetTRColor()
{
m_nColor = (m_nColor == ATL_COLOR_TR1) ? ATL_COLOR_TR2 : ATL_COLOR_TR1;
TCHAR cr[8];
if (RGBToHtml(m_nColor, cr, sizeof(cr)))
m_HttpResponse << cr;
return HTTP_SUCCESS;
}
[tag_name("GetBodyColor")]
HTTP_CODE GetBodyColor()
{
TCHAR cr[8];
if (RGBToHtml(ATL_COLOR_BODYBG, cr, sizeof(cr)))
m_HttpResponse << cr;
return HTTP_SUCCESS;
}
[tag_name("GetNumEntries")]
HTTP_CODE GetNumEntries()
{
DWORD dwEntries = 0;
m_MgrObj.GetEntryCount(&dwEntries);
m_HttpResponse << dwEntries;
return HTTP_SUCCESS;
}
[tag_name("EnumEntries")]
HTTP_CODE EnumEntries()
{
// we lock the cache while we enum entries so no entries
// will be removed during the enumeration request.
if (m_nEnumIndex == INVALID_INDEX)
{
// set up for the iteration
m_MgrObj.GetEntryCount((DWORD*)&m_nEnumCount);
if (!m_nEnumCount)
return HTTP_S_FALSE; // nothing to enum
m_pEntries = new _DLL_CACHE_ENTRY[m_nEnumCount];
if (!m_pEntries)
return HTTP_ERROR(500, ISE_SUBERR_OUTOFMEM);
DWORD dwFetched = INVALID_INDEX;
if (S_OK != m_MgrObj.GetEntries(m_nEnumCount, m_pEntries, &dwFetched))
return HTTP_ERROR(500, ISE_SUBERR_UNEXPECTED);
m_nEnumIndex = 0;
return HTTP_SUCCESS;
}
m_nEnumIndex++;
if (m_nEnumIndex < m_nEnumCount)
return HTTP_SUCCESS; // continue iterating
else
{
// done, clean up
for (int i = 0; i< m_nEnumCount; i++)
{
::SysFreeString(m_pEntries[i].szDllName);
}
delete [] m_pEntries;
m_pEntries = NULL;
m_nEnumCount = INVALID_INDEX;
m_nEnumIndex = INVALID_INDEX;
return HTTP_S_FALSE; // terminate iterations.
}
}
[tag_name("GetDllName")]
HTTP_CODE GetDllName()
{
m_HttpResponse << m_pEntries[m_nEnumIndex].szDllName;
return HTTP_SUCCESS;
}
[tag_name("GetDllReferences")]
HTTP_CODE GetDllReferences()
{
m_HttpResponse << m_pEntries[m_nEnumIndex].dwRefs;
return HTTP_SUCCESS;
}
HTTP_CODE ValidateAndExchange()
{
HTTP_CODE hcErr = m_MgrObj.Initialize(m_spServiceProvider);
if (hcErr != HTTP_SUCCESS)
return hcErr;
__if_exists(_Authority)
{
// Make sure caller is authorized on this system
hcErr = HTTP_FAIL;
ATLTRY(hcErr = _Authority.IsAuthorized(m_pRequestInfo, ATL_DEFAULT_AUTHGRP))
if (hcErr != HTTP_SUCCESS)
return hcErr;
}
hcErr = LoadStencilResource(m_hInstHandler, IDR_DLLMGR_SRF);
m_HttpResponse.SetContentType("text/html");
return hcErr;
}
CDllMgrObject m_MgrObj;
long m_nColor;
int m_nEnumCount;
int m_nEnumIndex;
_DLL_CACHE_ENTRY *m_pEntries;
};
#endif // _ATL_DLLCACHE_NOUI
#endif // _ATL_DLLCACHE_MANAGEMENT
}; // ATL
#pragma pack(pop)
#pragma warning(pop)
#endif // __ATLEXTMGMT_H__