682 lines
18 KiB
C++
682 lines
18 KiB
C++
/*===================================================================
|
|
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
|