|
|
/*===================================================================
Microsoft Denali
Microsoft Confidential. Copyright 1996 Microsoft Corporation. All Rights Reserved.
Component: Appln Manager
File: Applmgr.h
Owner: PramodD
This is the application manager header file. ===================================================================*/ #ifndef APPLMGR_H
#define APPLMGR_H
#include "debug.h"
#include "hashing.h"
#include "cachemgr.h"
#include "appcnfg.h"
#include "compcol.h"
#include "fileapp.h"
#include "idhash.h"
#include "memcls.h"
#include "ftm.h"
#include "disptch2.h"
/*===================================================================
#defines
===================================================================*/
#define NUM_APPLMGR_HASHING_BUCKETS 17
#define NOTIFICATION_BUFFER_SIZE 4096
#define INVALID_THREADID 0xFFFFFFFF
#include "asptlb.h"
// Use to specify which source file name you want (pathInfo or pathTranslated)
#ifndef _SRCPATHTYPE_DEFINED
#define _SRCPATHTYPE_DEFINED
enum SOURCEPATHTYPE { SOURCEPATHTYPE_VIRTUAL = 0, SOURCEPATHTYPE_PHYSICAL = 1 };
#endif
/*===================================================================
Forward declarations ===================================================================*/
class CComponentCollection; class CSessionMgr; class CViperActivity; class CActiveScriptEngine; struct IDebugApplication; struct IDebugApplicationNode;
/*===================================================================
C A p p l n V a r i a n t s ===================================================================*/ class CApplnVariants : public IVariantDictionaryImpl { private: ULONG m_cRefs; // ref count
CAppln * m_pAppln; // pointer to parent object
CompType m_ctColType; // type of components in collection
CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
HRESULT ObjectNameFromVariant(VARIANT &vKey, WCHAR **ppwszName, BOOL fVerify = FALSE);
public: CApplnVariants(); ~CApplnVariants();
HRESULT Init(CAppln *pAppln, CompType ctColType); HRESULT UnInit();
// The Big Three
STDMETHODIMP QueryInterface(const GUID &, void **); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release();
// OLE Automation Interface
STDMETHODIMP get_Item(VARIANT Var, VARIANT *pvar); STDMETHODIMP put_Item(VARIANT varKey, VARIANT var); STDMETHODIMP putref_Item(VARIANT varKey, VARIANT var); STDMETHODIMP get_Key(VARIANT Var, VARIANT *pvar); STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn); STDMETHODIMP get_Count(int *pcValues); STDMETHODIMP Remove(VARIANT VarKey); STDMETHODIMP RemoveAll(); // Cache on per-class basis
ACACHE_INCLASS_DEFINITIONS() };
/*===================================================================
C A p p l n ===================================================================*/
class CAppln : public IApplicationObjectImpl, public CLinkElem, public CFTMImplementation {
friend class CApplnMgr; friend class CApplnCleanupMgr; friend class CDirMonitorEntry; friend class CApplnVariants; private:
//========= Misc flags
DWORD m_fInited : 1; // Are we initialized?
DWORD m_fFirstRequestRan : 1; // 1st request for this app ran?
DWORD m_fGlobalChanged : 1; // Global.asa has changed?
DWORD m_fDeleteInProgress : 1; // Delete event posted?
DWORD m_fTombstone : 1; // ASP is done with the app?
DWORD m_fDebuggable : 1; // Debugging enabled for this app?
//========= Notification flags
// ReadDirectoryChangesW done?
DWORD m_fNotificationAdded : 1; // change notification should use impersonation?
DWORD m_fUseImpersonationHandle : 1;
//========= Ref counts
DWORD m_cRefs; DWORD m_cRequests; // Active requests count
DWORD m_cSessions; // Session count
//========= Application's key, path, global.asa
// metabase key (unique app id)
TCHAR *m_pszMetabaseKey; // physical application directory path
TCHAR *m_pszApplnPath; // virtual application directory path
TCHAR *m_pszApplnVRoot; // Path to global.asa for application
TCHAR *m_pszGlobalAsa; // Pointer to compliled template for global.asa
CTemplate *m_pGlobalTemplate;
//========= Application's Session Manager
CSessionMgr *m_pSessionMgr; // Session manager for this app
//========= Application's Configuration Settings
CAppConfig *m_pAppConfig; // Application Configuration object
//========= Application's Component Collection
CComponentCollection *m_pApplCompCol; // Application scope objects
//========= Application's dictionaries for presenting component collection
CApplnVariants *m_pProperties; CApplnVariants *m_pTaggedObjects;
//========= Viper Activity
// Application's activity (for thread-locked appls)
CViperActivity *m_pActivity;
// ======== COM+ Services Config Object
IUnknown *m_pServicesConfig; //========= Critical section for internal lock
CRITICAL_SECTION m_csInternalLock;
//========= External lock support
CRITICAL_SECTION m_csApplnLock; DWORD m_dwLockThreadID; // thread which locked
DWORD m_cLockRefCount; // lock count
//========= Notification support
// Identifiers stored by notification system
CPtrArray m_rgpvDME; // list of directory monitor entries
CPtrArray m_rgpvFileAppln; // list of entries relating files to applications
// User impersonation handle for UNC change notification
HANDLE m_hUserImpersonation;
//========= Type Library wrapper from GLOBAL.ASA
IDispatch *m_pdispGlobTypeLibWrapper;
//========= SupportErrorInfo
// Interface to indicate that we support ErrorInfo reporting
CSupportErrorInfo m_ISuppErrImp; //========= Debugging Support
// root node for browsing of running documents
IDebugApplicationNode *m_pAppRoot;
HRESULT InitServicesConfig();
// proc used to asynchronously cleanup the app
static DWORD __stdcall ApplnCleanupProc(VOID *pArg);
public: CAppln(); ~CAppln(); HRESULT Init ( TCHAR *pszApplnKey, TCHAR *pszApplnPath, CIsapiReqInfo *pIReq, HANDLE hUserImpersonation );
// cnvert to tombstone state
HRESULT UnInit();
// create application's activity as clone of param
HRESULT BindToActivity(CViperActivity *pActivity = NULL);
// set (and remember) global.asa for this app
HRESULT SetGlobalAsa(const TCHAR *pszGlobalAsa);
// make sure script didn't leave locks
HRESULT UnLockAfterRequest();
// Non-delegating object IUnknown
STDMETHODIMP QueryInterface(REFIID, void **); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release();
// Tombstone stub
HRESULT CheckForTombstone();
// Restart an application (such as when global.asa changes)
HRESULT Restart(BOOL fForceRestart = FALSE);
// IApplicationObject functions
STDMETHODIMP Lock(); STDMETHODIMP UnLock(); STDMETHODIMP get_Value(BSTR bstr, VARIANT *pvar); STDMETHODIMP put_Value(BSTR bstr, VARIANT var); STDMETHODIMP putref_Value(BSTR bstr, VARIANT var); STDMETHODIMP get_Contents(IVariantDictionary **ppDictReturn); STDMETHODIMP get_StaticObjects(IVariantDictionary **ppDictReturn);
// Application config related methods
CAppConfig *QueryAppConfig(); BOOL FConfigNeedsUpdate(); HRESULT UpdateConfig(CIsapiReqInfo *pIReq, BOOL *pfRestart = NULL, BOOL *pfFlushAll = NULL);
// inline methods to access member properties
CSessionMgr *PSessionMgr(); CComponentCollection *PCompCol(); CViperActivity *PActivity(); IDebugApplicationNode *PAppRoot(); CTemplate *PGlobalTemplate(); void SetGlobalTemplate(CTemplate *); TCHAR *GetMetabaseKey(); TCHAR *GetApplnPath(SOURCEPATHTYPE = SOURCEPATHTYPE_PHYSICAL); TCHAR *GetGlobalAsa(); DWORD GetNumSessions(); DWORD GetNumRequests(); BOOL FGlobalChanged(); BOOL FDebuggable(); BOOL FTombstone(); BOOL FHasGlobalAsa(); BOOL FFirstRequestRun(); IDispatch *PGlobTypeLibWrapper(); IUnknown *PServicesConfig();
void SetFirstRequestRan(); void SetGlobTypeLibWrapper(IDispatch *); HRESULT AddDirMonitorEntry(CDirMonitorEntry *); HRESULT AddFileApplnEntry(CFileApplnList *pFileAppln);
CASPDirMonitorEntry *FPathMonitored(LPCTSTR pszPath); // Misc inline methods
void InternalLock(); void InternalUnLock(); void IncrementSessionCount(); void DecrementSessionCount(); void IncrementRequestCount(); void DecrementRequestCount();
// AssertValid()
public:
#ifdef DBG
virtual void AssertValid() const; #else
virtual void AssertValid() const {} #endif
// Cache on per-class basis
ACACHE_INCLASS_DEFINITIONS()
// Trace Log info -- keep in both free & checked builds so that ntsd extension will work for both builds
// for FREE build, trace log is always NULL. Checked builds, it must be enabled.
static PTRACE_LOG gm_pTraceLog; };
/*===================================================================
C A p p l n inlines ===================================================================*/
inline CSessionMgr *CAppln::PSessionMgr() { return m_pSessionMgr; }
inline CComponentCollection *CAppln::PCompCol() { return m_pApplCompCol; }
inline CViperActivity *CAppln::PActivity() { return m_pActivity; }
inline IDebugApplicationNode *CAppln::PAppRoot() { return m_pAppRoot; }
inline TCHAR *CAppln::GetMetabaseKey() { return m_pszMetabaseKey; }
inline TCHAR *CAppln::GetApplnPath(SOURCEPATHTYPE pathtype) { return (pathtype == SOURCEPATHTYPE_VIRTUAL? m_pszApplnVRoot : (pathtype == SOURCEPATHTYPE_PHYSICAL? m_pszApplnPath : NULL)); }
inline CTemplate *CAppln::PGlobalTemplate() { return m_pGlobalTemplate; }
inline void CAppln::SetGlobalTemplate(CTemplate *pTemplate) { pTemplate->AddRef(); m_pGlobalTemplate = pTemplate; }
inline TCHAR *CAppln::GetGlobalAsa() { return m_pszGlobalAsa; }
inline DWORD CAppln::GetNumSessions() { return m_cSessions; }
inline DWORD CAppln::GetNumRequests() { return m_cRequests; }
inline BOOL CAppln::FGlobalChanged() { return m_fGlobalChanged; }
inline BOOL CAppln::FDebuggable() { return m_fDebuggable; }
inline BOOL CAppln::FTombstone() { return m_fTombstone; }
inline BOOL CAppln::FHasGlobalAsa() { return (m_pszGlobalAsa != NULL); }
inline BOOL CAppln::FFirstRequestRun() { return m_fFirstRequestRan; }
inline void CAppln::SetFirstRequestRan() { Assert(m_fInited); m_fFirstRequestRan = TRUE; }
inline IDispatch *CAppln::PGlobTypeLibWrapper() { return m_pdispGlobTypeLibWrapper; }
inline IUnknown *CAppln::PServicesConfig() { return m_pServicesConfig; } inline void CAppln::SetGlobTypeLibWrapper(IDispatch *pdisp) { if (m_pdispGlobTypeLibWrapper) m_pdispGlobTypeLibWrapper->Release(); m_pdispGlobTypeLibWrapper = pdisp; if (m_pdispGlobTypeLibWrapper) m_pdispGlobTypeLibWrapper->AddRef(); }
inline void CAppln::IncrementSessionCount() { Assert(m_fInited); InterlockedIncrement((LPLONG)&m_cSessions); } inline void CAppln::DecrementSessionCount() { Assert(m_fInited); InterlockedDecrement((LPLONG)&m_cSessions); }
inline void CAppln::IncrementRequestCount() { Assert(m_fInited); InterlockedIncrement((LPLONG)&m_cRequests); } inline void CAppln::DecrementRequestCount() { Assert(m_fInited); InterlockedDecrement((LPLONG)&m_cRequests); } inline void CAppln::InternalLock() { Assert(m_fInited); EnterCriticalSection(&m_csInternalLock); } inline void CAppln::InternalUnLock() { Assert(m_fInited); LeaveCriticalSection(&m_csInternalLock); }
inline CAppConfig * CAppln::QueryAppConfig() { return m_pAppConfig; }
inline BOOL CAppln::FConfigNeedsUpdate() { return m_pAppConfig->fNeedUpdate(); }
/*===================================================================
C A p p l n M g r ===================================================================*/
class CApplnMgr : public CHashTable { private: // Flags
DWORD m_fInited : 1; // Are we initialized?
DWORD m_fHashTableInited : 1; // Need to UnInit hash table?
DWORD m_fCriticalSectionInited : 1; // Need to delete CS?
// Critical section for locking
CRITICAL_SECTION m_csLock;
// List of script engines that need to be closed on next request.
// (See comments in code, esp. CApplnMgr::AddEngine)
CDblLink m_listEngineCleanup;
public: CApplnMgr(); ~CApplnMgr();
HRESULT Init(); HRESULT UnInit();
// CAppln manipulations
HRESULT AddAppln ( TCHAR *pszApplnKey, TCHAR *pszApplnPath, CIsapiReqInfo *pIReq, HANDLE hUserImpersonation, CAppln **ppAppln ); HRESULT FindAppln ( TCHAR *pszApplnKey, CAppln **ppAppln ); HRESULT DeleteApplicationIfExpired(CAppln *pAppln); HRESULT DeleteAllApplications(); HRESULT RestartApplications(BOOL fRestartAllApplications = FALSE); // Add an engine to the deferred cleanup list/release engines in the list
HRESULT AddEngine(CActiveScriptEngine *pEng); void CleanupEngines();
// inlines
void Lock(); void UnLock(); HANDLE HDeleteEvent(); void SetDeleteEvent(void); };
/*===================================================================
C A p p l n M g r inlines ===================================================================*/
inline void CApplnMgr::Lock() { Assert(m_fInited); EnterCriticalSection(&m_csLock); } inline void CApplnMgr::UnLock() { Assert(m_fInited); LeaveCriticalSection( &m_csLock ); } /*===================================================================
C A p p l n C l e a n u p M g r ===================================================================*/
class CApplnCleanupMgr { private: // Flags
DWORD m_fInited : 1; // Are we initialized?
DWORD m_fCriticalSectionInited : 1; // Need to delete CS?
DWORD m_fThreadAlive : 1; // worker thread alive?
// Critical section for locking
CRITICAL_SECTION m_csLock;
HANDLE m_hAppToCleanup; // event to signal when there is an app to cleanup
CLinkElem m_List;
CAppln *Head(); void AddElem(CAppln *pAppln); void RemoveElem(CAppln *pAppln);
public: CApplnCleanupMgr(); ~CApplnCleanupMgr();
HRESULT Init(); HRESULT UnInit();
// CAppln manipulations
HRESULT AddAppln ( CAppln *ppAppln );
void Wakeup(); private: // inlines
void Lock(); void UnLock();
// thread proc used to cleanup deleted applications
static DWORD __stdcall ApplnCleanupThread(VOID *pArg); void ApplnCleanupDoWork(); };
/*===================================================================
C A p p l n C l e a n u p M g r inlines ===================================================================*/
inline void CApplnCleanupMgr::Lock() { Assert(m_fCriticalSectionInited); EnterCriticalSection(&m_csLock); } inline void CApplnCleanupMgr::UnLock() { Assert(m_fCriticalSectionInited); LeaveCriticalSection( &m_csLock ); }
inline CAppln *CApplnCleanupMgr::Head() { return ((m_List.m_pNext == &m_List) ? NULL : (CAppln *)m_List.m_pNext); } inline void CApplnCleanupMgr::AddElem(CAppln *pAppln) { pAppln->m_pNext = &m_List; pAppln->m_pPrev = m_List.m_pPrev; m_List.m_pPrev->m_pNext = pAppln; m_List.m_pPrev = pAppln; }
inline void CApplnCleanupMgr::RemoveElem(CAppln *pAppln) { pAppln->m_pPrev->m_pNext = pAppln->m_pNext; pAppln->m_pNext->m_pPrev = pAppln->m_pPrev; }
inline void CApplnCleanupMgr::Wakeup() { SetEvent(m_hAppToCleanup); } /*===================================================================
C A p p l n M g r thread proc prototype ===================================================================*/ void __cdecl RestartAppsThreadProc(VOID *arg);
/*===================================================================
Globals ===================================================================*/
extern CApplnMgr g_ApplnMgr; extern DWORD g_nApplications; extern DWORD g_nApplicationsRestarting;
/*===================================================================
C A p p l n I t e r a t o r ===================================================================*/
class CApplnIterator { private: CApplnMgr *m_pApplnMgr; CAppln *m_pCurr; BOOL m_fEnded; // iterator ended
public: CApplnIterator(void); virtual ~CApplnIterator(void);
public: HRESULT Start(CApplnMgr *pApplnMgr = NULL); HRESULT Stop(void); CAppln * Next(void); };
#endif // APPLMGR_H
|