// 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 #include #include #include // // 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 members 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 noone 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 #includin'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 n 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(_countof(buff)); if (!pContext->GetServerVariable("SERVER_NAME", buff, &dwLen)) { return HTTP_FAIL; } buff[_countof(buff)-1]='\0'; strRedirect+=buff; dwLen = static_cast(_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 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(m_spStencilCacheControl); return m_spStencilCacheControl->RemoveStencilByName(CW2A(szStencil)); } HRESULT RemoveAllStencils() { ATLENSURE(m_spStencilCacheControl); return m_spStencilCacheControl->RemoveAllStencils(); } // we show lifespan in milli-seconds 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 milli seconds 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 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 m_spMemCacheStats; CComPtr 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 milli-seconds 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 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 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__