windows-nt/Source/XPSP1/NT/ds/netapi/svcdlls/browser/server/brutil.c
2020-09-26 16:20:57 +08:00

534 lines
12 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
brutil.c
Abstract:
This module contains miscellaneous utility routines used by the
Browser service.
Author:
Rita Wong (ritaw) 01-Mar-1991
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
//-------------------------------------------------------------------//
// //
// Local function prototypes //
// //
//-------------------------------------------------------------------//
//-------------------------------------------------------------------//
// //
// Global variables //
// //
//-------------------------------------------------------------------//
NET_API_STATUS
BrMapStatus(
IN NTSTATUS NtStatus
)
/*++
Routine Description:
This function takes an NT status code and maps it to the appropriate
error code expected from calling a LAN Man API.
Arguments:
NtStatus - Supplies the NT status.
Return Value:
Returns the appropriate LAN Man error code for the NT status.
--*/
{
//
// A small optimization for the most common case.
//
if (NT_SUCCESS(NtStatus)) {
return NERR_Success;
}
switch (NtStatus) {
case STATUS_OBJECT_NAME_COLLISION:
return ERROR_ALREADY_ASSIGNED;
case STATUS_OBJECT_NAME_NOT_FOUND:
return NERR_UseNotFound;
case STATUS_REDIRECTOR_STARTED:
return NERR_ServiceInstalled;
default:
return NetpNtStatusToApiStatus(NtStatus);
}
}
ULONG
BrCurrentSystemTime()
{
NTSTATUS Status;
SYSTEM_TIMEOFDAY_INFORMATION TODInformation;
LARGE_INTEGER CurrentTime;
ULONG TimeInSecondsSince1980 = 0; // happy prefix 112576
ULONG BootTimeInSecondsSince1980 = 0; // ""
Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
&TODInformation,
sizeof(TODInformation),
NULL);
if (!NT_SUCCESS(Status)) {
return(0);
}
Status = NtQuerySystemTime(&CurrentTime);
if (!NT_SUCCESS(Status)) {
return(0);
}
RtlTimeToSecondsSince1980(&CurrentTime, &TimeInSecondsSince1980);
RtlTimeToSecondsSince1980(&TODInformation.BootTime, &BootTimeInSecondsSince1980);
return(TimeInSecondsSince1980 - BootTimeInSecondsSince1980);
}
VOID
BrLogEvent(
IN ULONG MessageId,
IN ULONG ErrorCode,
IN ULONG NumberOfSubStrings,
IN LPWSTR *SubStrings
)
{
DWORD Severity;
WORD Type;
PVOID RawData;
ULONG RawDataSize;
//
// Log the error code specified
//
Severity = (MessageId & 0xc0000000) >> 30;
if (Severity == STATUS_SEVERITY_WARNING) {
Type = EVENTLOG_WARNING_TYPE;
} else if (Severity == STATUS_SEVERITY_SUCCESS) {
Type = EVENTLOG_SUCCESS;
} else if (Severity == STATUS_SEVERITY_INFORMATIONAL) {
Type = EVENTLOG_INFORMATION_TYPE;
} else if (Severity == STATUS_SEVERITY_ERROR) {
Type = EVENTLOG_ERROR_TYPE;
} else {
// prefix uninit var consistency.
ASSERT(!"Unknown event log type!!");
return;
}
if (ErrorCode == NERR_Success) {
RawData = NULL;
RawDataSize = 0;
} else {
RawData = &ErrorCode;
RawDataSize = sizeof(DWORD);
}
//
// Use netlogon's routine to write eventlog messages.
// (It ditches duplicate events.)
//
NetpEventlogWrite (
BrGlobalEventlogHandle,
MessageId,
Type,
RawData,
RawDataSize,
SubStrings,
NumberOfSubStrings );
}
#if DBG
#define TRACE_FILE_SIZE 256
VOID
BrResetTraceLogFile(
VOID
);
CRITICAL_SECTION
BrowserTraceLock = {0};
HANDLE
BrowserTraceLogHandle = NULL;
DWORD
BrTraceLogFileSize = 0;
BOOLEAN BrowserTraceInitialized = {0};
VOID
BrowserTrace(
ULONG DebugFlag,
PCHAR FormatString,
...
)
#define LAST_NAMED_ARGUMENT FormatString
{
CHAR OutputString[4096];
ULONG length;
ULONG BytesWritten;
static BeginningOfLine = TRUE;
va_list ParmPtr; // Pointer to stack parms.
if (!BrowserTraceInitialized) {
return;
}
//
// If we aren't debugging this functionality, just return.
//
if ( DebugFlag != 0 && (BrInfo.BrowserDebug & DebugFlag) == 0 ) {
return;
}
EnterCriticalSection(&BrowserTraceLock);
length = 0;
try {
if (BrowserTraceLogHandle == NULL) {
//
// We've not opened the trace log file yet, so open it.
//
BrOpenTraceLogFile();
}
if (BrowserTraceLogHandle == INVALID_HANDLE_VALUE) {
LeaveCriticalSection(&BrowserTraceLock);
return;
}
//
// Attempt to catch bad trace.
//
for (BytesWritten = 0; BytesWritten < strlen(FormatString) ; BytesWritten += 1) {
if (FormatString[BytesWritten] > 0x7f) {
DbgBreakPoint();
}
}
//
// Handle the beginning of a new line.
//
//
if ( BeginningOfLine ) {
SYSTEMTIME SystemTime;
//
// Put the timestamp at the begining of the line.
//
GetLocalTime( &SystemTime );
length += (ULONG) sprintf( &OutputString[length],
"%02u/%02u %02u:%02u:%02u ",
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond );
//
// Indicate the type of message on the line
//
{
char *Text;
switch (DebugFlag) {
case BR_CRITICAL:
Text = "[CRITICAL]"; break;
case BR_INIT:
Text = "[INIT] "; break;
case BR_SERVER_ENUM:
Text = "[ENUM] "; break;
case BR_UTIL:
Text = "[UTIL] "; break;
case BR_CONFIG:
Text = "[CONFIG] "; break;
case BR_MAIN:
Text = "[MAIN] "; break;
case BR_BACKUP:
Text = "[BACKUP] "; break;
case BR_MASTER:
Text = "[MASTER] "; break;
case BR_DOMAIN:
Text = "[DOMAIN] "; break;
case BR_NETWORK:
Text = "[NETWORK]"; break;
case BR_TIMER:
Text = "[TIMER]"; break;
case BR_QUEUE:
Text = "[QUEUE]"; break;
case BR_LOCKS:
Text = "[LOCKS]"; break;
default:
Text = "[UNKNOWN]"; break;
}
length += (ULONG) sprintf( &OutputString[length], "%s ", Text );
}
}
//
// Put a the information requested by the caller onto the line
//
va_start(ParmPtr, FormatString);
length += (ULONG) vsprintf(&OutputString[length], FormatString, ParmPtr);
BeginningOfLine = (length > 0 && OutputString[length-1] == '\n' );
if ( BeginningOfLine ) {
OutputString[length-1] = '\r';
OutputString[length] = '\n';
OutputString[length+1] = '\0';
length++;
}
va_end(ParmPtr);
ASSERT(length <= sizeof(OutputString));
//
// Actually write the bytes.
//
if (!WriteFile(BrowserTraceLogHandle, OutputString, length, &BytesWritten, NULL)) {
KdPrint(("Error writing to Browser log file: %ld\n", GetLastError()));
KdPrint(("%s", OutputString));
return;
}
if (BytesWritten != length) {
KdPrint(("Error writing time to Browser log file: %ld\n", GetLastError()));
KdPrint(("%s", OutputString));
return;
}
//
// If the file has grown too large,
// truncate it.
//
BrTraceLogFileSize += BytesWritten;
if (BrTraceLogFileSize > BrInfo.BrowserDebugFileLimit) {
BrResetTraceLogFile();
}
} finally {
LeaveCriticalSection(&BrowserTraceLock);
}
}
VOID
BrInitializeTraceLog()
{
try {
InitializeCriticalSection(&BrowserTraceLock);
BrowserTraceInitialized = TRUE;
} except ( EXCEPTION_EXECUTE_HANDLER ) {
#if DBG
KdPrint( ("[Browser.dll]: Exception <%lu>. Failed to initialize trace log\n",
_exception_code() ) );
#endif
}
}
VOID
BrGetTraceLogRoot(
IN PWCHAR TraceFile
)
{
PSHARE_INFO_502 ShareInfo;
//
// If the DEBUG share exists, put the log file in that directory,
// otherwise, use the system root.
//
// This way, if the browser is running on an NTAS server, we can always
// get access to the log file.
//
if (NetShareGetInfo(NULL, L"DEBUG", 502, (PCHAR *)&ShareInfo) != NERR_Success) {
if (GetSystemDirectory(TraceFile, TRACE_FILE_SIZE*sizeof(WCHAR)) == 0) {
KdPrint(("Unable to get system directory: %ld\n", GetLastError()));
}
if (TraceFile[wcslen(TraceFile)] != L'\\') {
TraceFile[wcslen(TraceFile)+1] = L'\0';
TraceFile[wcslen(TraceFile)] = L'\\';
}
} else {
//
// Seed the trace file buffer with the local path of the netlogon
// share if it exists.
//
wcscpy(TraceFile, ShareInfo->shi502_path);
TraceFile[wcslen(ShareInfo->shi502_path)] = L'\\';
TraceFile[wcslen(ShareInfo->shi502_path)+1] = L'\0';
NetApiBufferFree(ShareInfo);
}
}
VOID
BrResetTraceLogFile(
VOID
)
{
WCHAR OldTraceFile[TRACE_FILE_SIZE];
WCHAR NewTraceFile[TRACE_FILE_SIZE];
if (BrowserTraceLogHandle != NULL) {
CloseHandle(BrowserTraceLogHandle);
}
BrowserTraceLogHandle = NULL;
BrGetTraceLogRoot(OldTraceFile);
wcscpy(NewTraceFile, OldTraceFile);
wcscat(OldTraceFile, L"Browser.Log");
wcscat(NewTraceFile, L"Browser.Bak");
//
// Delete the old log
//
DeleteFile(NewTraceFile);
//
// Rename the current log to the new log.
//
MoveFile(OldTraceFile, NewTraceFile);
BrOpenTraceLogFile();
}
VOID
BrOpenTraceLogFile(
VOID
)
{
WCHAR TraceFile[TRACE_FILE_SIZE];
BrGetTraceLogRoot(TraceFile);
wcscat(TraceFile, L"Browser.Log");
BrowserTraceLogHandle = CreateFile(TraceFile,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (BrowserTraceLogHandle == INVALID_HANDLE_VALUE) {
KdPrint(("Error creating trace file %ws: %ld\n", TraceFile, GetLastError()));
return;
}
BrTraceLogFileSize = SetFilePointer(BrowserTraceLogHandle, 0, NULL, FILE_END);
if (BrTraceLogFileSize == 0xffffffff) {
KdPrint(("Error setting trace file pointer: %ld\n", GetLastError()));
return;
}
}
VOID
BrUninitializeTraceLog()
{
DeleteCriticalSection(&BrowserTraceLock);
if (BrowserTraceLogHandle != NULL) {
CloseHandle(BrowserTraceLogHandle);
}
BrowserTraceLogHandle = NULL;
BrowserTraceInitialized = FALSE;
}
NET_API_STATUS
BrTruncateLog()
{
if (BrowserTraceLogHandle == NULL) {
BrOpenTraceLogFile();
}
if (BrowserTraceLogHandle == INVALID_HANDLE_VALUE) {
return ERROR_GEN_FAILURE;
}
if (SetFilePointer(BrowserTraceLogHandle, 0, NULL, FILE_BEGIN) == 0xffffffff) {
return GetLastError();
}
if (!SetEndOfFile(BrowserTraceLogHandle)) {
return GetLastError();
}
return NO_ERROR;
}
#endif