Source code of Windows XP (NT5)
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.

551 lines
12 KiB

  1. /*++
  2. Copyright (c) 1995-1997 Microsoft Corporation
  3. Module Name :
  4. wam.cpp
  5. Abstract:
  6. This module implements the exported routines for WAM object
  7. Author:
  8. David Kaplan ( DaveK ) 26-Feb-1997
  9. Wade Hilmo ( WadeH ) 08-Sep-2000
  10. Environment:
  11. User Mode - Win32
  12. Project:
  13. Wam DLL
  14. --*/
  15. //
  16. // Following are the notes from the original MSDEV generated file
  17. // Note: Proxy/Stub Information
  18. // To merge the proxy/stub code into the object DLL, add the file
  19. // dlldatax.c to the project. Make sure precompiled headers
  20. // are turned off for this file, and add _MERGE_PROXYSTUB to the
  21. // defines for the project.
  22. //
  23. // If you are not running WinNT4.0 or Win95 with DCOM, then you
  24. // need to remove the following define from dlldatax.c
  25. // #define _WIN32_WINNT 0x0400
  26. //
  27. // Further, if you are running MIDL without /Oicf switch, you also
  28. // need to remove the following define from dlldatax.c.
  29. // #define USE_STUBLESS_PROXY
  30. //
  31. // Modify the custom build rule for Wam.idl by adding the following
  32. // files to the Outputs.
  33. // Wam_p.c
  34. // dlldata.c
  35. // To build a separate proxy/stub DLL,
  36. // run nmake -f Wamps.mk in the project directory.
  37. // BEGIN mods
  38. // Post-wizard mods appear within BEGIN mods ... END mods
  39. // END mods
  40. #include "precomp.hxx"
  41. #include <w3isapi.h>
  42. #include <isapi_context.hxx>
  43. #include "wamobj.hxx"
  44. #include "IWam_i.c"
  45. #include "wamccf.hxx"
  46. #include <atlbase.h>
  47. // BEGIN mods
  48. #ifdef _ATL_STATIC_REGISTRY
  49. #include <statreg.h>
  50. #include <statreg.cpp>
  51. #endif
  52. #include <atlimpl.cpp>
  53. // END mods
  54. /************************************************************
  55. * Global Variables
  56. ************************************************************/
  57. const CHAR g_pszModuleName[] = "WAM";
  58. const CHAR g_pszWamRegLocation[] =
  59. "System\\CurrentControlSet\\Services\\W3Svc\\WAM";
  60. HMODULE WAM::sm_hIsapiModule;
  61. PFN_ISAPI_TERM_MODULE WAM::sm_pfnTermIsapiModule;
  62. PFN_ISAPI_PROCESS_REQUEST WAM::sm_pfnProcessIsapiRequest;
  63. PFN_ISAPI_PROCESS_COMPLETION WAM::sm_pfnProcessIsapiCompletion;
  64. #ifdef _MERGE_PROXYSTUB
  65. extern "C" HINSTANCE hProxyDll;
  66. #endif
  67. BEGIN_OBJECT_MAP(ObjectMap)
  68. OBJECT_ENTRY(CLSID_Wam, WAM)
  69. END_OBJECT_MAP()
  70. // BEGIN mods
  71. WAM_CCF_MODULE _WAMCCFModule;
  72. DECLARE_PLATFORM_TYPE();
  73. DECLARE_DEBUG_VARIABLE();
  74. DECLARE_DEBUG_PRINTS_OBJECT();
  75. // END mods
  76. /************************************************************
  77. * Type Definitions
  78. ************************************************************/
  79. // BUGBUG
  80. #undef INET_INFO_KEY
  81. #undef INET_INFO_PARAMETERS_KEY
  82. //
  83. // Configuration parameters registry key.
  84. //
  85. #define INET_INFO_KEY \
  86. "System\\CurrentControlSet\\Services\\iisw3adm"
  87. #define INET_INFO_PARAMETERS_KEY \
  88. INET_INFO_KEY "\\Parameters"
  89. const CHAR g_pszWpRegLocation[] =
  90. INET_INFO_PARAMETERS_KEY "\\WP";
  91. class DEBUG_WRAPPER {
  92. public:
  93. DEBUG_WRAPPER( IN LPCSTR pszModule )
  94. {
  95. #if DBG
  96. CREATE_DEBUG_PRINT_OBJECT( pszModule );
  97. #else
  98. UNREFERENCED_PARAMETER( pszModule );
  99. #endif
  100. LOAD_DEBUG_FLAGS_FROM_REG_STR( g_pszWpRegLocation, DEBUG_ERROR );
  101. }
  102. ~DEBUG_WRAPPER(void)
  103. { DELETE_DEBUG_PRINT_OBJECT(); }
  104. };
  105. class CWamModule _Module;
  106. /////////////////////////////////////////////////////////////////////////////
  107. // DLL Entry Point
  108. extern "C"
  109. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  110. {
  111. DWORD dwErr = NO_ERROR;
  112. #ifdef _MERGE_PROXYSTUB
  113. if (!PrxDllMain(hInstance, dwReason, lpReserved))
  114. return FALSE;
  115. #endif
  116. if (dwReason == DLL_PROCESS_ATTACH)
  117. {
  118. //
  119. // BEGIN mods
  120. //
  121. // From ATL generated
  122. _Module.Init(ObjectMap, hInstance);
  123. DisableThreadLibraryCalls(hInstance);
  124. // End of ATL generated
  125. _WAMCCFModule.Init();
  126. // END mods
  127. }
  128. else if (dwReason == DLL_PROCESS_DETACH)
  129. {
  130. if ( NULL != lpReserved )
  131. {
  132. //
  133. // Only cleanup if there is a FreeLibrary() call
  134. //
  135. return ( TRUE);
  136. }
  137. _WAMCCFModule.Term();
  138. _Module.Term();
  139. // BEGIN mods
  140. DELETE_DEBUG_PRINT_OBJECT();
  141. // END mods
  142. }
  143. return (dwErr == NO_ERROR);
  144. } // DllMain()
  145. /////////////////////////////////////////////////////////////////////////////
  146. // Used to determine whether the DLL can be unloaded by OLE
  147. STDAPI DllCanUnloadNow(void)
  148. {
  149. #ifdef _MERGE_PROXYSTUB
  150. if (PrxDllCanUnloadNow() != S_OK)
  151. return S_FALSE;
  152. #endif
  153. return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
  154. }
  155. /////////////////////////////////////////////////////////////////////////////
  156. // Returns a class factory to create an object of the requested type
  157. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  158. {
  159. HRESULT hr;
  160. if (ppv == NULL) {
  161. return ( NULL);
  162. }
  163. *ppv = NULL; // reset the value before getting inside.
  164. if (ppv == NULL) {
  165. return ( E_POINTER);
  166. }
  167. *ppv = NULL; // set the incoming value to be invalid entry
  168. #ifdef _MERGE_PROXYSTUB
  169. if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
  170. return S_OK;
  171. #endif
  172. hr = _WAMCCFModule.GetClassObject(rclsid, riid, ppv);
  173. // BEGIN mods
  174. if (hr == CLASS_E_CLASSNOTAVAILABLE)
  175. {
  176. // If request for standard CF failed -> try custom
  177. hr = _Module.GetClassObject(CLSID_Wam, riid, ppv);
  178. }
  179. // END mods
  180. return ( hr);
  181. } // DllGetClassObject()
  182. /////////////////////////////////////////////////////////////////////////////
  183. // DllRegisterServer - Adds entries to the system registry
  184. STDAPI DllRegisterServer(void)
  185. {
  186. #ifdef _MERGE_PROXYSTUB
  187. HRESULT hRes = PrxDllRegisterServer();
  188. if (FAILED(hRes))
  189. return hRes;
  190. #endif
  191. // registers object, typelib and all interfaces in typelib
  192. return _Module.RegisterServer(TRUE);
  193. }
  194. /////////////////////////////////////////////////////////////////////////////
  195. // DllUnregisterServer - Removes entries from the system registry
  196. STDAPI DllUnregisterServer(void)
  197. {
  198. #ifdef _MERGE_PROXYSTUB
  199. PrxDllUnregisterServer();
  200. #endif
  201. _Module.UnregisterServer();
  202. return S_OK;
  203. }
  204. HRESULT
  205. WAM::WamProcessIsapiRequest(
  206. BYTE *pCoreData,
  207. DWORD cbCoreData,
  208. IIsapiCore *pIsapiCore,
  209. DWORD *pdwHseResult
  210. )
  211. /*++
  212. Routine Description:
  213. Processes an ISAPI request
  214. Arguments:
  215. pCoreData - The core data from the server for the request
  216. cbCoreData - The size of pCoreData
  217. pIsapiCore - The IIsapiCore interface pointer for this request
  218. pdwHseResult - Upon return, contains the return from HttpExtensionProc
  219. Return Value:
  220. HRESULT
  221. --*/
  222. {
  223. HRESULT hr = NOERROR;
  224. pIsapiCore->AddRef();
  225. hr = sm_pfnProcessIsapiRequest(
  226. pIsapiCore,
  227. (ISAPI_CORE_DATA*)pCoreData,
  228. pdwHseResult
  229. );
  230. pIsapiCore->Release();
  231. return hr;
  232. }
  233. HRESULT
  234. WAM::WamProcessIsapiCompletion(
  235. DWORD64 IsapiContext,
  236. DWORD cbCompletion,
  237. DWORD cbCompletionStatus
  238. )
  239. /*++
  240. Routine Description:
  241. Processes an ISAPI I/O completion
  242. Arguments:
  243. IsapiContext - The ISAPI_CONTEXT that identifies the request
  244. cbCompletion - The number of bytes associated with the completion
  245. cbCompletionStatus - The status code associated with the completion
  246. Return Value:
  247. HRESULT
  248. --*/
  249. {
  250. HRESULT hr = NOERROR;
  251. hr = sm_pfnProcessIsapiCompletion(
  252. IsapiContext,
  253. cbCompletion,
  254. cbCompletionStatus
  255. );
  256. return hr;
  257. }
  258. HRESULT
  259. WAM::WamInitProcess(
  260. BYTE *szIsapiModule,
  261. DWORD cbIsapiModule,
  262. DWORD *pdwProcessId,
  263. LPSTR szClsid,
  264. LPSTR szIsapiHandlerInstance,
  265. DWORD dwCallingProcess
  266. )
  267. /*++
  268. Routine Description:
  269. Initializes WAM for the host process. This includes loading
  270. w3isapi.dll and getting function pointers for the relevant stuff
  271. Arguments:
  272. szIsapiModule - The full path (UNICODE) of w3isapi.dll
  273. cbIsapiModule - The number of bytes in the above path
  274. pdwProcessId - Upon return, contains the process ID of the
  275. host process
  276. szClsid - The CLSID of the WAM object being initialized
  277. szIsapiHandlerInstance - The instance ID of the W3_ISAPI_HANDLER that's
  278. initializing this WAM.
  279. dwCallingProcess - The process ID of this function's caller
  280. Return Value:
  281. HRESULT
  282. --*/
  283. {
  284. HRESULT hr = NOERROR;
  285. PFN_ISAPI_INIT_MODULE pfnInit = NULL;
  286. //
  287. // Initialize IISUTIL
  288. //
  289. if ( !InitializeIISUtil() )
  290. {
  291. hr = HRESULT_FROM_WIN32( GetLastError() );
  292. DBGPRINTF(( DBG_CONTEXT,
  293. "Error initializing IISUTIL. hr = %x\n",
  294. hr ));
  295. goto ErrorExit;
  296. }
  297. //
  298. // Load and initialize the ISAPI module
  299. //
  300. sm_hIsapiModule = LoadLibraryW( (LPWSTR)szIsapiModule );
  301. if( sm_hIsapiModule == NULL )
  302. {
  303. hr = HRESULT_FROM_WIN32( GetLastError() );
  304. goto ErrorExit;
  305. }
  306. sm_pfnTermIsapiModule =
  307. (PFN_ISAPI_TERM_MODULE)GetProcAddress( sm_hIsapiModule,
  308. ISAPI_TERM_MODULE
  309. );
  310. sm_pfnProcessIsapiRequest =
  311. (PFN_ISAPI_PROCESS_REQUEST)GetProcAddress( sm_hIsapiModule,
  312. ISAPI_PROCESS_REQUEST
  313. );
  314. sm_pfnProcessIsapiCompletion =
  315. (PFN_ISAPI_PROCESS_COMPLETION)GetProcAddress( sm_hIsapiModule,
  316. ISAPI_PROCESS_COMPLETION
  317. );
  318. if( !sm_pfnTermIsapiModule ||
  319. !sm_pfnProcessIsapiRequest ||
  320. !sm_pfnProcessIsapiCompletion )
  321. {
  322. hr = E_FAIL;
  323. goto ErrorExit;
  324. }
  325. pfnInit =
  326. (PFN_ISAPI_INIT_MODULE)GetProcAddress( sm_hIsapiModule,
  327. ISAPI_INIT_MODULE
  328. );
  329. if( !pfnInit )
  330. {
  331. hr = E_FAIL;
  332. goto ErrorExit;
  333. }
  334. hr = pfnInit(
  335. szClsid,
  336. szIsapiHandlerInstance,
  337. dwCallingProcess
  338. );
  339. if( FAILED(hr) )
  340. {
  341. goto ErrorExit;
  342. }
  343. //
  344. // Set the process ID for the process hosting this object
  345. //
  346. *pdwProcessId = GetCurrentProcessId();
  347. return hr;
  348. ErrorExit:
  349. DBG_ASSERT( FAILED( hr ) );
  350. return hr;
  351. }
  352. HRESULT
  353. WAM::WamUninitProcess(
  354. VOID
  355. )
  356. /*++
  357. Routine Description:
  358. Uninitializes WAM for the host process. This function ultimately
  359. causes TerminateExtension to get called for each loaded extension.
  360. Arguments:
  361. None
  362. Return Value:
  363. HRESULT
  364. --*/
  365. {
  366. HRESULT hr = NOERROR;
  367. DBG_ASSERT( sm_pfnTermIsapiModule );
  368. DBG_ASSERT( sm_hIsapiModule );
  369. if( sm_pfnTermIsapiModule )
  370. {
  371. sm_pfnTermIsapiModule();
  372. sm_pfnTermIsapiModule = NULL;
  373. }
  374. if( sm_hIsapiModule )
  375. {
  376. FreeLibrary( sm_hIsapiModule );
  377. sm_hIsapiModule = NULL;
  378. }
  379. TerminateIISUtil();
  380. return hr;
  381. }
  382. HRESULT
  383. WAM::WamMarshalAsyncReadBuffer(
  384. DWORD64 IsapiContext,
  385. BYTE *pBuffer,
  386. DWORD cbBuffer
  387. )
  388. /*++
  389. Routine Description:
  390. Receives a buffer to be passed to a request. This function will be
  391. called just prior to an I/O completion in the case where and OOP
  392. extension does an asynchronous ReadClient.
  393. Arguments:
  394. IsapiContext - The ISAPI_CONTEXT that identifies the request
  395. pBuffer - The data buffer
  396. cbBuffer - The size of pBuffer
  397. Return Value:
  398. HRESULT
  399. --*/
  400. {
  401. ISAPI_CONTEXT * pIsapiContext;
  402. VOID * pReadBuffer;
  403. pIsapiContext = reinterpret_cast<ISAPI_CONTEXT*>( IsapiContext );
  404. DBG_ASSERT( pIsapiContext );
  405. DBG_ASSERT( pIsapiContext->QueryIoState() == AsyncReadPending );
  406. pReadBuffer = pIsapiContext->QueryAsyncIoBuffer();
  407. DBG_ASSERT( pReadBuffer != NULL );
  408. memcpy( pReadBuffer, pBuffer, cbBuffer );
  409. pIsapiContext->SetAsyncIoBuffer( NULL );
  410. return NO_ERROR;
  411. }