Leaked source code of windows server 2003
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.
 
 
 
 
 
 

358 lines
10 KiB

// Ruler
// 1 2 3 4 5 6 7 8
//345678901234567890123456789012345678901234567890123456789012345678901234567890
/********************************************************************/
/* */
/* The standard layout. */
/* */
/* The standard layout for 'cpp' files in this code is as */
/* follows: */
/* */
/* 1. Include files. */
/* 2. Constants local to the class. */
/* 3. Data structures local to the class. */
/* 4. Data initializations. */
/* 5. Static functions. */
/* 6. Class functions. */
/* */
/* The constructor is typically the first function, class */
/* member functions appear in alphabetical order with the */
/* destructor appearing at the end of the file. Any section */
/* or function this is not required is simply omitted. */
/* */
/********************************************************************/
#include "LibraryPCH.hpp"
#include "Global.hpp"
#include "Spinlock.hpp"
/********************************************************************/
/* */
/* Constants local to the class. */
/* */
/* The constants supplied here control various debug settings. */
/* */
/********************************************************************/
CONST SBIT32 MaxDebugFileName = 128;
CONST SBIT32 DebugBufferSize = 512;
#ifdef ENABLE_DEBUG
#ifdef ENABLE_DEBUG_FILE
/********************************************************************/
/* */
/* Static member initialization. */
/* */
/* Static member initialization sets the initial value for all */
/* static members. */
/* */
/********************************************************************/
STATIC CHAR DebugModuleName[ MaxDebugFileName ] = "";
STATIC SPINLOCK Spinlock;
/********************************************************************/
/* */
/* Debug file name. */
/* */
/* We sometimes want to change the debug file name to prevent */
/* the debug file being overwritten by a DLLs output or a later */
/* run of the same application. */
/* */
/********************************************************************/
HANDLE DebugFileHandle( VOID )
{
AUTO CHAR FileName[ MaxDebugFileName ];
STATIC HANDLE DebugFile = INVALID_HANDLE_VALUE;
//
// We will open the debug file if it is not
// already open.
//
if ( DebugFile == INVALID_HANDLE_VALUE )
{
//
// Construct the full file name.
//
sprintf
(
FileName,
"C:\\Temp\\DebugTrace%s.log",
DebugModuleName
);
//
// Now lets try to open the file.
//
DebugFile =
(
CreateFile
(
((LPCTSTR) FileName),
(GENERIC_READ | GENERIC_WRITE),
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
NULL,
NULL
)
);
//
// When the file will not open for some reason
// we try an alternative path.
//
if ( DebugFile == INVALID_HANDLE_VALUE )
{
//
// Construct the alternate file name.
//
sprintf
(
FileName,
"C:\\DebugTrace%s.log",
DebugModuleName
);
//
// Try again using an alternative name.
//
DebugFile =
(
CreateFile
(
((LPCTSTR) FileName),
(GENERIC_READ | GENERIC_WRITE),
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
NULL,
NULL
)
);
}
}
return DebugFile;
}
/********************************************************************/
/* */
/* Debug file name. */
/* */
/* We sometimes want to change the debug file name to prevent */
/* the debug file being overwritten by a DLLs output or a later */
/* run of the same application. */
/* */
/********************************************************************/
VOID DebugFileName( CONST CHAR *FileName )
{
AUTO CHAR EditBuffer[ MaxDebugFileName ];
REGISTER CHAR *Current;
//
// Copy the file name into an edit buffer
// so we can remove any directories or
// trailing names.
//
strncpy( EditBuffer,FileName,MaxDebugFileName );
EditBuffer[ (MaxDebugFileName-1) ] = '\0';
//
// Scan backwards to remove any suffix.
//
for
(
Current = & EditBuffer[ (strlen( EditBuffer )-1) ];
(Current > EditBuffer) && ((*Current) != '.') && ((*Current) != '\\');
Current --
);
if ( (Current > EditBuffer) && (*Current) == '.' )
{ (*Current) = '\0'; }
//
// Scan backwards to the first directory name.
//
for
(
Current = & EditBuffer[ (strlen( EditBuffer )-1) ];
(Current > EditBuffer) && ((*Current) != '\\');
Current --
);
if ( (*Current) == '\\' )
{ Current ++; }
//
// Copy the edited file name.
//
DebugModuleName[0] = '-';
strncpy( & DebugModuleName[1],Current,(MaxDebugFileName-1) );
}
#endif
#endif
/********************************************************************/
/* */
/* Debug printing. */
/* */
/* We sometimes need to print message during debugging. We */
/* do this using the following 'printf' like function. */
/* */
/********************************************************************/
VOID DebugPrint( CONST CHAR *Format,... )
{
AUTO CHAR Buffer[ DebugBufferSize ];
//
// Start of variable arguments.
//
va_list Arguments;
va_start(Arguments, Format);
//
// Format the string to be printed.
//
_vsnprintf
(
Buffer,
(DebugBufferSize-1),
Format,
Arguments
);
//
// Force null termination.
//
Buffer[ (DebugBufferSize-1) ] = '\0';
#ifdef ENABLE_DEBUG_FILE
//
// Claim a spinlock to prevent multiple
// threads executing overlapping writes.
//
Spinlock.ClaimLock();
//
// We will write to the debug file if there
// is a valid handle.
//
if ( DebugFileHandle() != INVALID_HANDLE_VALUE )
{
REGISTER CHAR *Current = Buffer;
REGISTER SBIT32 Length;
//
// A number of windows applications are too
// stupid to understand a simple '\n'. So
// here we convert all "\n" to "\r\n".
//
for ( /* void */;(*Current) != '\0';Current += Length )
{
STATIC DWORD Written;
//
// Count the characters until the next
// newline or end of string.
//
for
(
Length=0;
((Current[ Length ] != '\n') && (Current[ Length ] != '\0'));
Length ++
);
//
// Write the string and then add a return
// newline sequence.
//
WriteFile
(
DebugFileHandle(),
((LPCVOID) Current),
((DWORD) Length),
& Written,
NULL
);
//
// Generate a newline (if needed).
//
if ( Current[ Length ] == '\n' )
{
WriteFile
(
DebugFileHandle(),
((LPCVOID) "\r\n"),
((DWORD) (sizeof("\r\n") - 1)),
& Written,
NULL
);
Length ++;
}
}
//
// Flush the file buffers.
//
FlushFileBuffers( DebugFileHandle() );
}
//
// Release any lock claimed earlier.
//
Spinlock.ReleaseLock();
#else
//
// Write to the debug window.
//
OutputDebugString( Buffer );
#endif
//
// End of variable arguments.
//
va_end( Arguments );
}
/********************************************************************/
/* */
/* Software failure. */
/* */
/* We know that when this function is called the application */
/* has failed so we simply try to cleanly exit in the vain */
/* hope that the failure can be caught and corrected. */
/* */
/********************************************************************/
VOID Failure( char *Message,BOOLEAN Report )
{
#ifdef ENABLE_DEBUG
//
// Report the fault to the debug stream
// (if required).
//
if ( Report )
{ DebugPrint( "*** Software Failure: %s ***\n",Message ); }
#endif
//
// Raise an exception.
//
#ifdef DISABLE_STRUCTURED_EXCEPTIONS
throw ((FAULT) Message);
#else
RaiseException( 1,0,1,((CONST DWORD*) Message) );
#endif
}