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.
 
 
 
 
 
 

539 lines
11 KiB

/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
wam_process.hxx
Abstract:
WAM process management for ISAPI
Author:
Wade Hilmo (wadeh) 10-Oct-2000
Revision History:
--*/
#ifndef _WAM_PROCESS_HXX_
#define _WAM_PROCESS_HXX_
#include "precomp.hxx"
#include <w3isapi.h>
#include "isapi_request.hxx"
#include "iwam.h"
#include <comadmin.h>
#define POOL_WAM_CLSID L"{99169CB1-A707-11d0-989D-00C04FD919C1}"
#define DEFAULT_RECOVER_LIMIT 5
#define MAX_MESSAGE_TEXT 2048
class ISAPI_REQUEST;
class WAM_PROCESS_MANAGER;
class WAM_CRASH_RECORD
{
public:
WCHAR szClsid[SIZE_CLSID_STRING];
DWORD dwNumCrashes;
LIST_ENTRY leCrashHistory;
WAM_CRASH_RECORD()
: dwNumCrashes( 0 )
{
InitializeListHead( &leCrashHistory );
}
};
class WAM_PROCESS
{
public:
WAM_PROCESS(
LPCWSTR szWamClsid,
WAM_PROCESS_MANAGER * pWamProcessManager,
LPCSTR szIsapiHandlerInstance
);
HRESULT WAM_PROCESS::Create(
LPCWSTR szApplMdPathW
);
LONG AddRef()
{
return InterlockedIncrement( &_cRefs );
}
LONG Release()
{
LONG lRet;
lRet = InterlockedDecrement( &_cRefs );
if ( lRet == 0 )
{
delete this;
}
return lRet;
}
HRESULT ProcessRequest(
ISAPI_REQUEST * pIsapiRequest,
ISAPI_CORE_DATA * pIsapiCoreData,
DWORD * pdwHseResult
);
HRESULT ProcessCompletion(
ISAPI_REQUEST * pIsapiRequest,
DWORD64 IsapiContext,
DWORD cbCompletion,
DWORD dwCompletionStatus
);
VOID DecrementRequestCount(
VOID
);
VOID HandleCrash(
VOID
);
HRESULT Disable(
BOOL fRemoveFromProcessHash = TRUE
);
HRESULT CleanupRequests(
DWORD dwDrainTime
);
HRESULT Shutdown(
VOID
);
HRESULT Unload(
DWORD dwDrainTime
);
LPCWSTR QueryClsid(
VOID
) const
{
return _szWamClsid;
}
HANDLE QueryProcess(
VOID
)
{
return _hProcess;
}
BOOL QueryCrashed(
VOID
)
{
return _fCrashed;
}
HRESULT
MarshalAsyncReadBuffer(
DWORD64 pWamExecInfo,
LPBYTE pBuffer,
DWORD cbBuffer
)
{
return _pIWam->WamMarshalAsyncReadBuffer( pWamExecInfo, pBuffer,
cbBuffer );
}
VOID
AddIsapiRequestToList(
ISAPI_REQUEST * pIsapiRequest
);
VOID
RemoveIsapiRequestFromList(
ISAPI_REQUEST * pIsapiRequest
);
LIST_ENTRY _leProcess;
private:
VOID
LockRequestList()
{
EnterCriticalSection( &_csRequestList );
}
VOID
UnlockRequestList()
{
LeaveCriticalSection( &_csRequestList );
}
VOID
DisconnectIsapiRequests(
VOID
);
~WAM_PROCESS();
WCHAR _szWamClsid[SIZE_CLSID_STRING];
CHAR _szIsapiHandlerInstance[SIZE_CLSID_STRING];
LONG _cRefs;
LONG _cCurrentRequests;
LONG _cTotalRequests;
LONG _cMaxRequests;
IWam * _pIWam;
LIST_ENTRY _RequestListHead;
CRITICAL_SECTION _csRequestList;
WAM_PROCESS_MANAGER * _pWamProcessManager;
DWORD _dwProcessId;
BSTR _bstrInstanceId;
HANDLE _hProcess;
LONG _fGoingAway;
STRU _strApplMdPathW;
BOOL _fCrashed;
};
class WAM_PROCESS_HASH
: public CTypedHashTable<
WAM_PROCESS_HASH,
WAM_PROCESS,
LPCWSTR >
{
public:
WAM_PROCESS_HASH()
: CTypedHashTable< WAM_PROCESS_HASH,
WAM_PROCESS,
LPCWSTR > ( "WAM_PROCESS_HASH" )
{
}
static
LPCWSTR
ExtractKey(
const WAM_PROCESS * pWamProcess
)
{
return pWamProcess->QueryClsid();
}
static
DWORD
CalcKeyHash(
LPCWSTR szKey
)
{
int cchKey = (int)wcslen( szKey );
return HashStringNoCase( szKey, cchKey );
}
static
bool
EqualKeys(
LPCWSTR szKey1,
LPCWSTR szKey2
)
{
return _wcsicmp( szKey1, szKey2 ) == 0;
}
static
void
AddRefRecord(
WAM_PROCESS * pEntry,
int nIncr
)
{
if ( nIncr == +1 )
{
pEntry->AddRef();
}
else if ( nIncr == -1 )
{
pEntry->Release();
}
}
private:
//
// Avoid c++ errors
//
WAM_PROCESS_HASH( const WAM_PROCESS_HASH & )
: CTypedHashTable< WAM_PROCESS_HASH,
WAM_PROCESS,
LPCWSTR > ( "WAM_PROCESS_HASH" )
{
}
WAM_PROCESS_HASH & operator = ( const WAM_PROCESS_HASH & ) { return *this; }
};
class WAM_APP_INFO
{
public:
WAM_APP_INFO(
LPWSTR szAppPath,
LPWSTR szClsid,
DWORD dwAppIsolated
)
: _cRefs( 1 ),
_dwAppIsolated( dwAppIsolated )
{
wcsncpy( _szAppPath, szAppPath, MAX_PATH );
wcsncpy( _szClsid, szClsid, SIZE_CLSID_STRING );
}
VOID
AddRef(
VOID
)
{
InterlockedIncrement( &_cRefs );
}
VOID
Release(
VOID
)
{
LONG cRefs;
cRefs = InterlockedDecrement( &_cRefs );
if ( cRefs == 0 )
{
delete this;
}
}
DWORD _dwAppIsolated;
WCHAR _szClsid[SIZE_CLSID_STRING];
WCHAR _szAppPath[MAX_PATH];
DWORD _dwAppOopRecoverLimit;
private:
LONG _cRefs;
};
class WAM_PROCESS_MANAGER
{
public:
WAM_PROCESS_MANAGER( LPWSTR szIsapiModule )
: _cRefs( 1 ),
_pCatalog( NULL )
{
DBG_ASSERT( szIsapiModule );
INITIALIZE_CRITICAL_SECTION( &_csWamHashLock );
INITIALIZE_CRITICAL_SECTION( &_csCrashHistoryLock );
InitializeListHead( &_CrashHistoryList );
wcsncpy( _szIsapiModule, szIsapiModule, MAX_PATH );
}
HRESULT
WAM_PROCESS_MANAGER::Create(
VOID
);
HRESULT
GetWamProcess(
LPCWSTR szWamClsid,
LPCWSTR szApplMdPathW,
DWORD * pdwWamSubError,
WAM_PROCESS ** ppWamProcess,
LPCSTR szIsapiHandlerInstance
);
HRESULT
GetWamProcessInfo(
LPCWSTR szAppPath,
WAM_APP_INFO ** ppWamAppInfo,
BOOL * pfIsLoaded
);
HRESULT
RemoveWamProcessFromHash(
WAM_PROCESS * pWamProcess
);
static
LK_PREDICATE
UnloadWamProcess(
WAM_PROCESS * pWamProcess,
void * pvState
);
HRESULT
Shutdown(
VOID
);
ICOMAdminCatalog2 *
QueryCatalog(
VOID
)
{
return _pCatalog;
}
VOID
LockWamProcessHash()
{
EnterCriticalSection( &_csWamHashLock );
}
VOID
UnlockWamProcessHash()
{
LeaveCriticalSection( &_csWamHashLock );
}
LONG AddRef()
{
return InterlockedIncrement( &_cRefs );
}
LONG Release()
{
LONG cRefs = InterlockedDecrement( &_cRefs );
if ( cRefs == 0 )
{
delete this;
return 0;
}
return cRefs;
}
LPWSTR
QueryIsapiModule(
VOID
)
{
DBG_ASSERT( _szIsapiModule[0] != L'\0' );
return _szIsapiModule;
}
VOID
RegisterCrash(
LPCWSTR szWamClsid
);
HRESULT
QueryCrashHistory(
LPCWSTR szWamClsid,
DWORD * pdwNumCrashes
);
private:
//
// Avoid c++ errors
//
WAM_PROCESS_MANAGER( const WAM_PROCESS_MANAGER & ) {}
WAM_PROCESS_MANAGER & operator = ( const WAM_PROCESS_MANAGER & ) { return *this; }
~WAM_PROCESS_MANAGER()
{
LIST_ENTRY * pleTemp;
WAM_CRASH_RECORD * pWamCrashRecord;
//
// Delete the WAM crash history. It's not necessary
// to lock the list because if WAM_PROCESS_MANAGER is
// getting destroyed, then there had better not be
// any requests alive that are holding references
// to the entries.
//
while ( !IsListEmpty( &_CrashHistoryList ) )
{
pleTemp = RemoveHeadList( &_CrashHistoryList );
pWamCrashRecord = CONTAINING_RECORD(
pleTemp,
WAM_CRASH_RECORD,
leCrashHistory
);
DBG_ASSERT( pWamCrashRecord );
delete pWamCrashRecord;
pWamCrashRecord = NULL;
}
//
// Release the COM catalog
//
if ( _pCatalog )
{
_pCatalog->Release();
}
//
// Cleanup the hash lock (the hash itself will
// get cleaned up automatically).
//
DeleteCriticalSection( &_csWamHashLock );
DeleteCriticalSection( &_csCrashHistoryLock );
IF_DEBUG( ISAPI )
{
DBGPRINTF((
DBG_CONTEXT,
"WAM_PROCESS_MANAGER %p has been destroyed.\r\n",
this
));
}
}
VOID
LockCrashHistoryList(
VOID
)
{
EnterCriticalSection( &_csCrashHistoryLock );
}
VOID
UnlockCrashHistoryList(
VOID
)
{
LeaveCriticalSection( &_csCrashHistoryLock );
}
WAM_PROCESS_HASH _WamProcessHash;
CRITICAL_SECTION _csWamHashLock;
CRITICAL_SECTION _csCrashHistoryLock;
ICOMAdminCatalog2 * _pCatalog;
LONG _cRefs;
WCHAR _szIsapiModule[MAX_PATH];
LIST_ENTRY _CrashHistoryList;
};
#endif // _WAM_PROCESS_HXX