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.
 
 
 
 
 
 

1531 lines
39 KiB

/*******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 1997
*
* TITLE: WiaLog.cpp
*
* VERSION: 1.0
*
* AUTHOR: CoopP
*
* DATE: 20 Aug, 1999
*
* DESCRIPTION:
* Class implementation for WIA Logging.
*
*******************************************************************************/
#include "cplusinc.h"
#include "sticomm.h"
static const TCHAR szServiceName[] = TEXT("WIASERVC");
static const TCHAR szDefaultName[] = TEXT("WIASERVC.LOG");
static const TCHAR szDefaultKeyName[] = TEXT("WIASERVC");
static const TCHAR szDefaultDLLName[] = TEXT("noname.dll");
static const TCHAR szOpenedLog[] = TEXT("[%s] Opened log at %s %s");
static const TCHAR szClosedLog[] = TEXT("[%s] Closed log on %s %s");
static const WCHAR szFormatSignature[]= L"F9762DD2679F";
//#define DEBUG_WIALOG
/**************************************************************************\
* CWiaLog::CreateInstance
*
* Create the CWiaLog object.
*
* Arguments:
*
* iid - iid of Logging interface
* ppv - return interface pointer
*
* Return Value:
*
* status
*
* History:
*
* 8/20/1999 Original Version
*
\**************************************************************************/
HRESULT CWiaLog::CreateInstance(const IID& iid, void** ppv)
{
HRESULT hr;
//
// Create the WIA Logging component.
//
CWiaLog* pWiaLog = new CWiaLog();
if (!pWiaLog) {
return E_OUTOFMEMORY;
}
//
// Initialize the WIA logging component.
//
hr = pWiaLog->Initialize();
if (FAILED(hr)) {
delete pWiaLog;
return hr;
}
//
// Get the requested interface from the logging component.
//
hr = pWiaLog->QueryInterface(iid, ppv);
if (FAILED(hr)) {
#ifdef DEBUG_WIALOG
OutputDebugString(TEXT("CWiaLog::CreateInstance, Unkown interface\n"));
#endif
delete pWiaLog;
return hr;
}
#ifdef DEBUG_WIALOG
OutputDebugString(TEXT("CWiaLog::CreateInstance, Created WiaLog\n"));
#endif
return hr;
}
/**************************************************************************\
* QueryInterface
* AddRef
* Release
*
* CWiaLog IUnknown Interface
*
* Arguments:
*
*
*
* Return Value:
*
*
*
* History:
*
* 8/20/1999 Original Version
*
\**************************************************************************/
HRESULT __stdcall CWiaLog::QueryInterface(const IID& iid, void** ppv)
{
if (ppv == NULL)
{
return E_POINTER;
}
*ppv = NULL;
if ((iid == IID_IUnknown) || (iid == IID_IWiaLog)) {
*ppv = (IWiaLog*) this;
} else if (iid == IID_IWiaLogEx) {
*ppv = (IWiaLogEx*) this;
} else {
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG __stdcall CWiaLog::AddRef()
{
InterlockedIncrement((long*) &m_cRef);
//DPRINTF(DM_TRACE,TEXT("CWiaLog::AddRef() m_cRef = %d"),m_cRef);
return m_cRef;
}
ULONG __stdcall CWiaLog::Release()
{
ULONG ulRefCount = m_cRef - 1;
if (InterlockedDecrement((long*) &m_cRef) == 0) {
//DPRINTF(DM_TRACE,TEXT("CWiaLog::Release() m_cRef = %d"),m_cRef);
delete this;
return 0;
}
//DPRINTF(DM_TRACE,TEXT("CWiaLog::Release() m_cRef = %d"),m_cRef);
return ulRefCount;
}
/*******************************************************************************
*
* CWiaLog
* ~CWiaLog
*
* CWiaLog Constructor/Initialize/Destructor Methods.
*
* History:
*
* 8/20/1999 Original Version
*
\**************************************************************************/
CWiaLog::CWiaLog():m_cRef(0)
{
m_cRef = 0; // Initialize Reference count to zero
m_pITypeInfo = NULL; // Initialize InfoType to NULL
m_dwReportMode = 0; // Initialize Report Type to zero
m_dwMaxSize = WIA_MAX_LOG_SIZE; // Initialize File Max size to default
m_hLogFile = NULL; // Initialize File handle to NULL
m_lDetail = 0; // Initialize TRACE detail level to zero (off)
m_bLogToDebugger = FALSE; // Initialize Logging to DEBUGGER to FALSE
m_bLoggerInitialized = FALSE; // Initialize Logger to UNINITIALIZED
m_bTruncate = FALSE; // Initialize Truncation to FALSE
m_bClear = TRUE; // Initialize Clear Log file to TRUE (Don't want to make huge log files for no reason :) )
ZeroMemory(m_szLogFilePath, // Initialize Path buffer
sizeof(m_szLogFilePath));
ZeroMemory(m_szModeText, // Initialize formatted mode text buffer
sizeof(m_szModeText));
}
CWiaLog::~CWiaLog()
{
//DPRINTF(DM_TRACE,TEXT("CWiaLog::Destroy"));
if (m_pITypeInfo != NULL) {
m_pITypeInfo->Release();
}
//
// Flush buffers to disk
//
//DPRINTF(DM_TRACE,TEXT("Flushing final buffers"));
FlushFileBuffers(m_hLogFile);
//
// close log file on destruction of log object
//
//DPRINTF(DM_TRACE,TEXT("Closing file handle"));
CloseHandle(m_hLogFile);
//
// mark handle as invalid
//
m_hLogFile = INVALID_HANDLE_VALUE;
}
////////////////////////////////////////////////////////////////////////////////////
// IWiaLog private methods (exposed to the client) //
////////////////////////////////////////////////////////////////////////////////////
/**************************************************************************\
* CWiaLog::InitializeLog
*
* Initializes the Logging component
*
* Arguments:
*
* none
*
* Return Value:
*
* status
*
* History:
*
* 8/20/1999 Original Version
*
\**************************************************************************/
HRESULT _stdcall CWiaLog::InitializeLog (LONG hInstance)
{
HRESULT hr = S_OK;
//
// set instance handle
//
m_hInstance = (HINSTANCE) ULongToPtr(hInstance);
//
// set DLL's name
//
if(!FormatDLLName(m_hInstance,m_szFmtDLLName,sizeof(m_szFmtDLLName)/sizeof(m_szFmtDLLName[0]))) {
//
// if this there is no DLL name created, use a default one
//
lstrcpy(m_szFmtDLLName, szDefaultDLLName);
hr = E_INVALIDARG;
}
//
// Create Registry Key name
//
lstrcpyn(m_szKeyName,m_szFmtDLLName, (sizeof(m_szKeyName)/sizeof(m_szKeyName[0])) - 1);
m_szKeyName[(sizeof(m_szKeyName)/sizeof(m_szKeyName[0])) - 1] = TEXT('\0');
//
// open log file
//
if (OpenLogFile()) {
if (m_hLogFile != NULL) {
//
// query logging settings from registry, to
// setup logging system
//
QueryLoggingSettings();
if(m_bTruncate) {
ProcessTruncation();
}
if(m_bClear) {
//
// clear log file
//
::SetFilePointer(m_hLogFile, 0, NULL, FILE_BEGIN );
::SetEndOfFile(m_hLogFile );
}
WriteLogSessionHeader();
m_bLoggerInitialized = TRUE;
}
} else {
//
// Log file failed to Open... this is really bad
//
hr = E_FAIL;
}
return hr;
}
/**************************************************************************\
* CWiaLog::InitializeLogEx
*
* Initializes the Logging component.
*
* Arguments:
*
* hInstance - Handle of the caller's HINSTANCE
*
* Return Value:
*
* status
*
* History:
*
* 3/28/2000 Original Version
*
\**************************************************************************/
HRESULT _stdcall CWiaLog::InitializeLogEx(BYTE* hInstance)
{
HRESULT hr = S_OK;
//
// set instance handle
//
m_hInstance = (HINSTANCE) hInstance;
//
// set DLL's name
//
if(!FormatDLLName(m_hInstance,m_szFmtDLLName,sizeof(m_szFmtDLLName)/sizeof(m_szFmtDLLName[0]))) {
//
// if this there is no DLL name created, use a default one
//
lstrcpy(m_szFmtDLLName, szDefaultDLLName);
hr = E_INVALIDARG;
}
//
// Create Registry Key name
//
lstrcpyn(m_szKeyName,m_szFmtDLLName, (sizeof(m_szKeyName)/sizeof(m_szKeyName[0])) - 1);
m_szKeyName[(sizeof(m_szKeyName)/sizeof(m_szKeyName[0])) - 1] = TEXT('\0');
//
// open log file
//
if (OpenLogFile()) {
if (m_hLogFile != NULL) {
//
// query logging settings from registry, to
// setup logging system
//
QueryLoggingSettings();
if(m_bTruncate) {
ProcessTruncation();
}
if(m_bClear) {
//
// clear log file
//
::SetFilePointer(m_hLogFile, 0, NULL, FILE_BEGIN );
::SetEndOfFile(m_hLogFile );
}
WriteLogSessionHeader();
m_bLoggerInitialized = TRUE;
}
} else {
//
// Log file failed to Open... this is really bad
//
hr = E_FAIL;
}
return hr;
}
/**************************************************************************\
* Log()
*
* Handles Logging, TRACE,ERROR,and WARNING optional call logging
*
* Arguments:
*
* lFlags - Flag to determine which type of logging to use
* hInstance - Instance of the calling module
* lResID - Resource ID of the wiaservc.dll resource file
* lDetail - Logging detail level
* bstrText - string for display
*
*
* Return Value:
*
* status
*
* History:
*
* 8/20/1999 Original Version
*
\**************************************************************************/
HRESULT __stdcall CWiaLog::Log (LONG lFlags, LONG lResID, LONG lDetail, BSTR bstrText)
{
HRESULT hr = E_FAIL;
//
// check string for 'free signature' and remove signature if it exists.
//
BOOL bFreeString = NeedsToBeFreed(&bstrText);
if (m_bLoggerInitialized) {
// Find another way of updating the settings without querying the
// Registry every time
// QueryLoggingSettings();
/*
//
// NOTE: revisit this, How can you load a string resource ID from the service,
// if you don't have the service's HINSTANCE?????
//
if(lResID != WIALOG_NO_RESOURCE_ID) {
if (lResID < 35000) {
//
// Load the resource string from caller's resource
//
if (LoadString(g_hInstance,lResID,pBuffer, sizeof(pBuffer)) != 0) {
bstrText = SysAllocString(pBuffer);
bFreeString = TRUE;
}
} else {
//
// pull string from service's resource
//
}
}
*/
switch (lFlags) {
case WIALOG_ERROR:
if(m_dwReportMode & WIALOG_ERROR)
hr = Error(bstrText);
break;
case WIALOG_WARNING:
if(m_dwReportMode & WIALOG_WARNING)
hr = Warning(bstrText);
break;
case WIALOG_TRACE:
default:
if(m_dwReportMode & WIALOG_TRACE)
hr = Trace(bstrText,lDetail);
break;
}
}
if(bFreeString)
{
SysFreeString(bstrText);
}
return hr;
}
/**************************************************************************\
* LogEx()
*
* Handles Logging, TRACE,ERROR,and WARNING optional call logging. This
* is almost the same as the Log() call, but it contains a MethodId which
* can be used for more specific filtering.
*
* Arguments:
*
* lMethodId - Integer indicating the uniqeu ID associated with the
* calling method.
* lFlags - Flag to determine which type of logging to use
* hInstance - Instance of the calling module
* lResID - Resource ID of the wiaservc.dll resource file
* lDetail - Logging detail level
* bstrText - string for display
*
*
* Return Value:
*
* status
*
* History:
*
* 3/28/2000 Original Version
*
\**************************************************************************/
HRESULT _stdcall CWiaLog::LogEx(LONG lMethodId, LONG lFlags, LONG lResID, LONG lDetail, BSTR bstrText)
{
HRESULT hr = E_FAIL;
//
// check string for 'free signature' and remove signature if it exists.
//
BOOL bFreeString = NeedsToBeFreed(&bstrText);
if (m_bLoggerInitialized) {
switch (lFlags) {
case WIALOG_ERROR:
if(m_dwReportMode & WIALOG_ERROR)
hr = Error(bstrText, lMethodId);
break;
case WIALOG_WARNING:
if(m_dwReportMode & WIALOG_WARNING)
hr = Warning(bstrText, lMethodId);
break;
case WIALOG_TRACE:
default:
if(m_dwReportMode & WIALOG_TRACE)
hr = Trace(bstrText,lDetail, lMethodId);
break;
}
}
if(bFreeString)
{
SysFreeString(bstrText);
}
return hr;
}
/**************************************************************************\
* hResult()
*
* Handles hResult translating for Error call logging
*
* Arguments:
*
* hInstance - Instance of the calling module
* hr - HRESULT to be translated
*
* Return Value:
*
* status
*
* History:
*
* 8/20/1999 Original Version
*
\**************************************************************************/
HRESULT __stdcall CWiaLog::hResult (HRESULT hr)
{
HRESULT hRes = E_FAIL;
if (m_bLoggerInitialized) {
// Find another way of updating the settings without querying the
// Registry every time
// QueryLoggingSettings();
//
// we are initialized, so set the return to S_OK
//
hRes = S_OK;
if (m_dwReportMode & WIALOG_ERROR) {
#define NUM_CHARS_FOR_HRESULT 150
TCHAR szhResultText[NUM_CHARS_FOR_HRESULT];
ULONG ulLen = 0;
memset(szhResultText, 0, sizeof(szhResultText));
ulLen = ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)szhResultText,
NUM_CHARS_FOR_HRESULT,
NULL);
if (ulLen) {
szhResultText[NUM_CHARS_FOR_HRESULT - 1] = TEXT('\0');
memset(m_szTextBuffer,0,sizeof(m_szTextBuffer));
ConstructText();
_sntprintf(m_szTextBuffer,
(sizeof(m_szTextBuffer)/sizeof(m_szTextBuffer[0])) - 1,
TEXT("%s HRESULT: %s"),
m_szModeText,
szhResultText);
WriteStringToLog(m_szTextBuffer, FLUSH_STATE);
}
}
}
return hRes;
}
HRESULT _stdcall CWiaLog::hResultEx(LONG lMethodId, HRESULT hr)
{
HRESULT hRes = E_FAIL;
if (m_bLoggerInitialized) {
// Find another way of updating the settings without querying the
// Registry every time
// QueryLoggingSettings();
//
// we are initialized, so set the return to S_OK
//
hRes = S_OK;
if (m_dwReportMode & WIALOG_ERROR) {
#define NUM_CHARS_FOR_HRESULT 150
TCHAR szhResultText[NUM_CHARS_FOR_HRESULT];
ULONG ulLen = 0;
memset(szhResultText, 0, sizeof(szhResultText));
ulLen = ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)szhResultText,
NUM_CHARS_FOR_HRESULT,
NULL);
if (ulLen) {
szhResultText[NUM_CHARS_FOR_HRESULT - 1] = TEXT('\0');
memset(m_szTextBuffer,0,sizeof(m_szTextBuffer));
ConstructText();
_sntprintf(m_szTextBuffer,
(sizeof(m_szTextBuffer)/sizeof(m_szTextBuffer[0])) - 1,
TEXT("#0x%08X %s HRESULT: %s"),
lMethodId,
m_szModeText,
szhResultText);
WriteStringToLog(m_szTextBuffer, FLUSH_STATE);
}
}
}
return hRes;
}
HRESULT _stdcall CWiaLog::UpdateSettingsEx(LONG lCount, LONG *plMethodIds)
{
return E_NOTIMPL;
}
HRESULT _stdcall CWiaLog::ExportMappingTableEx(MappingTable **ppTable)
{
return E_NOTIMPL;
}
////////////////////////////////////////////////////////////////////////////////////
// IWiaLog private methods (not exposed to the client) //
////////////////////////////////////////////////////////////////////////////////////
/**************************************************************************\
* CWiaLog::Initialize
*
* Initializes the CWiaLog class object (does nothing at the moment)
*
* Arguments:
*
* none
*
* Return Value:
*
* status
*
* History:
*
* 8/20/1999 Original Version
*
\**************************************************************************/
HRESULT CWiaLog::Initialize()
{
//DPRINTF(DM_TRACE,TEXT("CWiaLog::Initialize"));
return S_OK;
}
/**************************************************************************\
* Trace()
*
* Handles Trace call logging
*
* Arguments:
*
* hInstance - Instance of the calling module
* lResID - Resource ID of the wiaservc.dll resource file
* bstrText - string for display
* lDetail - Logging detail level
*
* Return Value:
*
* status
*
* History:
*
* 8/20/1999 Original Version
*
\**************************************************************************/
HRESULT CWiaLog::Trace (BSTR bstrText, LONG lDetail, LONG lMethodId)
{
memset(m_szTextBuffer,0,sizeof(m_szTextBuffer));
//
// Turn off if lDetail level is zero
// TODO: Only don't log if both detail level = 0, and the lMethodId doesn't
// match one in our list
//
if(m_lDetail == 0) {
return S_OK;
}
if (lDetail <= m_lDetail) {
ConstructText();
_sntprintf(m_szTextBuffer,
sizeof(m_szTextBuffer) / sizeof(m_szTextBuffer[0]) - 1,
TEXT("#0x%08X %s TRACE: %ws"),
lMethodId,
m_szModeText,
bstrText);
WriteStringToLog(m_szTextBuffer, FLUSH_STATE);
}
return S_OK;
}
/**************************************************************************\
* Warning()
*
* Handles Warning call logging
*
* Arguments:
*
* hInstance - Instance of the calling module
* lResID - Resource ID of the wiaservc.dll resource file
* bstrText - string for display
*
* Return Value:
*
* status
*
* History:
*
* 8/20/1999 Original Version
*
\**************************************************************************/
HRESULT CWiaLog::Warning(BSTR bstrText, LONG lMethodId)
{
memset(m_szTextBuffer,0,sizeof(m_szTextBuffer));
ConstructText();
_sntprintf(m_szTextBuffer,
sizeof(m_szTextBuffer) / sizeof(m_szTextBuffer[0]) - 1,
TEXT("#0x%08X %s WARNING: %ws"),
lMethodId,
m_szModeText,
bstrText);
WriteStringToLog(m_szTextBuffer, FLUSH_STATE);
return S_OK;
}
/**************************************************************************\
* Error()
*
* Handles Error call logging
*
* Arguments:
*
* hInstance - Instance of the calling module
* lResID - Resource ID of the wiaservc.dll resource file
* bstrText - string for display
*
* Return Value:
*
* status
*
* History:
*
* 8/20/1999 Original Version
*
\**************************************************************************/
HRESULT CWiaLog::Error (BSTR bstrText, LONG lMethodId)
{
memset(m_szTextBuffer,0,sizeof(m_szTextBuffer));
ConstructText();
_sntprintf(m_szTextBuffer,
sizeof(m_szTextBuffer) / sizeof(m_szTextBuffer[0]) - 1,
TEXT("#0x%08X %s ERROR: %ws"),
lMethodId,
m_szModeText,
bstrText);
WriteStringToLog(m_szTextBuffer, FLUSH_STATE);
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////////
// IWiaLog private helpers (not exposed to the client) //
////////////////////////////////////////////////////////////////////////////////////
/**************************************************************************\
* OpenLogFile()
*
* Open the log file for logging
*
*
* Arguments:
*
* none
*
* Return Value:
*
* status
*
* History:
*
* 8/23/1999 Original Version
*
\**************************************************************************/
BOOL CWiaLog::OpenLogFile()
{
//
// Open log file
//
DWORD dwLength = 0;
CSimpleString csName;
m_hLogFile = INVALID_HANDLE_VALUE;
//
// Get Windows Directory
//
dwLength = ExpandEnvironmentStrings(TEXT("%USERPROFILE%"), m_szLogFilePath,
sizeof(m_szLogFilePath) /
sizeof(m_szLogFilePath[0]));
if (( dwLength == 0) || !*m_szLogFilePath ) {
//DPRINTF(DM_TRACE,TEXT("Could not GetWindowsDirectory()"));
return FALSE;
}
m_szLogFilePath[(sizeof(m_szLogFilePath)/sizeof(m_szLogFilePath[0]) - 1)] = TEXT('\0');
//
// Add log file name to Windows Directory
//
csName = m_szLogFilePath;
csName += TEXT("\\");
csName += TEXT("wiaservc.log");
//
// Create / open Log file
//
m_hLogFile = ::CreateFile(m_szLogFilePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL, // security attributes
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL); // template file handle
if (m_hLogFile == INVALID_HANDLE_VALUE)
return FALSE;
return TRUE;
}
/**************************************************************************\
* WriteStringToLog()
*
* Writed formatted TEXT to a log file
*
*
* Arguments:
*
* pszTextBuffer - Buffer of TEXT to write to file
* fFlush - TRUE = FLUSH file on write,
* FALSE = DON'T FLUSH file on write
*
* Return Value:
*
* status
*
* History:
*
* 8/23/1999 Original Version
*
\**************************************************************************/
VOID CWiaLog::WriteStringToLog(LPTSTR pszTextBuffer,BOOL fFlush)
{
DWORD dwcbWritten;
BY_HANDLE_FILE_INFORMATION fi;
if (!GetFileInformationByHandle(m_hLogFile,&fi)) {
//DPRINTF(DM_TRACE,TEXT("WIALOG could not get file size for log file. "));
return;
}
//
// check to see if our log file has exceeded it's MAX SIZE
// If it has, reset the file pointer, and start writing from the
// TOP.
//
//if ( fi.nFileSizeHigh !=0 || (fi.nFileSizeLow > m_dwMaxSize) ){
// ::SetFilePointer( m_hLogFile, 0, NULL, FILE_END);
// ::SetEndOfFile( m_hLogFile );
// ::GetFileInformationByHandle(m_hLogFile,&fi);
//}
#ifdef USE_FILE_LOCK
::LockFile(m_hLogFile,
fi.nFileSizeLow,
fi.nFileSizeHigh,
NUM_BYTES_TO_LOCK_LOW,
NUM_BYTES_TO_LOCK_HIGH);
#endif
::SetFilePointer( m_hLogFile, 0, NULL, FILE_END);
#ifdef UNICODE
//
// convert to ANSI if we are UNICODE, and write string to log.
//
CHAR buffer[MAX_PATH];
WideCharToMultiByte(CP_ACP,WC_NO_BEST_FIT_CHARS,pszTextBuffer,-1,buffer,MAX_PATH,NULL,NULL);
::WriteFile(m_hLogFile,
buffer,
lstrlen(pszTextBuffer),
&dwcbWritten,
NULL);
#else
//
// we are ANSI so write string to log.
//
::WriteFile(m_hLogFile,
pszTextBuffer,
lstrlen(pszTextBuffer),
&dwcbWritten,
NULL);
#endif
::WriteFile(m_hLogFile,
"\r\n",
2,
&dwcbWritten,
NULL);
#ifdef USE_FILE_LOCK
::UnlockFile(m_hLogFile,
fi.nFileSizeLow,
fi.nFileSizeHigh,
NUM_BYTES_TO_LOCK_LOW,
NUM_BYTES_TO_LOCK_HIGH);
#endif
//
// Flush buffers to disk if requested (should always be TRUE on Millenium)
//
if (fFlush) {
FlushFileBuffers(m_hLogFile);
}
//
// Log to a Debugger
//
if (m_bLogToDebugger) {
::OutputDebugString(pszTextBuffer);
::OutputDebugString(TEXT("\n"));
}
//
// Log to a Window / UI
//
if (m_bLogToUI) {
//
// Log to some window...or UI
//
}
}
/**************************************************************************\
* FormatStdTime()
*
* Formats the TIME to be added to a LOG file
*
*
* Arguments:
*
* pstNow - System Time NOW
* pchBuffer - buffer for the formatted time
* cbBuffer - Buffer size
*
*
* Return Value:
*
* status
*
* History:
*
* 8/23/1999 Original Version
*
\**************************************************************************/
BOOL CWiaLog::FormatStdTime(const SYSTEMTIME *pstNow,TCHAR *pchBuffer)
{
::wsprintf(pchBuffer,
TEXT("%02d:%02d:%02d.%03d"),
pstNow->wHour,
pstNow->wMinute,
pstNow->wSecond,
pstNow->wMilliseconds);
return TRUE;
}
/**************************************************************************\
* FormatStdDate()
*
* Formats the DATE to be added to a LOG file
*
*
* Arguments:
*
* pstNow - System TIME NOW
* pchBuffer - buffer for the formatted time
* cbBuffer - Buffer size
*
*
* Return Value:
*
* status
*
* History:
*
* 8/23/1999 Original Version
*
\**************************************************************************/
inline BOOL FormatStdDate(const SYSTEMTIME *pstNow,TCHAR *pchBuffer,INT cchBuffer)
{
return (GetDateFormat(LOCALE_SYSTEM_DEFAULT,
LOCALE_NOUSEROVERRIDE,
pstNow,
NULL,
pchBuffer,
cchBuffer)!= 0);
}
/**************************************************************************\
* WriteLogSessionHeader()
*
* Writes a header to the log file
*
*
* Arguments:
*
* none
*
* Return Value:
*
* void
*
* History:
*
* 8/23/1999 Original Version
*
\**************************************************************************/
VOID CWiaLog::WriteLogSessionHeader()
{
SYSTEMTIME stCurrentTime;
TCHAR szFmtDate[64] = {0};
TCHAR szFmtTime[64] = {0};
TCHAR szTextBuffer[128];
//
// Format TIME and DATE
//
GetLocalTime(&stCurrentTime);
FormatStdDate( &stCurrentTime, szFmtDate, sizeof(szFmtDate) / sizeof(szFmtDate[0]) - 1);
FormatStdTime( &stCurrentTime, szFmtTime);
//
// write formatted data to TEXT buffer
//
_sntprintf(szTextBuffer,
sizeof(szTextBuffer)/sizeof(szTextBuffer[0]),
szOpenedLog,
m_szFmtDLLName,
szFmtDate,
szFmtTime);
szTextBuffer[sizeof(szTextBuffer)/sizeof(szTextBuffer[0]) - 1] = TEXT('\0');
//
// write TEXT buffer to log
//
WriteStringToLog(szTextBuffer, FLUSH_STATE);
}
/**************************************************************************\
* QueryLoggingSettings()
*
* Read the registry and set the logging settings.
*
*
* Arguments:
*
* none
*
* Return Value:
*
* status
*
* History:
*
* 8/23/1999 Original Version
*
\**************************************************************************/
BOOL CWiaLog::QueryLoggingSettings()
{
DWORD dwLevel = 0;
DWORD dwMode = 0;
//
// read settings from the registry
//
RegEntry re(REGSTR_PATH_STICONTROL REGSTR_PATH_LOGGING,HKEY_LOCAL_MACHINE);
if (re.IsValid()) {
m_dwMaxSize = re.GetNumber(REGSTR_VAL_LOG_MAXSIZE,WIA_MAX_LOG_SIZE);
}
//
// read report mode flags
//
re.MoveToSubKey(m_szKeyName);
if (re.IsValid()) {
dwLevel = re.GetNumber(REGSTR_VAL_LOG_LEVEL,WIALOG_ERROR)
& WIALOG_MESSAGE_TYPE_MASK;
dwMode = re.GetNumber(REGSTR_VAL_LOG_MODE,WIALOG_ADD_THREAD|WIALOG_ADD_MODULE)
& WIALOG_MESSAGE_FLAGS_MASK;
m_lDetail = re.GetNumber(REGSTR_VAL_LOG_DETAIL,WIALOG_NO_LEVEL);
//
// set truncate log on boot options
//
DWORD dwTruncate = -1;
dwTruncate = re.GetNumber(REGSTR_VAL_LOG_TRUNCATE_ON_BOOT,FALSE);
if (dwTruncate == 0)
m_bTruncate = FALSE;
else
m_bTruncate = TRUE;
//
// set clear log on boot options
//
DWORD dwClear = -1;
dwClear = re.GetNumber(REGSTR_VAL_LOG_CLEARLOG_ON_BOOT,TRUE);
if (dwClear == 0)
m_bClear = FALSE;
else
m_bClear = TRUE;
//
// set debugger logging options
//
DWORD dwDebugLogging = -1;
dwDebugLogging = re.GetNumber(REGSTR_VAL_LOG_TO_DEBUGGER,FALSE);
if (dwDebugLogging == 0)
m_bLogToDebugger = FALSE;
else
m_bLogToDebugger = TRUE;
}
//
// set report mode
//
m_dwReportMode = dwLevel | dwMode;
//
// set UI (window) logging options
//
if(m_dwReportMode & WIALOG_UI)
m_bLogToUI = TRUE;
else
m_bLogToUI = FALSE;
return TRUE;
}
/**************************************************************************\
* ConstructText()
*
* Constructs TEXT according to Logging settings
*
*
* Arguments:
*
* pchBuffer - buffer for the formatted text
* cbBuffer - Buffer size
*
*
* Return Value:
*
* status
*
* History:
*
* 8/23/1999 Original Version
*
\**************************************************************************/
VOID CWiaLog::ConstructText()
{
//
// set string constructor to zero
//
CSimpleString csHeader;
CSimpleString csBuffer;
CSimpleString csModeText;
//
// add thread id
//
if(m_dwReportMode & WIALOG_ADD_THREAD) {
csBuffer.Format(TEXT("[%08X] "), ::GetCurrentThreadId());
csModeText += csBuffer;
csHeader += TEXT("[ Thread ] ");
}
//
// add module name
//
if(m_dwReportMode & WIALOG_ADD_MODULE) {
csBuffer.Format(TEXT("%s "), m_szFmtDLLName);
csModeText += csBuffer;
csHeader += TEXT("[ Module ] ");
}
//
// add time
//
if(m_dwReportMode & WIALOG_ADD_TIME) {
SYSTEMTIME stCurrentTime;
TCHAR szFmtTime[40];
GetLocalTime(&stCurrentTime);
FormatStdTime(&stCurrentTime, szFmtTime);
csBuffer.Format(TEXT(" %s "), szFmtTime);
csModeText += csBuffer;
csHeader += TEXT("[ HH:MM:SS.ms ] ");
}
//
// Copy the log text into m_szModeText
//
lstrcpyn(m_szModeText, csModeText.String(), sizeof(m_szColumnHeader)/sizeof(m_szColumnHeader[0]));
m_szModeText[sizeof(m_szModeText)/sizeof(m_szModeText[0]) - 1] = TEXT('\0');
//
// add column header if needed
//
if(csHeader.Compare(m_szColumnHeader) != 0) {
lstrcpyn(m_szColumnHeader,csHeader.String(), sizeof(m_szColumnHeader)/sizeof(m_szColumnHeader[0]));
m_szColumnHeader[sizeof(m_szColumnHeader)/sizeof(m_szColumnHeader[0]) - 1] = TEXT('\0');
WriteStringToLog(TEXT(" "), FLUSH_STATE);
WriteStringToLog(TEXT("============================================================================="), FLUSH_STATE);
WriteStringToLog(m_szColumnHeader, FLUSH_STATE);
WriteStringToLog(TEXT("============================================================================="), FLUSH_STATE);
WriteStringToLog(TEXT(" "), FLUSH_STATE);
}
}
/**************************************************************************\
* FormatDLLName()
*
* Formats the DLL name to be added to a LOG file
*
*
* Arguments:
*
* hInstance - Instance of the calling DLL
* pchBuffer - buffer for the formatted name
* cbBuffer - Buffer size
*
*
* Return Value:
*
* status
*
* History:
*
* 8/23/1999 Original Version
*
\**************************************************************************/
BOOL CWiaLog::FormatDLLName(HINSTANCE hInstance, TCHAR *pchBuffer, INT cchBuffer)
{
TCHAR lpfullpath[255];
TCHAR szModuleName[255]; // We know that the module name has to be <= ModuleFileName, so
// by having szModuleName be the same size, we are guranteed to have enough
// room (assuming lpFullPath is large enough for the ModuleFileName).
DWORD dwLength = 0;
dwLength = GetModuleFileName(hInstance,lpfullpath,sizeof(lpfullpath)/sizeof(lpfullpath[0]));
lpfullpath[sizeof(lpfullpath)/sizeof(lpfullpath[0]) - 1] = TEXT('\0');
if(dwLength == 0)
return FALSE;
//
// extract the file name from the full path
//
_tsplitpath(lpfullpath, NULL, NULL, szModuleName, NULL);
lstrcpyn(pchBuffer, szModuleName, cchBuffer);
pchBuffer[cchBuffer - 1] = TEXT('\0');
return TRUE;
}
/**************************************************************************\
* NeedsToBeFreed()
*
* Determines if the logger should free the allocated string.
* If the signature is found, it is stripped off the beginning of the string
* and the return of TRUE is set.
*
* Arguments:
*
* pBSTR - buffer for BSTRING
*
*
* Return Value:
*
* status
*
* History:
*
* 8/23/1999 Original Version
*
\**************************************************************************/
BOOL CWiaLog::NeedsToBeFreed(BSTR* pBSTR)
{
//
// NOTE: MAX_SIG_LEN *must* be larger than the string length of
// the signature!!!
//
WCHAR wszSig[MAX_SIG_LEN];
//
// check string to see if it is NULL, user may want to use a resource ID instead
//
if(*pBSTR == NULL) {
return FALSE;
}
//
// extract a possible signature from the beginning of the BSTR
//
wcsncpy(wszSig, *pBSTR, wcslen(szFormatSignature));
wszSig[wcslen(szFormatSignature)] = '\0';
//
// do they match?
//
if(wcscmp(wszSig,szFormatSignature) == 0) {
//
// They match, so strip off the signature from the BSTR, and
// return TRUE, (string can be freed by us).
//
wcscpy(*pBSTR,*pBSTR + wcslen(szFormatSignature));
return TRUE;
}
//
// signature did not match, must not be allocated by US
//
return FALSE;
}
/**************************************************************************\
* ProcessTruncation()
*
* Determines if the logger should truncate the file.
* The bottom part of the log file is copied, and copied back to the log file
* after the file has been truncated.
*
*
* Arguments:
*
* none
*
*
* Return Value:
*
* void
*
* History:
*
* 9/09/1999 Original Version
*
\**************************************************************************/
VOID CWiaLog::ProcessTruncation()
{
//
// determine file size
//
DWORD dwFileSize = 0;
BY_HANDLE_FILE_INFORMATION fi;
if (!GetFileInformationByHandle(m_hLogFile,&fi)) {
//DPRINTF(DM_TRACE,TEXT("WIALOG could not get file size for log file. "));
return;
}
dwFileSize = fi.nFileSizeLow;
if (dwFileSize > MAX_TRUNCATE_SIZE) {
//
// Allocate a temporary buffer
//
BYTE *pBuffer = NULL;
DWORD dwBytesRead = 0;
DWORD dwBytesWritten = 0;
pBuffer = (BYTE*)LocalAlloc(LPTR,MAX_TRUNCATE_SIZE);
if (pBuffer != NULL) {
BOOL bRead = FALSE;
//
// read buffered data
//
::SetFilePointer(m_hLogFile,dwFileSize - MAX_TRUNCATE_SIZE,NULL,FILE_BEGIN);
bRead = ::ReadFile(m_hLogFile,(VOID*)pBuffer,MAX_TRUNCATE_SIZE,&dwBytesRead,NULL);
//
// nuke existing file
//
::SetFilePointer(m_hLogFile, 0, NULL, FILE_BEGIN );
::SetEndOfFile(m_hLogFile );
if (bRead) {
//
// Write buffer to file
//
::WriteFile(m_hLogFile,pBuffer,MAX_TRUNCATE_SIZE,&dwBytesWritten,NULL);
//
// Write Truncation Header
//
WriteStringToLog(TEXT(" "), FLUSH_STATE);
WriteStringToLog(TEXT("============================================================================="), FLUSH_STATE);
TCHAR szHeader[MAX_PATH];
lstrcpy(szHeader,m_szFmtDLLName);
lstrcat(szHeader,TEXT(" REQUESTED A FILE TRUNCATION"));
WriteStringToLog(TEXT(" (Data above this marker is saved from a previous session)"), FLUSH_STATE);
WriteStringToLog(TEXT("============================================================================="), FLUSH_STATE);
WriteStringToLog(TEXT(" "), FLUSH_STATE);
}
LocalFree(pBuffer);
}
} else {
//
// File is too small, and does not need to be truncated
//
return;
}
}