Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

577 lines
14 KiB

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name :
pudebug.c
Abstract:
This module defines functions required for
Debugging and logging messages for a dynamic program.
Author:
Murali R. Krishnan ( MuraliK ) 10-Sept-1994
Modified to be moved to common dll in 22-Dec-1994.
Revisions:
MuraliK 16-May-1995 Code to load and save debug flags from registry
MuraliK 16-Nov-1995 Remove DbgPrint (undoc api)
--*/
/************************************************************
* Include Headers
************************************************************/
# include <nt.h>
# include <ntrtl.h>
# include <nturtl.h>
# include <windows.h>
# include <stdio.h>
# include <stdlib.h>
# include <stdarg.h>
# include <string.h>
# include "pudebug.h"
/*************************************************************
* Global Variables and Default Values
*************************************************************/
# define MAX_PRINTF_OUTPUT ( 1024)
# define DEFAULT_DEBUG_FLAGS_VALUE ( 0)
# define DEBUG_FLAGS_REGISTRY_LOCATION_W L"DebugFlags"
/*************************************************************
* Functions
*************************************************************/
LPDEBUG_PRINTS
PuCreateDebugPrintsObject(
IN char * pszPrintLabel,
IN DWORD dwOutputFlags)
/*++
This function creates a new DEBUG_PRINTS object for the required
program.
Arguments:
pszPrintLabel pointer to null-terminated string containing
the label for program's debugging output
dwOutputFlags DWORD containing the output flags to be used.
Returns:
pointer to a new DEBUG_PRINTS object on success.
Returns NULL on failure.
--*/
{
LPDEBUG_PRINTS pDebugPrints;
pDebugPrints = GlobalAlloc( GPTR, sizeof( DEBUG_PRINTS));
if ( pDebugPrints != NULL) {
if ( strlen( pszPrintLabel) < MAX_LABEL_LENGTH) {
strcpy( pDebugPrints->m_rgchLabel, pszPrintLabel);
} else {
strncpy( pDebugPrints->m_rgchLabel,
pszPrintLabel, MAX_LABEL_LENGTH - 1);
pDebugPrints->m_rgchLabel[MAX_LABEL_LENGTH-1] = '\0';
// terminate string
}
memset( pDebugPrints->m_rgchLogFilePath, 0, MAX_PATH);
memset( pDebugPrints->m_rgchLogFileName, 0, MAX_PATH);
pDebugPrints->m_LogFileHandle = INVALID_HANDLE_VALUE;
pDebugPrints->m_dwOutputFlags = dwOutputFlags;
pDebugPrints->m_StdErrHandle = GetStdHandle( STD_ERROR_HANDLE);
pDebugPrints->m_fInitialized = TRUE;
}
return ( pDebugPrints);
} // PuCreateDebugPrintsObject()
LPDEBUG_PRINTS
PuDeleteDebugPrintsObject(
IN OUT LPDEBUG_PRINTS pDebugPrints)
/*++
This function cleans up the pDebugPrints object and
frees the allocated memory.
Arguments:
pDebugPrints poitner to the DEBUG_PRINTS object.
Returns:
NULL on success.
pDebugPrints() if the deallocation failed.
--*/
{
if ( pDebugPrints != NULL) {
DWORD dwError = PuCloseDbgPrintFile( pDebugPrints);
if ( dwError != NO_ERROR) {
SetLastError( dwError);
} else {
pDebugPrints = GlobalFree( pDebugPrints);
}
}
return ( pDebugPrints);
} // PuDeleteDebugPrintsObject()
VOID
PuSetDbgOutputFlags(
IN OUT LPDEBUG_PRINTS pDebugPrints,
IN DWORD dwFlags)
{
if ( pDebugPrints == NULL) {
SetLastError( ERROR_INVALID_PARAMETER);
} else {
pDebugPrints->m_dwOutputFlags = dwFlags;
}
return;
} // PuSetDbgOutputFlags()
DWORD
PuGetDbgOutputFlags(
IN const LPDEBUG_PRINTS pDebugPrints)
{
return ( pDebugPrints != NULL) ? pDebugPrints->m_dwOutputFlags : 0;
} // PuGetDbgOutputFlags()
static DWORD
PuOpenDbgFileLocal(
IN OUT LPDEBUG_PRINTS pDebugPrints)
{
if ( pDebugPrints->m_LogFileHandle != INVALID_HANDLE_VALUE) {
//
// Silently return as a file handle exists.
//
return ( NO_ERROR);
}
pDebugPrints->m_LogFileHandle =
CreateFile( pDebugPrints->m_rgchLogFileName,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if ( pDebugPrints->m_LogFileHandle == INVALID_HANDLE_VALUE) {
CHAR pchBuffer[1024];
DWORD dwError = GetLastError();
wsprintfA( pchBuffer,
" Critical Error: Unable to Open File %s. Error = %d\n",
pDebugPrints->m_rgchLogFileName, dwError);
OutputDebugString( pchBuffer);
return ( dwError);
}
return ( NO_ERROR);
} // PuOpenDbgFileLocal()
DWORD
PuOpenDbgPrintFile(
IN OUT LPDEBUG_PRINTS pDebugPrints,
IN char * pszFileName,
IN char * pszPathForFile)
/*++
Opens a Debugging log file. This function can be called to set path
and name of the debugging file.
Arguments:
pszFileName pointer to null-terminated string containing
the name of the file.
pszPathForFile pointer to null-terminated string containing the
path for the given file.
If NULL, then the old place where dbg files were
stored is used or if none,
default windows directory will be used.
Returns:
Win32 error codes. NO_ERROR on success.
--*/
{
if ( pszFileName == NULL || pDebugPrints == NULL) {
return ( ERROR_INVALID_PARAMETER);
}
//
// Setup the Path information. if necessary.
//
if ( pszPathForFile != NULL) {
// Path is being changed.
if ( strlen( pszPathForFile) < MAX_PATH) {
strcpy( pDebugPrints->m_rgchLogFilePath, pszPathForFile);
} else {
return ( ERROR_INVALID_PARAMETER);
}
} else {
if ( pDebugPrints->m_rgchLogFilePath[0] == '\0' && // no old path
!GetWindowsDirectory( pDebugPrints->m_rgchLogFilePath, MAX_PATH)) {
//
// Unable to get the windows default directory. Use current dir
//
strcpy( pDebugPrints->m_rgchLogFilePath, ".");
}
}
//
// Should need be, we need to create this directory for storing file
//
//
// Form the complete Log File name and open the file.
//
if ( (strlen( pszFileName) + strlen( pDebugPrints->m_rgchLogFilePath))
>= MAX_PATH) {
return ( ERROR_NOT_ENOUGH_MEMORY);
}
// form the complete path
strcpy( pDebugPrints->m_rgchLogFileName, pDebugPrints->m_rgchLogFilePath);
if ( pDebugPrints->m_rgchLogFileName[ strlen(pDebugPrints->m_rgchLogFileName) - 1]
!= '\\') {
// Append a \ if necessary
strcat( pDebugPrints->m_rgchLogFileName, "\\");
};
strcat( pDebugPrints->m_rgchLogFileName, pszFileName);
return PuOpenDbgFileLocal( pDebugPrints);
} // PuOpenDbgPrintFile()
DWORD
PuReOpenDbgPrintFile(
IN OUT LPDEBUG_PRINTS pDebugPrints)
/*++
This function closes any open log file and reopens a new copy.
If necessary. It makes a backup copy of the file.
--*/
{
PuCloseDbgPrintFile( pDebugPrints); // close any existing file.
if ( pDebugPrints->m_dwOutputFlags & DbgOutputBackup) {
// MakeBkupCopy();
OutputDebugString( " Error: MakeBkupCopy() Not Yet Implemented\n");
}
return PuOpenDbgFileLocal( pDebugPrints);
} // PuReOpenDbgPrintFile()
DWORD
PuCloseDbgPrintFile(
IN OUT LPDEBUG_PRINTS pDebugPrints)
{
DWORD dwError = NO_ERROR;
if ( pDebugPrints == NULL ) {
dwError = ERROR_INVALID_PARAMETER;
} else {
if ( pDebugPrints->m_LogFileHandle != INVALID_HANDLE_VALUE) {
FlushFileBuffers( pDebugPrints->m_LogFileHandle);
if ( !CloseHandle( pDebugPrints->m_LogFileHandle)) {
CHAR pchBuffer[1024];
dwError = GetLastError();
wsprintf( pchBuffer,
"CloseDbgPrintFile() : CloseHandle( %d) failed."
" Error = %d\n",
pDebugPrints->m_LogFileHandle,
dwError);
OutputDebugString( pchBuffer);
}
pDebugPrints->m_LogFileHandle = INVALID_HANDLE_VALUE;
}
}
return ( dwError);
} // DEBUG_PRINTS::CloseDbgPrintFile()
VOID
PuDbgPrint(
IN OUT LPDEBUG_PRINTS pDebugPrints,
IN const char * pszFilePath,
IN int nLineNum,
IN const char * pszFormat,
...)
/*++
Main function that examines the incoming message and prints out a header
and the message.
--*/
{
LPCSTR pszFileName = strrchr( pszFilePath, '\\');
char pszOutput[ MAX_PRINTF_OUTPUT];
LPCSTR pszMsg = "";
va_list argsList;
DWORD dwErr;
//
// Skip the complete path name and retain file name in pszName
//
if ( pszFileName== NULL) {
pszFileName = pszFilePath; // if skipping \\ yields nothing use whole path.
}
# ifdef _PRINT_REASONS_INCLUDED_
switch (pr) {
case PrintError:
pszMsg = "ERROR: ";
break;
case PrintWarning:
pszMsg = "WARNING: ";
break;
case PrintCritical:
pszMsg = "FATAL ERROR ";
break;
case PrintAssertion:
pszMsg = "ASSERTION Failed ";
break;
case PrintLog:
pfnPrintFunction = &DEBUG_PRINTS::DebugPrintNone;
default:
break;
} /* switch */
# endif // _PRINT_REASONS_INClUDED_
dwErr = GetLastError();
// Format the message header
wsprintf( pszOutput, "%s (%lu)[ %12s : %05d]",
pDebugPrints->m_rgchLabel,
GetCurrentThreadId(),
pszFileName, nLineNum);
// Format the incoming message
va_start( argsList, pszFormat);
vsprintf( pszOutput + strlen( pszOutput), pszFormat, argsList);
va_end( argsList);
//
// Send the outputs to respective files.
//
if ( pDebugPrints->m_dwOutputFlags & DbgOutputStderr) {
DWORD nBytesWritten;
( VOID) WriteFile( pDebugPrints->m_StdErrHandle,
pszOutput,
strlen( pszOutput),
&nBytesWritten,
NULL);
}
if ( pDebugPrints->m_dwOutputFlags & DbgOutputLogFile &&
pDebugPrints->m_LogFileHandle != INVALID_HANDLE_VALUE) {
DWORD nBytesWritten;
//
// Truncation of log files. Not yet implemented.
( VOID) WriteFile( pDebugPrints->m_LogFileHandle,
pszOutput,
strlen( pszOutput),
&nBytesWritten,
NULL);
}
if ( pDebugPrints->m_dwOutputFlags & DbgOutputKdb) {
OutputDebugString( pszOutput);
}
SetLastError( dwErr );
return;
} // PuDbgPrint()
VOID
PuDbgAssertFailed(
IN OUT LPDEBUG_PRINTS pDebugPrints,
IN const char * pszFilePath,
IN int nLineNum,
IN const char * pszExpression,
IN const char * pszMessage)
/*++
This function calls assertion failure and records assertion failure
in log file.
--*/
{
PuDbgPrint( pDebugPrints, pszFilePath, nLineNum,
" Assertion (%s) Failed: %s\n",
pszExpression,
pszMessage);
DebugBreak();
return;
} // PuDbgAssertFailed()
DWORD
PuLoadDebugFlagsFromReg(IN HKEY hkey, IN DWORD dwDefault)
/*++
This function reads the debug flags assumed to be stored in
the location "DebugFlags" under given key.
If there is any error the default value is returned.
--*/
{
DWORD err;
DWORD dwDebug = dwDefault;
DWORD dwBuffer;
DWORD cbBuffer = sizeof(dwBuffer);
DWORD dwType;
if( hkey != NULL )
{
err = RegQueryValueExW( hkey,
DEBUG_FLAGS_REGISTRY_LOCATION_W,
NULL,
&dwType,
(LPBYTE)&dwBuffer,
&cbBuffer );
if( ( err == NO_ERROR ) && ( dwType == REG_DWORD ) )
{
dwDebug = dwBuffer;
}
}
return dwDebug;
} // PuLoadDebugFlagsFromReg()
DWORD
PuSaveDebugFlagsInReg(IN HKEY hkey, IN DWORD dwDbg)
/*++
Saves the debug flags in registry. On failure returns the error code for
the operation that failed.
--*/
{
DWORD err;
if( hkey == NULL ) {
err = ERROR_INVALID_PARAMETER;
} else {
err = RegSetValueExW(hkey,
DEBUG_FLAGS_REGISTRY_LOCATION_W,
0,
REG_DWORD,
(LPBYTE)&dwDbg,
sizeof(dwDbg) );
}
return (err);
} // PuSaveDebugFlagsInReg()
/****************************** End of File ******************************/