|
|
/*++
Copyright (c) 1995-1997 Microsoft Corporation
Module Name : wam.cpp
Abstract: This module implements the exported routines for WAM object
Author: David Kaplan ( DaveK ) 26-Feb-1997 Wade Hilmo ( WadeH ) 08-Sep-2000
Environment: User Mode - Win32
Project: Wam DLL
--*/
//
// Following are the notes from the original MSDEV generated file
// Note: Proxy/Stub Information
// To merge the proxy/stub code into the object DLL, add the file
// dlldatax.c to the project. Make sure precompiled headers
// are turned off for this file, and add _MERGE_PROXYSTUB to the
// defines for the project.
//
// If you are not running WinNT4.0 or Win95 with DCOM, then you
// need to remove the following define from dlldatax.c
// #define _WIN32_WINNT 0x0400
//
// Further, if you are running MIDL without /Oicf switch, you also
// need to remove the following define from dlldatax.c.
// #define USE_STUBLESS_PROXY
//
// Modify the custom build rule for Wam.idl by adding the following
// files to the Outputs.
// Wam_p.c
// dlldata.c
// To build a separate proxy/stub DLL,
// run nmake -f Wamps.mk in the project directory.
// BEGIN mods
// Post-wizard mods appear within BEGIN mods ... END mods
// END mods
#include "precomp.hxx"
#include <w3isapi.h>
#include <isapi_context.hxx>
#include "wamobj.hxx"
#include "IWam_i.c"
#include "wamccf.hxx"
#include <atlbase.h>
// BEGIN mods
#ifdef _ATL_STATIC_REGISTRY
#include <statreg.h>
#include <statreg.cpp>
#endif
#include <atlimpl.cpp>
// END mods
/************************************************************
* Global Variables ************************************************************/
const CHAR g_pszModuleName[] = "WAM"; const CHAR g_pszWamRegLocation[] = "System\\CurrentControlSet\\Services\\W3Svc\\WAM";
HMODULE WAM::sm_hIsapiModule; PFN_ISAPI_TERM_MODULE WAM::sm_pfnTermIsapiModule; PFN_ISAPI_PROCESS_REQUEST WAM::sm_pfnProcessIsapiRequest; PFN_ISAPI_PROCESS_COMPLETION WAM::sm_pfnProcessIsapiCompletion;
#ifdef _MERGE_PROXYSTUB
extern "C" HINSTANCE hProxyDll; #endif
BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_Wam, WAM) END_OBJECT_MAP()
// BEGIN mods
WAM_CCF_MODULE _WAMCCFModule;
DECLARE_PLATFORM_TYPE(); DECLARE_DEBUG_VARIABLE(); DECLARE_DEBUG_PRINTS_OBJECT(); // END mods
/************************************************************
* Type Definitions ************************************************************/ // BUGBUG
#undef INET_INFO_KEY
#undef INET_INFO_PARAMETERS_KEY
//
// Configuration parameters registry key.
//
#define INET_INFO_KEY \
"System\\CurrentControlSet\\Services\\iisw3adm"
#define INET_INFO_PARAMETERS_KEY \
INET_INFO_KEY "\\Parameters"
const CHAR g_pszWpRegLocation[] = INET_INFO_PARAMETERS_KEY "\\WP";
class DEBUG_WRAPPER {
public: DEBUG_WRAPPER( IN LPCSTR pszModule ) { #if DBG
CREATE_DEBUG_PRINT_OBJECT( pszModule ); #else
UNREFERENCED_PARAMETER( pszModule ); #endif
LOAD_DEBUG_FLAGS_FROM_REG_STR( g_pszWpRegLocation, DEBUG_ERROR ); }
~DEBUG_WRAPPER(void) { DELETE_DEBUG_PRINT_OBJECT(); } };
class CWamModule _Module;
/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { DWORD dwErr = NO_ERROR;
#ifdef _MERGE_PROXYSTUB
if (!PrxDllMain(hInstance, dwReason, lpReserved)) return FALSE; #endif
if (dwReason == DLL_PROCESS_ATTACH) {
//
// BEGIN mods
//
// From ATL generated
_Module.Init(ObjectMap, hInstance); DisableThreadLibraryCalls(hInstance); // End of ATL generated
_WAMCCFModule.Init();
// END mods
} else if (dwReason == DLL_PROCESS_DETACH) { if ( NULL != lpReserved ) { //
// Only cleanup if there is a FreeLibrary() call
//
return ( TRUE); } _WAMCCFModule.Term(); _Module.Term();
// BEGIN mods
DELETE_DEBUG_PRINT_OBJECT(); // END mods
}
return (dwErr == NO_ERROR); } // DllMain()
/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void) { #ifdef _MERGE_PROXYSTUB
if (PrxDllCanUnloadNow() != S_OK) return S_FALSE; #endif
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE; }
/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { HRESULT hr;
if (ppv == NULL) { return ( NULL); } *ppv = NULL; // reset the value before getting inside.
if (ppv == NULL) { return ( E_POINTER); } *ppv = NULL; // set the incoming value to be invalid entry
#ifdef _MERGE_PROXYSTUB
if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK) return S_OK; #endif
hr = _WAMCCFModule.GetClassObject(rclsid, riid, ppv);
// BEGIN mods
if (hr == CLASS_E_CLASSNOTAVAILABLE) { // If request for standard CF failed -> try custom
hr = _Module.GetClassObject(CLSID_Wam, riid, ppv); } // END mods
return ( hr);
} // DllGetClassObject()
/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void) { #ifdef _MERGE_PROXYSTUB
HRESULT hRes = PrxDllRegisterServer(); if (FAILED(hRes)) return hRes; #endif
// registers object, typelib and all interfaces in typelib
return _Module.RegisterServer(TRUE); }
/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void) { #ifdef _MERGE_PROXYSTUB
PrxDllUnregisterServer(); #endif
_Module.UnregisterServer(); return S_OK; }
HRESULT WAM::WamProcessIsapiRequest( BYTE *pCoreData, DWORD cbCoreData, IIsapiCore *pIsapiCore, DWORD *pdwHseResult ) /*++
Routine Description:
Processes an ISAPI request
Arguments:
pCoreData - The core data from the server for the request cbCoreData - The size of pCoreData pIsapiCore - The IIsapiCore interface pointer for this request pdwHseResult - Upon return, contains the return from HttpExtensionProc
Return Value:
HRESULT
--*/ { HRESULT hr = NOERROR;
pIsapiCore->AddRef();
hr = sm_pfnProcessIsapiRequest( pIsapiCore, (ISAPI_CORE_DATA*)pCoreData, pdwHseResult );
pIsapiCore->Release();
return hr; }
HRESULT WAM::WamProcessIsapiCompletion( DWORD64 IsapiContext, DWORD cbCompletion, DWORD cbCompletionStatus ) /*++
Routine Description:
Processes an ISAPI I/O completion
Arguments:
IsapiContext - The ISAPI_CONTEXT that identifies the request cbCompletion - The number of bytes associated with the completion cbCompletionStatus - The status code associated with the completion
Return Value:
HRESULT
--*/ { HRESULT hr = NOERROR;
hr = sm_pfnProcessIsapiCompletion( IsapiContext, cbCompletion, cbCompletionStatus );
return hr; }
HRESULT WAM::WamInitProcess( BYTE *szIsapiModule, DWORD cbIsapiModule, DWORD *pdwProcessId, LPSTR szClsid, LPSTR szIsapiHandlerInstance, DWORD dwCallingProcess ) /*++
Routine Description:
Initializes WAM for the host process. This includes loading w3isapi.dll and getting function pointers for the relevant stuff
Arguments:
szIsapiModule - The full path (UNICODE) of w3isapi.dll cbIsapiModule - The number of bytes in the above path pdwProcessId - Upon return, contains the process ID of the host process szClsid - The CLSID of the WAM object being initialized szIsapiHandlerInstance - The instance ID of the W3_ISAPI_HANDLER that's initializing this WAM. dwCallingProcess - The process ID of this function's caller
Return Value:
HRESULT
--*/ { HRESULT hr = NOERROR; PFN_ISAPI_INIT_MODULE pfnInit = NULL;
//
// Initialize IISUTIL
//
if ( !InitializeIISUtil() ) { hr = HRESULT_FROM_WIN32( GetLastError() );
DBGPRINTF(( DBG_CONTEXT, "Error initializing IISUTIL. hr = %x\n", hr ));
goto ErrorExit; } //
// Load and initialize the ISAPI module
//
sm_hIsapiModule = LoadLibraryW( (LPWSTR)szIsapiModule ); if( sm_hIsapiModule == NULL ) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto ErrorExit; }
sm_pfnTermIsapiModule = (PFN_ISAPI_TERM_MODULE)GetProcAddress( sm_hIsapiModule, ISAPI_TERM_MODULE );
sm_pfnProcessIsapiRequest = (PFN_ISAPI_PROCESS_REQUEST)GetProcAddress( sm_hIsapiModule, ISAPI_PROCESS_REQUEST );
sm_pfnProcessIsapiCompletion = (PFN_ISAPI_PROCESS_COMPLETION)GetProcAddress( sm_hIsapiModule, ISAPI_PROCESS_COMPLETION );
if( !sm_pfnTermIsapiModule || !sm_pfnProcessIsapiRequest || !sm_pfnProcessIsapiCompletion ) { hr = E_FAIL; goto ErrorExit; }
pfnInit = (PFN_ISAPI_INIT_MODULE)GetProcAddress( sm_hIsapiModule, ISAPI_INIT_MODULE ); if( !pfnInit ) { hr = E_FAIL; goto ErrorExit; }
hr = pfnInit( szClsid, szIsapiHandlerInstance, dwCallingProcess );
if( FAILED(hr) ) { goto ErrorExit; }
//
// Set the process ID for the process hosting this object
//
*pdwProcessId = GetCurrentProcessId(); return hr;
ErrorExit:
DBG_ASSERT( FAILED( hr ) );
return hr; }
HRESULT WAM::WamUninitProcess( VOID ) /*++
Routine Description:
Uninitializes WAM for the host process. This function ultimately causes TerminateExtension to get called for each loaded extension.
Arguments:
None
Return Value:
HRESULT
--*/ { HRESULT hr = NOERROR; DBG_ASSERT( sm_pfnTermIsapiModule ); DBG_ASSERT( sm_hIsapiModule );
if( sm_pfnTermIsapiModule ) { sm_pfnTermIsapiModule(); sm_pfnTermIsapiModule = NULL; }
if( sm_hIsapiModule ) { FreeLibrary( sm_hIsapiModule ); sm_hIsapiModule = NULL; }
TerminateIISUtil();
return hr; }
HRESULT WAM::WamMarshalAsyncReadBuffer( DWORD64 IsapiContext, BYTE *pBuffer, DWORD cbBuffer ) /*++
Routine Description:
Receives a buffer to be passed to a request. This function will be called just prior to an I/O completion in the case where and OOP extension does an asynchronous ReadClient.
Arguments:
IsapiContext - The ISAPI_CONTEXT that identifies the request pBuffer - The data buffer cbBuffer - The size of pBuffer
Return Value:
HRESULT
--*/ { ISAPI_CONTEXT * pIsapiContext; VOID * pReadBuffer;
pIsapiContext = reinterpret_cast<ISAPI_CONTEXT*>( IsapiContext );
DBG_ASSERT( pIsapiContext ); DBG_ASSERT( pIsapiContext->QueryIoState() == AsyncReadPending );
pReadBuffer = pIsapiContext->QueryAsyncIoBuffer();
DBG_ASSERT( pReadBuffer != NULL );
memcpy( pReadBuffer, pBuffer, cbBuffer );
pIsapiContext->SetAsyncIoBuffer( NULL );
return NO_ERROR; }
|