/*=================================================================== Microsoft Denali Microsoft Confidential. Copyright 1996 Microsoft Corporation. All Rights Reserved. Component: Hit Object File: Hitobj.h Owner: PramodD This is the Hit Object header file. ===================================================================*/ #ifndef HITOBJ_H #define HITOBJ_H #include "Compcol.h" #include "Sessmgr.h" #include "Applmgr.h" #include "Context.h" #include "aspresource.h" #include "exec.h" #include "glob.h" #include "memcls.h" #include "gip.h" #include "txnsup.h" #define SESSIONID_LEN 24 // HitObj type #define EHitType DWORD #define ehtUnInitedRequest 0x00000000 #define ehtBrowserRequest 0x00000001 #define ehtSessionCleanup 0x00000002 #define ehtApplicationCleanup 0x00000004 // Execution status (result) #define EExecStatus DWORD #define eExecFailed 0x00000000 #define eExecSucceeded 0x00000001 #define eExecTimedOut 0x00000002 // Current execution state #define EEventState DWORD #define eEventNone 0x00000000 #define eEventAppOnStart 0x00000001 #define eEventSesOnStart 0x00000002 #define eEventAppOnEnd 0x00000004 #define eEventSesOnEnd 0x00000008 // Global interface table extern IGlobalInterfaceTable *g_pGIT; extern LONG g_nRequestsHung; /*=================================================================== C H i t O b j The Hit Manager runs in the context of an IIS thread. It packages up a request, calls Viper async. and on callback executes the request ===================================================================*/ class CHitObj { private: // Flags and other bit-fields DWORD m_fInited : 1; // Are we initialized? DWORD m_fRunGlobalAsa : 1; // Should we run global.asa DWORD m_fStartSession : 1; // New session DWORD m_fNewCookie : 1; // Is New session cookie? DWORD m_fStartApplication : 1; // New application DWORD m_fClientCodeDebug : 1; // Client code debug enabled? DWORD m_fApplnOnStartFailed : 1; // Application_OnStart failed DWORD m_fCompilationFailed : 1; // Script Compilation error? DWORD m_fExecuting : 1; // Currently inside Viper callback DWORD m_fHideRequestAndResponseIntrinsics : 1; // TRUE while instrinsics are hidden DWORD m_fHideSessionIntrinsic : 1; // TRUE if session intrinsic's hidden DWORD m_fDoneWithSession : 1; // TRUE after DONE_WITH_SESSION DWORD m_fRejected : 1; // TRUE if rejected (not posted) DWORD m_f449Done : 1; // 449 processing done for this request DWORD m_fInTransferOnError : 1; // doing transfer on error (to break infinite) DWORD m_fSecure : 1; // Secure Connection EHitType m_ehtType : 4; // Type of the request EExecStatus m_eExecStatus : 4; // Error Status // for Perf Counter only EEventState m_eEventState : 4; // Current Event CompScope m_ecsActivityScope : 4; // Which activity running this request? LONG m_fRequestTimedout; // true if request exceeded its timeout // Intrinsics set from inside HitObj CSession *m_pSession; CAppln *m_pAppln; CResponse *m_pResponse; CRequest *m_pRequest; CServer *m_pServer; CASPObjectContext *m_pASPObjectContext; // IsapiReqInfo CIsapiReqInfo *m_pIReq; // Intrinsics set from outside HitObj (to be ref. counted) IUnknown *m_punkScriptingNamespace; // Component collection of extrinsic objects CComponentCollection *m_pPageCompCol; CPageComponentManager *m_pPageObjMgr; // Impersonation handle HANDLE m_hImpersonate; // Viper page-level activity (if no session) CViperActivity *m_pActivity; // Current session info char m_szSessionCookie[SESSIONID_LEN+4]; // +4 to keep DWORD boundary CSessionId m_SessionId; // Context object (for OnStartPage) CScriptingContext * m_pScriptingContext; // Misc long m_nScriptTimeout; // Maximum number of seconds script should run UINT m_uCodePage; // RunTime CodePage LCID m_lcid; // RunTime LCID ActiveEngineInfo *m_pEngineInfo; // List of active engines for this hit objext IDispatch *m_pdispTypeLibWrapper; // Page-level typelib wrapper DWORD m_dwtTimestamp; // Timestamp for wait time and perf calcs // Used to reffer to the current template during the compilation TCHAR *m_szCurrTemplatePhysPath; TCHAR *m_szCurrTemplateVirtPath; // ASP Error object IASPError *m_pASPError; // Store a pointer to the associated template so as to avoid redundant // FindTemplate calls. CTemplate *m_pTemplate; // Private interfaces HRESULT ParseCookiesForSessionIdAndFlags(); // Request rejection logic HRESULT RejectBrowserRequestWhenNeeded(DWORD dwtQueueWaitTime, BOOL *pfRejected); // Public Interfaces public: CHitObj(); virtual ~CHitObj(); static HRESULT NewBrowserRequest(CIsapiReqInfo *pIReq, BOOL *pfRejected = NULL, BOOL *pfCompleted = NULL, int *piErrorId = NULL); HRESULT BrowserRequestInit(CIsapiReqInfo *pIReq, int * dwId); HRESULT AssignApplnToBrowserRequest(BOOL *pfApplnRestarting); HRESULT AssignSessionToBrowserRequest(BOOL *pfNewSession, BOOL *pfNewCookie, int *pErrorId); HRESULT DetachBrowserRequestFromSession(); HRESULT ReassignAbandonedSession(); void SessionCleanupInit(CSession *pSession); void ApplicationCleanupInit(CAppln *pAppln); BOOL SendHeader(const char *szStatus); BOOL SendError(const char *szError); TCHAR* GetSzAppPhysicalPath(void); void ApplnOnStartFailed(); void SessionOnStartFailed(); void SessionOnStartInvoked(); void SessionOnEndPresent(); void SetEventState(EEventState eEvent); EEventState EventState(); // Report server error without response object HRESULT ReportServerError(UINT ErrorId); // Component Collection Interfaces HRESULT InitComponentProcessing(); HRESULT StopComponentProcessing(); HRESULT GetPageComponentCollection(CComponentCollection **ppCollection); HRESULT GetSessionComponentCollection(CComponentCollection **ppCollection); HRESULT GetApplnComponentCollection(CComponentCollection **ppCollection); HRESULT AddComponent(CompType type, const CLSID &clsid, CompScope scope, CompModel model, LPWSTR pwszName = NULL, IUnknown *pUnk = NULL); HRESULT GetComponent(CompScope scope, LPWSTR pwszName, DWORD cbName, CComponentObject **ppObj); HRESULT GetIntrinsic(LPWSTR pwszName, DWORD cbName, IUnknown **ppUnk); HRESULT CreateComponent(const CLSID &clsid, IDispatch **ppDisp); HRESULT SetPropertyComponent(CompScope scope, LPWSTR pwszName, VARIANT *pVariant); HRESULT GetPropertyComponent(CompScope scope, LPWSTR pwszName, CComponentObject **ppObj); // Viper Integration CViperActivity *PActivity(); CViperActivity *PCurrentActivity(); HRESULT SetActivity(CViperActivity *pActivity); HRESULT PostViperAsyncCall(); HRESULT ViperAsyncCallback(BOOL *pfRePosted); // Execute / Transfer HRESULT ExecuteChildRequest(BOOL fTransfer, TCHAR *szTemplate, TCHAR *szVirtTemplate); HRESULT GetASPError(IASPError **ppASPError); inline void SetASPError(IASPError *pASPError); inline BOOL FHasASPError(); // inline functions public: CIsapiReqInfo *PIReq(); HANDLE HImpersonate(); CResponse * PResponse(); CRequest * PRequest(); CServer * PServer(); CAppln * PAppln(); CSession * PSession(); CASPObjectContext *PASPObjectContext(); CASPObjectContext *SetASPObjectContext(CASPObjectContext *); CPageComponentManager * PPageComponentManager(); BOOL FIsBrowserRequest() const; BOOL FIsSessionCleanupRequest() const; BOOL FIsApplnCleanupRequest() const; BOOL FIsValidRequestType() const; const char * PSzNewSessionCookie() const; DWORD SessionId() const; CScriptingContext * PScriptingContextGet(); BOOL FStartApplication(); BOOL FStartSession(); BOOL FNewCookie(); BOOL FObjectTag(IDispatch * pDispatch); BOOL FHasSession(); BOOL FClientCodeDebug(); BOOL FDoneWithSession(); BOOL FExecuting(); void SetFExecuting(BOOL fValue); BOOL F449Done(); BOOL FInTransferOnError(); BOOL FSecure(); void SetScriptTimeout(long nScriptTimeout); long GetScriptTimeout(); void SetExecStatus(EExecStatus status); EExecStatus ExecStatus(); void SetActiveEngineInfo(ActiveEngineInfo *); void SetCompilationFailed(); void SetDoneWithSession(); void Set449Done(); void SetInTransferOnError(); void SetRequestTimedout(); TCHAR * GlobalAspPath(); HRESULT SetCodePage(UINT uCodePage); // Proxy function, CodePage is stored in m_pSession UINT GetCodePage(); // same as above HRESULT SetLCID(LCID lcid); // Proxy function, LCID is stored in m_pSession LCID GetLCID(); // same as above CAppConfig * QueryAppConfig(); TCHAR * PSzCurrTemplatePhysPath(); TCHAR * PSzCurrTemplateVirtPath(); DWORD DWInstanceID(); CTemplate *GetTemplate(); void SetTemplate(CTemplate *); // Instead of add/remove to/from component collection use these: void HideRequestAndResponseIntrinsics(); void UnHideRequestAndResponseIntrinsics(); BOOL FRequestAndResponseIntrinsicsHidden(); void AddScriptingNamespace(IUnknown *punkNamespace); void RemoveScriptingNamespace(); // Typelib wrapper support IDispatch *PTypeLibWrapper(); void SetTypeLibWrapper(IDispatch *pdisp); // Timestamp manipulation void UpdateTimestamp(); DWORD ElapsedTimeSinceTimestamp(); #ifdef DBG virtual void AssertValid() const; #else virtual void AssertValid() const {} #endif // Cache on per-class basis ACACHE_INCLASS_DEFINITIONS() }; /*=================================================================== CHitObj inlines ===================================================================*/ inline CIsapiReqInfo *CHitObj::PIReq() { return m_pIReq; } inline BOOL CHitObj::FIsBrowserRequest() const { return (m_ehtType == ehtBrowserRequest); } inline BOOL CHitObj::FIsSessionCleanupRequest() const { return (m_ehtType == ehtSessionCleanup); } inline BOOL CHitObj::FIsApplnCleanupRequest() const { return (m_ehtType == ehtApplicationCleanup); } inline BOOL CHitObj::FIsValidRequestType() const { return (FIsBrowserRequest() || FIsSessionCleanupRequest() || FIsApplnCleanupRequest()); } inline HANDLE CHitObj::HImpersonate() { return m_hImpersonate; } inline DWORD CHitObj::SessionId() const { return m_SessionId.m_dwId; } inline const char *CHitObj::PSzNewSessionCookie() const { return (m_fNewCookie ? m_szSessionCookie : NULL); } inline BOOL CHitObj::FStartApplication() { return m_fStartApplication; } inline BOOL CHitObj::FStartSession() { return m_fStartSession; } inline BOOL CHitObj::FNewCookie() { return m_fNewCookie; } inline BOOL CHitObj::FHasSession() { return (m_pSession != NULL && !m_fHideSessionIntrinsic); } inline BOOL CHitObj::FClientCodeDebug() { return m_fClientCodeDebug; } inline BOOL CHitObj::FDoneWithSession() { return m_fDoneWithSession; } inline BOOL CHitObj::FExecuting() { return m_fExecuting; } inline void CHitObj::SetFExecuting(BOOL fValue) { m_fExecuting = fValue; } inline BOOL CHitObj::F449Done() { return m_f449Done; } inline BOOL CHitObj::FInTransferOnError() { return m_fInTransferOnError; } inline BOOL CHitObj::FSecure() { return m_fSecure; } inline void CHitObj::SessionOnStartFailed() { Assert(m_pSession); m_pSession->SetOnStartFailedFlag(); } inline void CHitObj::ApplnOnStartFailed() { m_fApplnOnStartFailed = TRUE; if (m_pSession) SessionOnStartFailed(); } inline void CHitObj::SessionOnStartInvoked() { Assert(m_pSession); m_pSession->SetOnStartInvokedFlag(); } inline void CHitObj::SessionOnEndPresent() { Assert(m_pSession); m_pSession->SetOnEndPresentFlag(); } inline DWORD CHitObj::DWInstanceID() { return (m_pIReq) ? m_pIReq->QueryInstanceId() : 0; } inline CViperActivity *CHitObj::PActivity() { return m_pActivity; } inline CScriptingContext *CHitObj::PScriptingContextGet() { return m_pScriptingContext; } inline CResponse *CHitObj::PResponse() { return m_pResponse; } inline CRequest *CHitObj::PRequest() { return m_pRequest; } inline CServer *CHitObj::PServer() { return m_pServer; } inline CAppln *CHitObj::PAppln() { return m_pAppln; } inline CSession *CHitObj::PSession() { return m_pSession; } inline CASPObjectContext *CHitObj::PASPObjectContext() { return m_pASPObjectContext; } inline CASPObjectContext *CHitObj::SetASPObjectContext(CASPObjectContext *pContext) { CASPObjectContext *pPoppedContext = m_pASPObjectContext; m_pASPObjectContext = pContext; return pPoppedContext; } inline CPageComponentManager *CHitObj::PPageComponentManager() { return m_pPageObjMgr; } inline TCHAR *CHitObj::GlobalAspPath() { if ( m_fRunGlobalAsa ) return m_pAppln->GetGlobalAsa(); else return NULL; } inline void CHitObj::SetScriptTimeout(long nScriptTimeout) { m_nScriptTimeout = nScriptTimeout; } inline long CHitObj::GetScriptTimeout() { return m_nScriptTimeout; } inline void CHitObj::SetExecStatus(EExecStatus status) { m_eExecStatus = status; } inline EExecStatus CHitObj::ExecStatus() { return m_eExecStatus; } inline EEventState CHitObj::EventState() { return m_eEventState; } inline void CHitObj::SetEventState(EEventState eState) { m_eEventState = eState; } inline CAppConfig * CHitObj::QueryAppConfig(void) { return m_pAppln->QueryAppConfig(); } inline UINT CHitObj::GetCodePage(void) { return m_uCodePage == 0 ? GetACP() : m_uCodePage; } inline LCID CHitObj::GetLCID() { return m_lcid; } inline VOID CHitObj::SetActiveEngineInfo(ActiveEngineInfo *pActiveEngineInfo) { m_pEngineInfo = pActiveEngineInfo; } inline void CHitObj::SetCompilationFailed() { m_fCompilationFailed = TRUE; } inline void CHitObj::SetDoneWithSession() { Assert(!m_fDoneWithSession); m_fDoneWithSession = TRUE; } inline void CHitObj::Set449Done() { Assert(!m_f449Done); m_f449Done = TRUE; } inline void CHitObj::SetInTransferOnError() { Assert(!m_fInTransferOnError); m_fInTransferOnError = TRUE; } inline void CHitObj::SetRequestTimedout() { LONG fPrev = InterlockedExchange(&m_fRequestTimedout, 1); if (fPrev == 0) { InterlockedIncrement(&g_nRequestsHung); } } inline void CHitObj::HideRequestAndResponseIntrinsics() { m_fHideRequestAndResponseIntrinsics = TRUE; } inline void CHitObj::UnHideRequestAndResponseIntrinsics() { m_fHideRequestAndResponseIntrinsics = FALSE; } inline BOOL CHitObj::FRequestAndResponseIntrinsicsHidden() { return m_fHideRequestAndResponseIntrinsics; } inline void CHitObj::AddScriptingNamespace(IUnknown *punkNamespace) { Assert(m_punkScriptingNamespace == NULL); Assert(punkNamespace); m_punkScriptingNamespace = punkNamespace; m_punkScriptingNamespace->AddRef(); } inline void CHitObj::RemoveScriptingNamespace() { if (m_punkScriptingNamespace) { m_punkScriptingNamespace->Release(); m_punkScriptingNamespace = NULL; } } inline IDispatch *CHitObj::PTypeLibWrapper() { return m_pdispTypeLibWrapper; } inline void CHitObj::SetTypeLibWrapper(IDispatch *pdisp) { if (m_pdispTypeLibWrapper) m_pdispTypeLibWrapper->Release(); m_pdispTypeLibWrapper = pdisp; if (m_pdispTypeLibWrapper) m_pdispTypeLibWrapper->AddRef(); } inline void CHitObj::UpdateTimestamp() { m_dwtTimestamp = GetTickCount(); } inline DWORD CHitObj::ElapsedTimeSinceTimestamp() { DWORD dwt = GetTickCount(); if (dwt >= m_dwtTimestamp) return (dwt - m_dwtTimestamp); else return ((0xffffffff - m_dwtTimestamp) + dwt); } inline TCHAR *CHitObj::PSzCurrTemplatePhysPath() { if (m_szCurrTemplatePhysPath != NULL) return m_szCurrTemplatePhysPath; else if (m_pIReq != NULL) return m_pIReq->QueryPszPathTranslated(); else return NULL; } inline TCHAR *CHitObj::PSzCurrTemplateVirtPath() { if (m_szCurrTemplateVirtPath != NULL) return m_szCurrTemplateVirtPath; else if (m_pIReq != NULL) return m_pIReq->QueryPszPathInfo(); else return NULL; } inline void CHitObj::SetASPError(IASPError *pASPError) { if (m_pASPError) m_pASPError->Release(); m_pASPError = pASPError; // passed addref'd } inline BOOL CHitObj::FHasASPError() { return (m_pASPError != NULL); } inline CTemplate *CHitObj::GetTemplate() { return m_pTemplate; } inline void CHitObj::SetTemplate(CTemplate *pTemplate) { m_pTemplate = pTemplate; } /*=================================================================== Globals ===================================================================*/ extern DWORD g_nBrowserRequests; extern DWORD g_nSessionCleanupRequests; extern DWORD g_nApplnCleanupRequests; #undef SCRIPT_STATS #ifdef SCRIPT_STATS # include void ReadRegistrySettings(); extern CSmallSpinLock g_lockRequestStats; extern DWORD g_dwQueueDebugThreshold; extern DWORD g_fSendScriptlessOnAtqThread; extern LONG g_cRequests; extern LONG g_cScriptlessRequests; extern LONG g_cHttpExtensionsExecuting; extern LONG g_cConcurrentScriptlessRequests; extern LONG g_cMaxConcurrentScriptlessRequests; extern LONGLONG g_nSumConcurrentScriptlessRequests; extern LONGLONG g_nSumExecTimeScriptlessRequests; extern LONG g_nAvgConcurrentScriptlessRequests; extern LONG g_nAvgExecTimeScriptlessRequests; #endif // SCRIPT_STATS #endif // HITOBJ_H