aspnetcore/src/AspNetCoreModuleV2/CommonLib/debugutil.cpp

277 lines
6.1 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 "debugutil.h"
#include <string>
#include "dbgutil.h"
#include "stringu.h"
#include "stringa.h"
#include "dbgutil.h"
#include "Environment.h"
#include "SRWExclusiveLock.h"
#include "exceptions.h"
#include "atlbase.h"
#include "config_utility.h"
inline HANDLE g_hStandardOutput = INVALID_HANDLE_VALUE;
inline HANDLE g_logFile = INVALID_HANDLE_VALUE;
inline SRWLOCK g_logFileLock;
VOID
DebugInitialize()
{
g_hStandardOutput = GetStdHandle(STD_OUTPUT_HANDLE);
HKEY hKey;
InitializeSRWLock(&g_logFileLock);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\IIS Extensions\\IIS AspNetCore Module V2\\Parameters",
0,
KEY_READ,
&hKey) == NO_ERROR)
{
DWORD dwType;
DWORD dwData;
DWORD cbData;
cbData = sizeof(dwData);
if ((RegQueryValueEx(hKey,
L"DebugFlags",
NULL,
&dwType,
(LPBYTE)&dwData,
&cbData) == NO_ERROR) &&
(dwType == REG_DWORD))
{
DEBUG_FLAGS_VAR = dwData;
}
RegCloseKey(hKey);
}
try
{
SetDebugFlags(Environment::GetEnvironmentVariableValue(L"ASPNETCORE_MODULE_DEBUG").value_or(L"0"));
}
catch (...)
{
// ignore
}
try
{
const auto debugOutputFile = Environment::GetEnvironmentVariableValue(L"ASPNETCORE_MODULE_DEBUG_FILE");
CreateDebugLogFile(debugOutputFile.value_or(L""));
}
catch (...)
{
// ignore
}
if (IsDebuggerPresent())
{
DEBUG_FLAGS_VAR |= DEBUG_FLAGS_INFO;
}
}
HRESULT
DebugInitializeFromConfig(IHttpServer& pHttpServer, IHttpApplication& pHttpApplication)
{
CComPtr<IAppHostElement> pAspNetCoreElement;
const CComBSTR bstrAspNetCoreSection = L"system.webServer/aspNetCore";
CComBSTR bstrConfigPath = pHttpApplication.GetAppConfigPath();
RETURN_IF_FAILED(pHttpServer.GetAdminManager()->GetAdminSection(bstrAspNetCoreSection,
bstrConfigPath,
&pAspNetCoreElement));
STRU debugFile;
RETURN_IF_FAILED(ConfigUtility::FindDebugFile(pAspNetCoreElement, debugFile));
STRU debugValue;
RETURN_IF_FAILED(ConfigUtility::FindDebugLevel(pAspNetCoreElement, debugValue));
SetDebugFlags(debugValue.QueryStr());
CreateDebugLogFile(debugFile.QueryStr());
return S_OK;
}
void SetDebugFlags(const std::wstring &debugValue)
{
try
{
if (!debugValue.empty())
{
const auto value = std::stoi(debugValue.c_str());
if (value >= 1) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_ERROR;
if (value >= 2) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_WARNING;
if (value >= 3) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_INFO;
if (value >= 4) DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_CONSOLE;
}
}
catch (...)
{
// ignore
}
}
void CreateDebugLogFile(const std::wstring &debugOutputFile)
{
try
{
if (!debugOutputFile.empty())
{
if (g_logFile != INVALID_HANDLE_VALUE)
{
WLOG_INFOF(L"Switching debug log files to %s", debugOutputFile.c_str());
CloseHandle(g_logFile);
DEBUG_FLAGS_VAR &= ~ASPNETCORE_DEBUG_FLAG_FILE;
}
g_logFile = CreateFileW(debugOutputFile.c_str(),
(GENERIC_READ | GENERIC_WRITE),
(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
nullptr,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
nullptr
);
if (g_logFile != INVALID_HANDLE_VALUE)
{
DEBUG_FLAGS_VAR |= ASPNETCORE_DEBUG_FLAG_FILE;
}
}
}
catch (...)
{
// ignore
}
}
VOID
DebugStop()
{
if (IsEnabled(ASPNETCORE_DEBUG_FLAG_FILE))
{
CloseHandle(g_logFile);
}
}
BOOL
IsEnabled(
DWORD dwFlag
)
{
return ( dwFlag & DEBUG_FLAGS_VAR );
}
VOID
DebugPrint(
DWORD dwFlag,
const LPCSTR szString
)
{
STACK_STRA (strOutput, 256);
HRESULT hr = S_OK;
if ( IsEnabled( dwFlag ) )
{
hr = strOutput.SafeSnprintf(
"[%s] %s\r\n",
DEBUG_LABEL_VAR, szString );
if (FAILED (hr))
{
return;
}
OutputDebugStringA( strOutput.QueryStr() );
DWORD nBytesWritten = 0;
if (IsEnabled(ASPNETCORE_DEBUG_FLAG_CONSOLE))
{
WriteFile(g_hStandardOutput, strOutput.QueryStr(), strOutput.QueryCB(), &nBytesWritten, nullptr);
}
if (IsEnabled(ASPNETCORE_DEBUG_FLAG_FILE))
{
SRWExclusiveLock lock(g_logFileLock);
SetFilePointer(g_logFile, 0, nullptr, FILE_END);
WriteFile(g_logFile, strOutput.QueryStr(), strOutput.QueryCB(), &nBytesWritten, nullptr);
FlushFileBuffers(g_logFile);
}
}
}
VOID
DebugPrintf(
DWORD dwFlag,
const LPCSTR szFormat,
...
)
{
STACK_STRA (strCooked,256);
va_list args;
HRESULT hr = S_OK;
if ( IsEnabled( dwFlag ) )
{
va_start( args, szFormat );
hr = strCooked.SafeVsnprintf(szFormat, args );
va_end( args );
if (FAILED (hr))
{
return;
}
DebugPrint( dwFlag, strCooked.QueryStr() );
}
}
VOID
WDebugPrintf(
DWORD dwFlag,
LPCWSTR szFormat,
...
)
{
va_list args;
HRESULT hr = S_OK;
if ( IsEnabled( dwFlag ) )
{
STACK_STRU (formatted,256);
va_start( args, szFormat );
hr = formatted.SafeVsnwprintf(szFormat, args );
va_end( args );
if (FAILED (hr))
{
return;
}
STACK_STRA (converted, 256);
if (FAILED ( converted.CopyW(formatted.QueryStr(), formatted.QueryCCH()) ))
{
return;
}
DebugPrint( dwFlag, converted.QueryStr() );
}
}