windows-nt/Source/XPSP1/NT/ds/security/services/scerpc/server/errlog.cpp
2020-09-26 16:20:57 +08:00

609 lines
12 KiB
C++
Raw Permalink 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) 1996 Microsoft Corporation
Module Name:
errlog.c
Abstract:
Routines to handle error log information
Author:
Jin Huang (jinhuang) 9-Nov-1996
Revision History:
--*/
#include "headers.h"
#include "serverp.h"
#include <winnls.h>
#include <alloca.h>
#pragma hdrstop
#define SCESRV_LOG_PATH L"\\security\\logs\\scesrv.log"
extern HINSTANCE MyModuleHandle;
HANDLE Thread hMyLogFile=INVALID_HANDLE_VALUE;
BOOL
ScepCheckLogging(
IN INT ErrLevel,
IN DWORD rc
);
SCESTATUS
ScepSetVerboseLog(
IN INT dbgLevel
)
{
DWORD dValue;
if ( dbgLevel > 0 ) {
gDebugLevel = dbgLevel;
} else {
//
// load value from registry
//
if ( ScepRegQueryIntValue(
HKEY_LOCAL_MACHINE,
SCE_ROOT_PATH,
L"DebugLevel",
&dValue
) == SCESTATUS_SUCCESS )
gDebugLevel = (INT)dValue;
else
gDebugLevel = 1;
}
return(SCESTATUS_SUCCESS);
}
SCESTATUS
ScepEnableDisableLog(
IN BOOL bOnOff
)
{
bLogOn = bOnOff;
if ( INVALID_HANDLE_VALUE != hMyLogFile ) {
CloseHandle( hMyLogFile );
}
//
// Reset the LogFileName buffer and return
//
hMyLogFile = INVALID_HANDLE_VALUE;
return(SCESTATUS_SUCCESS);
}
SCESTATUS
ScepLogInitialize(
IN PCWSTR logname
)
/* ++
Routine Description:
Open the log file specified and save the name and its handle in global
variables.
Arguments:
logname - log file name
Return value:
SCESTATUS error code
-- */
{
DWORD rc=NO_ERROR;
if ( !bLogOn ) {
return(rc);
}
if ( logname && wcslen(logname) > 3 ) {
hMyLogFile = CreateFile(logname,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if ( INVALID_HANDLE_VALUE != hMyLogFile ) {
DWORD dwBytesWritten;
SetFilePointer (hMyLogFile, 0, NULL, FILE_BEGIN);
CHAR TmpBuf[3];
TmpBuf[0] = (CHAR)0xFF;
TmpBuf[1] = (CHAR)0xFE;
TmpBuf[2] = '\0';
WriteFile (hMyLogFile, (LPCVOID)TmpBuf, 2,
&dwBytesWritten,
NULL);
SetFilePointer (hMyLogFile, 0, NULL, FILE_END);
}
} else {
hMyLogFile = INVALID_HANDLE_VALUE;
}
BOOL bOpenGeneral = FALSE;
if ( INVALID_HANDLE_VALUE == hMyLogFile ) {
//
// use the general server log
//
LPTSTR dName=NULL;
DWORD dirSize=0;
DWORD rc = ScepGetNTDirectory(
&dName,
&dirSize,
SCE_FLAG_WINDOWS_DIR
);
if ( ERROR_SUCCESS == rc && dName ) {
LPTSTR windirName = (LPTSTR)ScepAlloc(0, (dirSize+wcslen(SCESRV_LOG_PATH)+1)*sizeof(TCHAR));
if ( windirName ) {
wcscpy(windirName, dName);
wcscat(windirName, SCESRV_LOG_PATH);
//
// only keep current log transaction. if other threads are holding
// on this log, it won't be deleted. It's ok (will be deleted later).
//
DeleteFile(windirName);
hMyLogFile = CreateFile(windirName,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if ( hMyLogFile != INVALID_HANDLE_VALUE ) {
DWORD dwBytesWritten;
SetFilePointer (hMyLogFile, 0, NULL, FILE_BEGIN);
CHAR TmpBuf[3];
TmpBuf[0] = (CHAR)0xFF;
TmpBuf[1] = (CHAR)0xFE;
TmpBuf[2] = '\0';
WriteFile (hMyLogFile, (LPCVOID)TmpBuf, 2,
&dwBytesWritten,
NULL);
SetFilePointer (hMyLogFile, 0, NULL, FILE_END);
}
ScepFree(windirName);
bOpenGeneral = TRUE;
}
}
if ( dName ) {
ScepFree(dName);
}
}
if ( hMyLogFile == INVALID_HANDLE_VALUE ) {
//
// Open file fails. return error
//
if (logname != NULL)
rc = ERROR_INVALID_NAME;
}
//
// log a separator to the file
//
ScepLogOutput3(0, 0, SCEDLL_SEPARATOR);
if ( bOpenGeneral && logname ) {
//
// the log file provided is not valid, log it
//
ScepLogOutput3(0, 0, IDS_ERROR_OPEN_LOG, logname);
}
//
// Write date/time information to the begining of the log file or to screen
//
TCHAR pvBuffer[100];
pvBuffer[0] = L'\0';
rc = ScepGetTimeStampString(pvBuffer);
if ( pvBuffer[0] != L'\0' )
ScepLogOutput(0, pvBuffer);
return(rc);
}
SCESTATUS
ScepLogOutput2(
IN INT ErrLevel,
IN DWORD rc,
IN PWSTR fmt,
...
)
/* ++
Routine Description:
This routine adds the information (variable arguments) to the end of the log file or
prints to screen
Arguments:
ErrLevel - the error level of this error (to determine if the error needs to be outputted)
rc - Win32 error code
fmt - the format of the error information
... - variable argument list
Return value:
SCESTATUS error code
-- */
{
PWSTR buf=NULL;
va_list args;
if ( !ScepCheckLogging(ErrLevel, rc) ) {
//
// no log
//
return(SCESTATUS_SUCCESS);
}
//
// check arguments
//
if ( !fmt )
return(SCESTATUS_SUCCESS);
//
// safely allocate the buffer on stack (or heap)
//
SafeAllocaAllocate( buf, SCE_BUF_LEN*sizeof(WCHAR) );
if ( buf == NULL ) {
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
}
va_start( args, fmt );
_vsnwprintf( buf, SCE_BUF_LEN - 1, fmt, args );
va_end( args );
SCESTATUS rCode = ScepLogOutput(rc, buf);
SafeAllocaFree( buf );
return rCode;
}
SCESTATUS
ScepLogOutput(
IN DWORD rc,
IN LPTSTR buf
)
{
if ( !buf ) {
return(SCESTATUS_SUCCESS);
}
LPVOID lpMsgBuf=NULL;
TCHAR strLevel[32];
INT idLevel=0;
if ( rc != NO_ERROR ) {
//
// determine if this is warning, or error
//
if ( rc == ERROR_FILE_NOT_FOUND ||
rc == ERROR_PATH_NOT_FOUND ||
rc == ERROR_ACCESS_DENIED ||
rc == ERROR_CANT_ACCESS_FILE ||
rc == ERROR_SHARING_VIOLATION ||
rc == ERROR_INVALID_OWNER ||
rc == ERROR_INVALID_PRIMARY_GROUP ||
rc == ERROR_INVALID_HANDLE ||
rc == ERROR_INVALID_SECURITY_DESCR ||
rc == ERROR_INVALID_ACL ||
rc == ERROR_SOME_NOT_MAPPED ) {
//
// this is warning
//
idLevel = IDS_WARNING;
} else {
//
// this is error
//
idLevel = IDS_ERROR;
}
strLevel[0] = L'\0';
if ( idLevel > 0 ) {
LoadString( MyModuleHandle,
idLevel,
strLevel,
31
);
}
//
// get error description of rc
//
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
rc,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL
);
}
if ( hMyLogFile != INVALID_HANDLE_VALUE ) {
//
// The log file is initialized
//
if ( rc != NO_ERROR ) {
if ( lpMsgBuf != NULL )
ScepWriteVariableUnicodeLog( hMyLogFile, TRUE, L"%s %d: %s %s",
strLevel, rc, (PWSTR)lpMsgBuf, buf );
else
ScepWriteVariableUnicodeLog( hMyLogFile, TRUE, L"%s %d: %s",
strLevel, rc, buf );
} else {
if ( lpMsgBuf != NULL )
ScepWriteVariableUnicodeLog( hMyLogFile, TRUE, L"%s %s",
(PWSTR)lpMsgBuf, buf );
else
ScepWriteSingleUnicodeLog( hMyLogFile, TRUE, buf );
}
}
if ( lpMsgBuf != NULL )
LocalFree(lpMsgBuf);
return(SCESTATUS_SUCCESS);
}
BOOL
ScepCheckLogging(
IN INT ErrLevel,
IN DWORD rc
)
{
DWORD dValue;
if ( rc )
gWarningCode = rc;
if ( !bLogOn ) {
return(FALSE);
}
if ( gDebugLevel < 0 ) {
//
// load value from registry
//
if ( ScepRegQueryIntValue(
HKEY_LOCAL_MACHINE,
SCE_ROOT_PATH,
L"DebugLevel",
&dValue
) == SCESTATUS_SUCCESS )
gDebugLevel = (INT)dValue;
else
gDebugLevel = 1;
}
//
// return if the error level is higher than required
//
if ( ErrLevel > gDebugLevel ) {
return(FALSE);
} else {
return(TRUE);
}
}
SCESTATUS
ScepLogOutput3(
IN INT ErrLevel,
IN DWORD rc,
IN UINT nId,
...
)
/* ++
Routine Description:
This routine load resource and adds error info (variable arguments)
to the end of the log file or prints to screen
Arguments:
ErrLevel - the error level of this error (to determine if the error needs to be outputted)
rc - Win32 error code
nId - the resource string ID
... - variable argument list
Return value:
SCESTATUS error code
-- */
{
WCHAR szTempString[256];
PWSTR buf=NULL;
va_list args;
if ( !ScepCheckLogging(ErrLevel, rc) ) {
//
// no log
//
return(SCESTATUS_SUCCESS);
}
if ( nId > 0 ) {
szTempString[0] = L'\0';
LoadString( MyModuleHandle,
nId,
szTempString,
256
);
//
// safely allocate the buffer on stack (or heap)
//
SafeAllocaAllocate( buf, SCE_BUF_LEN*sizeof(WCHAR) );
if ( buf == NULL ) {
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
}
//
// get the arguments
//
va_start( args, nId );
_vsnwprintf( buf, SCE_BUF_LEN - 1, szTempString, args );
va_end( args );
//
// log it and free
//
SCESTATUS rCode = ScepLogOutput(rc, buf);
SafeAllocaFree( buf );
return rCode;
}
return(SCESTATUS_SUCCESS);
}
SCESTATUS
ScepLogWriteError(
IN PSCE_ERROR_LOG_INFO pErrlog,
IN INT ErrLevel
)
/* ++
Routine Description:
This routine outputs the error message in each node of the SCE_ERROR_LOG_INFO
list to the log file
Arguments:
pErrlog - the error list
Return value:
None
-- */
{
PSCE_ERROR_LOG_INFO pErr;
if ( !bLogOn ) {
return(SCESTATUS_SUCCESS);
}
for ( pErr=pErrlog; pErr != NULL; pErr = pErr->next )
if ( pErr->buffer != NULL )
ScepLogOutput2( ErrLevel, pErr->rc, pErr->buffer );
return(SCESTATUS_SUCCESS);
}
SCESTATUS
ScepLogClose()
/* ++
Routine Description:
Close the log file if there is one opened. Clear the log varialbes
Arguments:
None
Return value:
None
--*/
{
if ( !bLogOn ) {
return(SCESTATUS_SUCCESS);
}
if ( hMyLogFile != INVALID_HANDLE_VALUE ) {
CloseHandle( hMyLogFile );
}
//
// Reset the log handle
//
hMyLogFile = INVALID_HANDLE_VALUE;
return(SCESTATUS_SUCCESS);
}