aspnetcore/src/AspNetCore/Src/dllmain.cpp

243 lines
6.3 KiB
C++

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
#include "precomp.hxx"
#include <IPHlpApi.h>
HTTP_MODULE_ID g_pModuleId = NULL;
IHttpServer * g_pHttpServer = NULL;
HANDLE g_hEventLog = NULL;
BOOL g_fRecycleProcessCalled = FALSE;
PCWSTR g_pszModuleName = NULL;
HINSTANCE g_hModule;
HMODULE g_hAspnetCoreRH = NULL;
BOOL g_fAspnetcoreRHAssemblyLoaded = FALSE;
BOOL g_fAspnetcoreRHLoadedError = FALSE;
BOOL g_fInShutdown = FALSE;
DWORD g_dwAspNetCoreDebugFlags = 0;
DWORD g_dwActiveServerProcesses = 0;
SRWLOCK g_srwLock;
DWORD g_dwDebugFlags = 0;
PCSTR g_szDebugLabel = "ASPNET_CORE_MODULE";
PCWSTR g_pwzAspnetcoreRequestHandlerName = L"aspnetcorerh.dll";
PFN_ASPNETCORE_CREATE_APPLICATION g_pfnAspNetCoreCreateApplication;
PFN_ASPNETCORE_CREATE_REQUEST_HANDLER g_pfnAspNetCoreCreateRequestHandler;
VOID
StaticCleanup()
{
APPLICATION_MANAGER::Cleanup();
if (g_hEventLog != NULL)
{
DeregisterEventSource(g_hEventLog);
g_hEventLog = NULL;
}
}
BOOL WINAPI DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
UNREFERENCED_PARAMETER(lpReserved);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hModule = hModule;
DisableThreadLibraryCalls(hModule);
break;
case DLL_PROCESS_DETACH:
// IIS can cause dll detatch to occur before we receive global notifications
// For example, when we switch the bitness of the worker process,
// this is a bug in IIS. To try to avoid AVs, we will set a global flag
g_fInShutdown = TRUE;
StaticCleanup();
default:
break;
}
return TRUE;
}
HRESULT
__stdcall
RegisterModule(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo * pModuleInfo,
IHttpServer * pHttpServer
)
/*++
Routine description:
Function called by IIS immediately after loading the module, used to let
IIS know what notifications the module is interested in
Arguments:
dwServerVersion - IIS version the module is being loaded on
pModuleInfo - info regarding this module
pHttpServer - callback functions which can be used by the module at
any point
Return value:
HRESULT
--*/
{
HRESULT hr = S_OK;
HKEY hKey;
BOOL fDisableANCM = FALSE;
ASPNET_CORE_PROXY_MODULE_FACTORY * pFactory = NULL;
ASPNET_CORE_GLOBAL_MODULE * pGlobalModule = NULL;
APPLICATION_MANAGER * pApplicationManager = NULL;
UNREFERENCED_PARAMETER(dwServerVersion);
#ifdef DEBUG
CREATE_DEBUG_PRINT_OBJECT("Asp.Net Core Module");
g_dwDebugFlags = DEBUG_FLAGS_ANY;
#endif // DEBUG
CREATE_DEBUG_PRINT_OBJECT;
//LoadGlobalConfiguration();
InitializeSRWLock(&g_srwLock);
g_pModuleId = pModuleInfo->GetId();
g_pszModuleName = pModuleInfo->GetName();
g_pHttpServer = pHttpServer;
if (g_pHttpServer->IsCommandLineLaunch())
{
g_hEventLog = RegisterEventSource(NULL, ASPNETCORE_IISEXPRESS_EVENT_PROVIDER);
}
else
{
g_hEventLog = RegisterEventSource(NULL, ASPNETCORE_EVENT_PROVIDER);
}
// check whether the feature is disabled due to security reason
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module\\Parameters",
0,
KEY_READ,
&hKey) == NO_ERROR)
{
DWORD dwType;
DWORD dwData;
DWORD cbData;
cbData = sizeof(dwData);
if ((RegQueryValueEx(hKey,
L"DisableANCM",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD))
{
fDisableANCM = (dwData != 0);
}
RegCloseKey(hKey);
}
if (fDisableANCM)
{
// Logging
STACK_STRU(strEventMsg, 256);
if (SUCCEEDED(strEventMsg.SafeSnwprintf(
ASPNETCORE_EVENT_MODULE_DISABLED_MSG)))
{
UTILITY::LogEvent(g_hEventLog,
EVENTLOG_WARNING_TYPE,
ASPNETCORE_EVENT_MODULE_DISABLED,
strEventMsg.QueryStr());
}
// this will return 500 error to client
// as we did not register the module
goto Finished;
}
//
// Create the factory before any static initialization.
// The ASPNET_CORE_PROXY_MODULE_FACTORY::Terminate method will clean any
// static object initialized.
//
pFactory = new ASPNET_CORE_PROXY_MODULE_FACTORY;
if (pFactory == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pModuleInfo->SetRequestNotifications(
pFactory,
RQ_EXECUTE_REQUEST_HANDLER,
0);
if (FAILED(hr))
{
goto Finished;
}
pFactory = NULL;
pApplicationManager = APPLICATION_MANAGER::GetInstance();
if(pApplicationManager == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pApplicationManager->Initialize();
if(FAILED(hr))
{
goto Finished;
}
pGlobalModule = NULL;
pGlobalModule = new ASPNET_CORE_GLOBAL_MODULE(pApplicationManager);
if (pGlobalModule == NULL)
{
hr = E_OUTOFMEMORY;
goto Finished;
}
hr = pModuleInfo->SetGlobalNotifications(
pGlobalModule,
GL_CONFIGURATION_CHANGE | // Configuration change trigers IIS application stop
GL_STOP_LISTENING); // worker process stop or recycle
if (FAILED(hr))
{
goto Finished;
}
pGlobalModule = NULL;
hr = ALLOC_CACHE_HANDLER::StaticInitialize();
if (FAILED(hr))
{
goto Finished;
}
Finished:
if (pGlobalModule != NULL)
{
delete pGlobalModule;
pGlobalModule = NULL;
}
if (pFactory != NULL)
{
pFactory->Terminate();
pFactory = NULL;
}
return hr;
}