482 lines
13 KiB
C
482 lines
13 KiB
C
//============================================================================
|
|
// Copyright (c) 1995, Microsoft Corporation
|
|
//
|
|
// File: config.c
|
|
//
|
|
// History:
|
|
// t-abolag 7/22/95 Created.
|
|
//
|
|
// contains client configuration functions for tracing dll
|
|
//============================================================================
|
|
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
#include <rtutils.h>
|
|
#include "trace.h"
|
|
//#define STRSAFE_LIB
|
|
#include <strsafe.h>
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: TraceEnableClient
|
|
//
|
|
// Parameters:
|
|
// LPTRACE_CLIENT *lpclient
|
|
// BOOL bFirstTime
|
|
//
|
|
// This function is called when a client first registers,
|
|
// every time a client is re-enabled after having been disabled,
|
|
// and every time a client's settings change.
|
|
// it assumes the client specified has been locked for writing
|
|
// and thus that the server is locked for writing
|
|
//----------------------------------------------------------------------------
|
|
DWORD
|
|
TraceEnableClient(
|
|
LPTRACE_SERVER lpserver,
|
|
LPTRACE_CLIENT lpclient,
|
|
BOOL bFirstTime
|
|
) {
|
|
|
|
|
|
DWORD dwErr, dwOldFlags, dwCache;
|
|
|
|
// enable by clearing disabled flag
|
|
lpclient->TC_Flags &= ~TRACEFLAGS_DISABLED;
|
|
|
|
dwCache = 0;
|
|
dwOldFlags = lpclient->TC_Flags;
|
|
|
|
|
|
//
|
|
// if the client uses registry settings, load them
|
|
//
|
|
if (TRACE_CLIENT_USES_REGISTRY(lpclient)) {
|
|
|
|
dwErr = TraceRegConfigClient(lpclient, bFirstTime);
|
|
if (dwErr != 0) { return dwErr; }
|
|
}
|
|
|
|
|
|
//
|
|
// if console tracing enabled and client had no console buffer
|
|
// open a console buffer for the client
|
|
//
|
|
if (TRACE_CLIENT_USES_CONSOLE(lpclient)) {
|
|
|
|
//
|
|
// open the console only if it wasn't already open
|
|
//
|
|
if (bFirstTime || (dwOldFlags & TRACEFLAGS_USECONSOLE) == 0) {
|
|
dwErr = TraceOpenClientConsole(lpserver, lpclient);
|
|
if (dwErr != NO_ERROR)
|
|
return dwErr;
|
|
}
|
|
|
|
dwCache |= (lpclient->TC_ConsoleMask | TRACEFLAGS_USECONSOLE);
|
|
}
|
|
else {
|
|
|
|
//
|
|
// console isn't enabled; if it WAS enabled,
|
|
// close the old console
|
|
//
|
|
if (!bFirstTime && (dwOldFlags & TRACEFLAGS_USECONSOLE)) {
|
|
|
|
//
|
|
// used to use the console,
|
|
// the buffer handle should be closed and active buffer
|
|
// set to be someone else
|
|
//
|
|
TraceCloseClientConsole(lpserver, lpclient);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// if this client was using a file, close it even if
|
|
// file tracing is still enabled for the client.
|
|
// the path of the tracing file may have been changed
|
|
//
|
|
if (!bFirstTime && (dwOldFlags & TRACEFLAGS_USEFILE)) {
|
|
TraceCloseClientFile(lpclient);
|
|
}
|
|
|
|
|
|
//
|
|
// if file tracing enabled open the client's tracing file
|
|
//
|
|
if (TRACE_CLIENT_USES_FILE(lpclient)) {
|
|
if ( (dwErr=TraceCreateClientFile(lpclient)) != NO_ERROR)
|
|
return dwErr;
|
|
|
|
dwCache |= (lpclient->TC_FileMask | TRACEFLAGS_USEFILE);
|
|
}
|
|
|
|
InterlockedExchange(
|
|
lpserver->TS_FlagsCache + lpclient->TC_ClientID, dwCache
|
|
);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: TraceDisableClient
|
|
//
|
|
// Parameters:
|
|
// LPTRACE_CLIENT *lpclient
|
|
//
|
|
// This function is called when a client is disabled
|
|
// it assumes the client specified has been locked for writing
|
|
//----------------------------------------------------------------------------
|
|
DWORD
|
|
TraceDisableClient(
|
|
LPTRACE_SERVER lpserver,
|
|
LPTRACE_CLIENT lpclient
|
|
) {
|
|
|
|
// disable by setting the disabled flag
|
|
lpclient->TC_Flags |= TRACEFLAGS_DISABLED;
|
|
|
|
InterlockedExchange(lpserver->TS_FlagsCache + lpclient->TC_ClientID, 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: TraceRegConfigClient
|
|
//
|
|
// Parameters:
|
|
// LPTRACE_CLIENT *lpclient
|
|
// BOOL bFirstTime
|
|
//
|
|
// This function loads the client's tracing configuration
|
|
// for the registry under
|
|
// Software
|
|
// \\Microsoft
|
|
// \\Tracing
|
|
// \\<client_name>
|
|
// EnableFileTracing REG_DWORD
|
|
// EnableConsoleTracing REG_DWORD
|
|
// MaxFileSize REG_DWORD
|
|
// FileDirectory REG_EXPAND_SZ
|
|
//----------------------------------------------------------------------------
|
|
DWORD
|
|
TraceRegConfigClient(
|
|
LPTRACE_CLIENT lpclient,
|
|
BOOL bFirstTime
|
|
) {
|
|
|
|
HKEY hkeyTracing;
|
|
TCHAR szTracing[MAX_PATH];
|
|
TCHAR szFileDir[MAX_PATH];
|
|
DWORD dwErr, dwType, dwValue, dwSize;
|
|
HRESULT hrResult;
|
|
|
|
if (bFirstTime) {
|
|
|
|
hrResult = StringCchCopy(szTracing, MAX_PATH, REGKEY_TRACING);//ss not req
|
|
if (FAILED(hrResult))
|
|
return HRESULT_CODE(hrResult);
|
|
|
|
hrResult = StringCchCat(szTracing, MAX_PATH, STR_DIRSEP);
|
|
if (FAILED(hrResult))
|
|
return HRESULT_CODE(hrResult);
|
|
|
|
hrResult = StringCchCat(szTracing, MAX_PATH, lpclient->TC_ClientName);
|
|
if (FAILED(hrResult))
|
|
return HRESULT_CODE(hrResult);
|
|
|
|
//
|
|
// open the registry key for the client
|
|
//
|
|
dwErr = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE, szTracing, 0, KEY_READ, &hkeyTracing
|
|
);
|
|
|
|
//
|
|
// if that failed, try to create it
|
|
//
|
|
if (dwErr != ERROR_SUCCESS) {
|
|
|
|
dwErr = TraceRegCreateDefaults(szTracing, &hkeyTracing);
|
|
|
|
if (dwErr != ERROR_SUCCESS) {
|
|
RegCloseKey(hkeyTracing);
|
|
lpclient->TC_ConfigKey = NULL;
|
|
return dwErr;
|
|
}
|
|
}
|
|
|
|
lpclient->TC_ConfigKey = hkeyTracing;
|
|
}
|
|
else {
|
|
hkeyTracing = lpclient->TC_ConfigKey;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// read the file-tracing flag
|
|
//
|
|
dwSize = sizeof(DWORD);
|
|
dwErr = RegQueryValueEx(
|
|
hkeyTracing, REGVAL_ENABLEFILETRACING, NULL,
|
|
&dwType, (LPBYTE)&dwValue, &dwSize
|
|
);
|
|
|
|
if (dwErr != ERROR_SUCCESS || dwType != REG_DWORD) {
|
|
dwValue = DEF_ENABLEFILETRACING;
|
|
}
|
|
|
|
|
|
if (dwValue == 1) { lpclient->TC_Flags |= TRACEFLAGS_USEFILE; }
|
|
else { lpclient->TC_Flags &= ~TRACEFLAGS_USEFILE; }
|
|
|
|
|
|
//
|
|
// read the file-tracing mask
|
|
//
|
|
dwSize = sizeof(DWORD);
|
|
dwErr = RegQueryValueEx(
|
|
hkeyTracing, REGVAL_FILETRACINGMASK, NULL,
|
|
&dwType, (LPBYTE)&dwValue, &dwSize
|
|
);
|
|
if (dwErr != ERROR_SUCCESS || dwType != REG_DWORD) {
|
|
dwValue = DEF_FILETRACINGMASK;
|
|
}
|
|
|
|
lpclient->TC_FileMask = (dwValue & 0xffff0000);
|
|
|
|
|
|
//
|
|
// read the console-tracing flag
|
|
//
|
|
dwSize = sizeof(DWORD);
|
|
dwErr = RegQueryValueEx(
|
|
hkeyTracing, REGVAL_ENABLECONSOLETRACING, NULL,
|
|
&dwType, (LPBYTE)&dwValue, &dwSize
|
|
);
|
|
if (dwErr != ERROR_SUCCESS || dwType != REG_DWORD) {
|
|
dwValue = DEF_ENABLECONSOLETRACING;
|
|
}
|
|
|
|
if (dwValue == 1) { lpclient->TC_Flags |= TRACEFLAGS_USECONSOLE; }
|
|
else { lpclient->TC_Flags &= ~TRACEFLAGS_USECONSOLE; }
|
|
|
|
|
|
|
|
//
|
|
// read the console-tracing mask
|
|
//
|
|
dwSize = sizeof(DWORD);
|
|
dwErr = RegQueryValueEx(
|
|
hkeyTracing, REGVAL_CONSOLETRACINGMASK, NULL,
|
|
&dwType, (LPBYTE)&dwValue, &dwSize
|
|
);
|
|
if (dwErr != ERROR_SUCCESS || dwType != REG_DWORD) {
|
|
dwValue = DEF_CONSOLETRACINGMASK;
|
|
}
|
|
|
|
lpclient->TC_ConsoleMask = (dwValue & 0xffff0000);
|
|
|
|
|
|
//
|
|
// read the maximum file size
|
|
//
|
|
dwSize = sizeof(DWORD);
|
|
dwErr = RegQueryValueEx(
|
|
hkeyTracing, REGVAL_MAXFILESIZE, NULL,
|
|
&dwType, (LPBYTE)&dwValue, &dwSize
|
|
);
|
|
if (dwErr != ERROR_SUCCESS || dwType != REG_DWORD) {
|
|
dwValue = DEF_MAXFILESIZE;
|
|
}
|
|
|
|
lpclient->TC_MaxFileSize = dwValue;
|
|
|
|
|
|
//
|
|
// read the tracing file directory
|
|
//
|
|
dwSize = MAX_PATH * sizeof(TCHAR);//size in bytes
|
|
dwErr = RegQueryValueEx(hkeyTracing, REGVAL_FILEDIRECTORY,
|
|
NULL, &dwType, (LPBYTE)szFileDir, &dwSize);
|
|
if (dwErr != ERROR_SUCCESS ||
|
|
(dwType != REG_EXPAND_SZ && dwType != REG_SZ)) {
|
|
hrResult = StringCchCopy(szFileDir, MAX_PATH,
|
|
DEF_FILEDIRECTORY);//ss not req
|
|
if (FAILED(hrResult))
|
|
return HRESULT_CODE(hrResult);
|
|
}
|
|
|
|
if (ExpandEnvironmentStrings(szFileDir, lpclient->TC_FileDir, MAX_PATH)
|
|
== 0)
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
// below is strsafe
|
|
#ifdef UNICODE
|
|
wcstombs(
|
|
lpclient->TC_FileDirA, lpclient->TC_FileDirW,
|
|
lstrlenW(lpclient->TC_FileDirW) + 1
|
|
);
|
|
#else
|
|
mbstowcs(
|
|
lpclient->TC_FileDirW, lpclient->TC_FileDirA,
|
|
lstrlenA(lpclient->TC_FileDirA) + 1
|
|
);
|
|
#endif
|
|
|
|
|
|
//
|
|
// request registry change notification
|
|
//
|
|
if (lpclient->TC_ConfigEvent == NULL) {
|
|
lpclient->TC_ConfigEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
if (lpclient->TC_ConfigEvent == NULL)
|
|
return GetLastError();
|
|
}
|
|
|
|
dwErr = RegNotifyChangeKeyValue(
|
|
lpclient->TC_ConfigKey, FALSE,
|
|
REG_NOTIFY_CHANGE_ATTRIBUTES |
|
|
REG_NOTIFY_CHANGE_LAST_SET |
|
|
REG_NOTIFY_CHANGE_SECURITY,
|
|
lpclient->TC_ConfigEvent, TRUE
|
|
);
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
DWORD
|
|
TraceRegCreateDefaults(
|
|
LPCTSTR lpszTracing,
|
|
PHKEY phkeyTracing
|
|
) {
|
|
|
|
DWORD dwSize, dwValue;
|
|
DWORD dwErr, dwDisposition;
|
|
TCHAR szFileDir[MAX_PATH];
|
|
HRESULT hrResult;
|
|
|
|
//
|
|
// create \\Microsoft\\Tracing
|
|
//
|
|
dwErr = RegCreateKeyEx(
|
|
HKEY_LOCAL_MACHINE, REGKEY_TRACING, 0, NULL,
|
|
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
|
|
phkeyTracing, &dwDisposition
|
|
);
|
|
if (dwErr != ERROR_SUCCESS) { return dwErr; }
|
|
|
|
RegCloseKey(*phkeyTracing);
|
|
|
|
|
|
//
|
|
// create \\Microsoft\\Tracing
|
|
//
|
|
dwErr = RegCreateKeyEx(
|
|
HKEY_LOCAL_MACHINE, lpszTracing, 0, NULL,
|
|
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
|
|
phkeyTracing, &dwDisposition
|
|
);
|
|
if (dwErr != ERROR_SUCCESS) { return dwErr; }
|
|
|
|
|
|
|
|
dwSize = sizeof(DWORD);
|
|
|
|
// all below sizeof dword
|
|
{
|
|
dwValue = DEF_ENABLEFILETRACING;
|
|
dwErr = RegSetValueEx(
|
|
*phkeyTracing, REGVAL_ENABLEFILETRACING, 0,
|
|
REG_DWORD, (LPBYTE)&dwValue, dwSize
|
|
);
|
|
if (dwErr != ERROR_SUCCESS) { return dwErr; }
|
|
|
|
dwValue = DEF_ENABLECONSOLETRACING;
|
|
dwErr = RegSetValueEx(
|
|
*phkeyTracing, REGVAL_ENABLECONSOLETRACING, 0,
|
|
REG_DWORD, (LPBYTE)&dwValue, dwSize
|
|
);
|
|
if (dwErr != ERROR_SUCCESS) { return dwErr; }
|
|
|
|
dwValue = DEF_FILETRACINGMASK;
|
|
dwErr = RegSetValueEx(
|
|
*phkeyTracing, REGVAL_FILETRACINGMASK, 0,
|
|
REG_DWORD, (LPBYTE)&dwValue, dwSize
|
|
);
|
|
if (dwErr != ERROR_SUCCESS) { return dwErr; }
|
|
|
|
dwValue = DEF_CONSOLETRACINGMASK;
|
|
dwErr = RegSetValueEx(
|
|
*phkeyTracing, REGVAL_CONSOLETRACINGMASK, 0,
|
|
REG_DWORD, (LPBYTE)&dwValue, dwSize
|
|
);
|
|
if (dwErr != ERROR_SUCCESS) { return dwErr; }
|
|
|
|
dwValue = DEF_MAXFILESIZE;
|
|
dwErr = RegSetValueEx(
|
|
*phkeyTracing, REGVAL_MAXFILESIZE, 0,
|
|
REG_DWORD, (LPBYTE)&dwValue, dwSize
|
|
);
|
|
if (dwErr != ERROR_SUCCESS) { return dwErr; }
|
|
}
|
|
|
|
hrResult = StringCchCopy(szFileDir, MAX_PATH, DEF_FILEDIRECTORY);
|
|
if (FAILED(hrResult))
|
|
return HRESULT_CODE(hrResult);
|
|
|
|
dwSize = lstrlen(szFileDir) * sizeof(TCHAR);//size in bytes
|
|
dwErr = RegSetValueEx(
|
|
*phkeyTracing, REGVAL_FILEDIRECTORY, 0,
|
|
REG_EXPAND_SZ, (LPBYTE)szFileDir, dwSize
|
|
);
|
|
if (dwErr != ERROR_SUCCESS) { return dwErr; }
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// assumes client is locked for reading
|
|
//
|
|
DWORD
|
|
TraceUpdateConsoleTitle(
|
|
LPTRACE_CLIENT lpclient
|
|
) {
|
|
|
|
TCHAR szTitle[MAX_PATH];
|
|
HRESULT hrResult = S_OK;
|
|
|
|
if (TRACE_CLIENT_IS_DISABLED(lpclient)) {
|
|
hrResult = StringCchPrintf(szTitle, MAX_PATH,
|
|
TEXT("%s [Tracing Inactive]"),
|
|
lpclient->TC_ClientName);
|
|
}
|
|
else {
|
|
hrResult = StringCchPrintf(szTitle, MAX_PATH,
|
|
TEXT("%s [Tracing Active]"),
|
|
lpclient->TC_ClientName);
|
|
}
|
|
|
|
if (FAILED(hrResult))
|
|
return HRESULT_CODE(hrResult);
|
|
|
|
SetConsoleTitle(szTitle);
|
|
return 0;
|
|
}
|
|
|
|
|