Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*===================================================================
Microsoft Denali
Microsoft Confidential. Copyright 1997 Microsoft Corporation. All Rights Reserved.
Component: Viper Integration Objects
File: viperint.h
Owner: DmitryR
This file contains the definiton of viper integration classes ===================================================================*/
#ifndef VIPERINT_H
#define VIPERINT_H
#include "comsvcs.h"
#include "mtxpriv.h"
#include "glob.h"
#include "asptlb.h" // needed to define interface pointers
#include "reftrace.h"
#include "memcls.h"
#define REFTRACE_VIPER_REQUESTS DBG
class CHitObj; // forward decl
/*===================================================================
Transaction Support Types ===================================================================*/ #define TransType DWORD
#define ttUndefined 0x00000000
#define ttNotSupported 0x00000001
#define ttSupported 0x00000002
#define ttRequired 0x00000004
#define ttRequiresNew 0x00000008
/*===================================================================
CViperAsyncRequest class implements IMTSCall interface. Its OnCall() method does HitObj processing. This is a private class used in CViperActivity class ===================================================================*/
class CViperAsyncRequest : public IServiceCall, public IAsyncErrorNotify, public CDblLink { private: LONG m_cRefs; // reference count
CHitObj *m_pHitObj; // request
IServiceActivity *m_pActivity; HRESULT m_hrOnError; DWORD m_dwTimeout:16; DWORD m_dwRepostAttempts:8; DWORD m_fBrowserRequest:1; DWORD m_fTestingConnection:1; DWORD m_fAsyncCallPosted:1; DWORD m_dwLastTestTimeStamp; private: CViperAsyncRequest(); ~CViperAsyncRequest();
HRESULT Init(CHitObj *pHitObj, IServiceActivity *pActivity);
public: BOOL FBrowserRequest() { return m_fBrowserRequest; } CHitObj *PHitObj() { return m_pHitObj; }
DWORD SecsSinceLastTest(); void UpdateTestTimeStamp() { m_dwLastTestTimeStamp = GetTickCount(); }
DWORD dwTimeout() { return m_dwTimeout; };
#if REFTRACE_VIPER_REQUESTS
static PTRACE_LOG gm_pTraceLog; #endif
public: #ifdef DBG
virtual void AssertValid() const; #else
virtual void AssertValid() const {} #endif
public: // IUnknown Methods
STDMETHODIMP QueryInterface(REFIID iid, void **ppv); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release();
// IServiceCall Method
STDMETHODIMP OnCall();
// IAsyncErrorNotify
STDMETHODIMP OnError(HRESULT hr);
BOOL FTestingConnection() { return m_fTestingConnection; } void SetTestingConnection() { m_fTestingConnection = TRUE; } void ClearTestingConnection() { m_fTestingConnection = FALSE; }
BOOL FAsyncCallPosted() { return m_fAsyncCallPosted; } void SetAsyncCallPosted() { m_fAsyncCallPosted = TRUE; } void ClearAsyncCallPosted() { m_fAsyncCallPosted = FALSE; }
friend class CViperActivity;
// Cache on per-class basis
ACACHE_INCLASS_DEFINITIONS() };
extern volatile LONG g_nViperRequests;
/*===================================================================
CViperActivity corresponds to a Session. It creates MTS activity, and launches async requests ===================================================================*/
class CViperActivity { private: IServiceActivity *m_pActivity; DWORD m_cBind; // inited-flag + bind-to-thread count
inline BOOL FInited() const { return (m_cBind > 0); }
public: CViperActivity(); ~CViperActivity();
// Create Viper activity
HRESULT Init(IUnknown *pConfig); // Clone Viper activity
HRESULT InitClone(CViperActivity *pActivity);
// Bind/Unbind
HRESULT BindToThread(); HRESULT UnBindFromThread();
// Release Viper activity
HRESULT UnInit();
// Check if thread-bound
inline BOOL FThreadBound() const { return (m_cBind > 1); }
// Post async request within this activity
HRESULT PostAsyncRequest(CHitObj *pHitObj);
// post async request without an activity
static HRESULT PostGlobalAsyncRequest(CHitObj *pHitObj);
public: #ifdef DBG
virtual void AssertValid() const; #else
virtual void AssertValid() const {} #endif
// Cache on per-class basis
ACACHE_INCLASS_DEFINITIONS()
};
/*===================================================================
Misc. Functions ===================================================================*/
HRESULT ViperAttachIntrinsicsToContext ( IApplicationObject *pAppln, ISessionObject *pSession = NULL, IRequest *pRequest = NULL, IResponse *pResponse = NULL, IServer *pServer = NULL );
HRESULT ViperGetObjectFromContext ( BSTR bstrName, IDispatch **ppdisp );
HRESULT ViperGetHitObjFromContext ( CHitObj **ppHitObj );
HRESULT ViperCreateInstance ( REFCLSID rclsid, REFIID riid, void **ppv );
HRESULT ViperConfigure(); HRESULT ViperConfigureMTA(); HRESULT ViperConfigureSTA();
/*===================================================================
CViperReqManager
This class manages the outstanding CViperAsyncRequest objects. With this class, we can periodically cleanup disconnected requests on the queue. ===================================================================*/
class CViperReqManager { public: CViperReqManager(); ~CViperReqManager() {};
HRESULT Init(); HRESULT UnInit();
HRESULT AddReqObj(CViperAsyncRequest *pReqObj); BOOL RemoveReqObj(CViperAsyncRequest *pReqObj, BOOL fForce = FALSE);
void LockQueue(); void UnlockQueue();
private:
CDblLink m_ReqObjList; DWORD m_dwReqObjs; DWORD m_fCsInited:1; DWORD m_fCsQueueInited:1; DWORD m_fShutdown:1; DWORD m_fDisabled : 1; CRITICAL_SECTION m_csLock; CRITICAL_SECTION m_csQueueLock; DWORD m_dwQueueMin; HANDLE m_hWakeUpEvent; HANDLE m_hThreadAlive; DWORD m_dwLastAwakened; DWORD m_dwQueueAlwaysWakeupMin;
void Lock(); void Unlock(); CViperAsyncRequest *GetNext(CDblLink *pViperReq, BOOL fTestForF5Attack);
void WakeUp(BOOL fForce = FALSE);
static DWORD __stdcall WatchThread(VOID *pArg);
};
extern CViperReqManager g_ViperReqMgr;
/*===================================================================
CViperReqManager - Inlines
===================================================================*/
inline void CViperReqManager::Lock() { Assert(m_fCsInited); EnterCriticalSection(&m_csLock); }
inline void CViperReqManager::Unlock() { LeaveCriticalSection(&m_csLock); }
inline void CViperReqManager::LockQueue() { Assert(m_fCsQueueInited); EnterCriticalSection(&m_csQueueLock); }
inline void CViperReqManager::UnlockQueue() { LeaveCriticalSection(&m_csQueueLock); }
inline void CViperReqManager::WakeUp(BOOL fForce /* = FALSE */) { // set the wakeup event under any of the three conditions:
// 1) fForce is true (set when shutting down)
// 2) requests queued exceed level that will always force wakeup
// 3) not at the force level of requests, but have some queueing and
// haven't awakened for at least one second
if (fForce || (m_dwReqObjs >= m_dwQueueAlwaysWakeupMin) || ((m_dwReqObjs >= m_dwQueueMin) && (GetTickCount()/1000 > m_dwLastAwakened))) SetEvent(m_hWakeUpEvent); }
/*===================================================================
COM Helper API ===================================================================*/
BOOL ViperCoObjectIsaProxy ( IUnknown *pUnk );
BOOL ViperCoObjectAggregatesFTM ( IUnknown *pUnk );
#endif // VIPERINT
|