1126 lines
20 KiB
C++
1126 lines
20 KiB
C++
// WMDMLogger.cpp : Implementation of CWMDMLogger
|
|
//
|
|
#include "stdafx.h"
|
|
#include "wmdmlog.h"
|
|
#include "WMDMLogger.h"
|
|
#define STRSAFE_NO_DEPRECATE
|
|
#include <strsafe.h>
|
|
|
|
#define REGKEY_WMDM_ROOT "Software\\Microsoft\\Windows Media Device Manager"
|
|
#define REGVAL_LOGENABLED "Log.Enabled"
|
|
#define REGVAL_LOGFILE "Log.Filename"
|
|
#define REGVAL_MAXSIZE "Log.MaxSize"
|
|
#define REGVAL_SHRINKTOSIZE "Log.ShrinkToSize"
|
|
|
|
#define MUTEX_REGISTRY "WMDMLogger.Registry.Mutex"
|
|
#define MUTEX_LOGFILE "WMDMLogger.LogFile.Mutex"
|
|
|
|
#define READ_BUF_SIZE 4*1024
|
|
|
|
#define CRLF "\r\n"
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CWMDMLogger
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
CWMDMLogger::CWMDMLogger()
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Save instance handle for easy access
|
|
//
|
|
m_hInst = _Module.GetModuleInstance();
|
|
if( !m_hInst )
|
|
{
|
|
ExitOnFail( hr = E_FAIL );
|
|
}
|
|
|
|
// Create the mutex'es for coordinating access to
|
|
// shared resources.
|
|
//
|
|
m_hMutexRegistry = CreateMutex( NULL, FALSE, MUTEX_REGISTRY );
|
|
if( !m_hMutexRegistry )
|
|
{
|
|
ExitOnFail( hr = E_FAIL );
|
|
}
|
|
m_hMutexLogFile = CreateMutex( NULL, FALSE, MUTEX_LOGFILE );
|
|
if( !m_hMutexLogFile )
|
|
{
|
|
ExitOnFail( hr = E_FAIL );
|
|
}
|
|
|
|
// Get the initial values from the registry. For values that
|
|
// don't exist in the registry, the defaults will be used
|
|
//
|
|
hr = hrLoadRegistryValues();
|
|
|
|
lExit:
|
|
|
|
// Save the return code from the constructor so it can be checked
|
|
// in public methods.
|
|
//
|
|
m_hrInit = hr;
|
|
}
|
|
|
|
CWMDMLogger::~CWMDMLogger()
|
|
{
|
|
// Close the mutex handles
|
|
//
|
|
if( NULL != m_hMutexRegistry )
|
|
{
|
|
CloseHandle( m_hMutexRegistry );
|
|
}
|
|
if( NULL != m_hMutexLogFile )
|
|
{
|
|
CloseHandle( m_hMutexLogFile );
|
|
}
|
|
}
|
|
|
|
HRESULT CWMDMLogger::hrWaitForAccess( HANDLE hMutex )
|
|
{
|
|
HRESULT hr;
|
|
DWORD dwWaitRetVal;
|
|
static DWORD dwTimeout = 0;
|
|
static BOOL fHaveTimeout = FALSE;
|
|
|
|
if( !fHaveTimeout )
|
|
{
|
|
hr = hrGetResourceDword( IDS_MUTEX_TIMEOUT, &dwTimeout );
|
|
ExitOnFail( hr );
|
|
|
|
fHaveTimeout = TRUE;
|
|
}
|
|
|
|
if( 0 == dwTimeout )
|
|
{
|
|
dwTimeout = INFINITE;
|
|
}
|
|
|
|
dwWaitRetVal = WaitForSingleObject( hMutex, dwTimeout );
|
|
|
|
if( WAIT_FAILED == dwWaitRetVal )
|
|
{
|
|
ExitOnFail( hr = E_FAIL );
|
|
}
|
|
if( WAIT_TIMEOUT == dwWaitRetVal )
|
|
{
|
|
ExitOnFail( hr = E_ABORT );
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::hrGetResourceDword( UINT uStrID, LPDWORD pdw )
|
|
{
|
|
HRESULT hr;
|
|
CHAR szDword[64];
|
|
|
|
// Check params
|
|
//
|
|
if( !pdw )
|
|
{
|
|
hr = E_INVALIDARG;
|
|
ExitOnFail( hr );
|
|
}
|
|
|
|
LoadString( m_hInst, uStrID, szDword, sizeof(szDword) );
|
|
|
|
*pdw = (DWORD) atol( szDword );
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::hrGetDefaultFileName( LPSTR szFilename, DWORD cchFilename )
|
|
{
|
|
HRESULT hr;
|
|
UINT uRet;
|
|
CHAR szLogFile[MAX_PATH];
|
|
|
|
uRet = GetSystemDirectory( szFilename, cchFilename );
|
|
if( 0 == uRet )
|
|
{
|
|
ExitOnFail( hr = E_FAIL );
|
|
}
|
|
|
|
LoadString( m_hInst, IDS_DEF_LOGFILE, szLogFile, sizeof(szLogFile) );
|
|
|
|
AddPath( szFilename, szLogFile );
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::hrLoadRegistryValues()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fMutex = FALSE;
|
|
HKEY hKey = NULL;
|
|
LONG lRetVal;
|
|
DWORD dwType;
|
|
DWORD dwDataLen;
|
|
DWORD dwEnabled;
|
|
|
|
// Coordinate access to the shared registry value
|
|
//
|
|
hr = hrWaitForAccess( m_hMutexRegistry );
|
|
ExitOnFail( hr );
|
|
|
|
fMutex = TRUE;
|
|
|
|
// Open the root WMDM registry key
|
|
//
|
|
lRetVal = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
REGKEY_WMDM_ROOT,
|
|
0,
|
|
KEY_QUERY_VALUE | KEY_SET_VALUE,
|
|
&hKey
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal )
|
|
{
|
|
ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
|
|
}
|
|
|
|
// Get the enabled status of the logfile
|
|
//
|
|
dwDataLen = sizeof( dwEnabled );
|
|
|
|
lRetVal = RegQueryValueEx(
|
|
hKey,
|
|
REGVAL_LOGENABLED,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&dwEnabled,
|
|
&dwDataLen
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal || dwType != REG_DWORD )
|
|
{
|
|
// No existing value, use the default
|
|
//
|
|
hr = hrGetResourceDword( IDS_DEF_LOGENABLED, &dwEnabled );
|
|
ExitOnFail( hr );
|
|
}
|
|
|
|
m_fEnabled = ( dwEnabled != 0 );
|
|
|
|
// Check if the log filename value already exists
|
|
//
|
|
dwDataLen = sizeof( m_szFilename );
|
|
|
|
lRetVal = RegQueryValueEx(
|
|
hKey,
|
|
REGVAL_LOGFILE,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)m_szFilename,
|
|
&dwDataLen
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal || dwType != REG_SZ )
|
|
{
|
|
CHAR szDefLogFile[MAX_PATH];
|
|
|
|
// No existing value, so form the default log filename
|
|
//
|
|
hr = hrGetDefaultFileName( szDefLogFile, sizeof(szDefLogFile) );
|
|
ExitOnFail( hr );
|
|
|
|
// Set the default log filename
|
|
//
|
|
hr = hrSetLogFileName( szDefLogFile );
|
|
ExitOnFail( hr );
|
|
}
|
|
|
|
// Get the maximum size for the logfile
|
|
//
|
|
dwDataLen = sizeof( m_dwMaxSize );
|
|
|
|
lRetVal = RegQueryValueEx(
|
|
hKey,
|
|
REGVAL_MAXSIZE,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&m_dwMaxSize,
|
|
&dwDataLen
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal || dwType != REG_DWORD )
|
|
{
|
|
// No existing value, use the default
|
|
//
|
|
hr = hrGetResourceDword( IDS_DEF_MAXSIZE, &m_dwMaxSize );
|
|
ExitOnFail( hr );
|
|
}
|
|
|
|
// Get the shrink-to size for the logfile
|
|
//
|
|
dwDataLen = sizeof( m_dwShrinkToSize );
|
|
|
|
lRetVal = RegQueryValueEx(
|
|
hKey,
|
|
REGVAL_SHRINKTOSIZE,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&m_dwShrinkToSize,
|
|
&dwDataLen
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal || dwType != REG_DWORD )
|
|
{
|
|
// No existing value, use the default
|
|
//
|
|
hr = hrGetResourceDword( IDS_DEF_SHRINKTOSIZE, &m_dwShrinkToSize );
|
|
ExitOnFail( hr );
|
|
}
|
|
|
|
// Set the file size params
|
|
//
|
|
hr = hrSetSizeParams( m_dwMaxSize, m_dwShrinkToSize );
|
|
ExitOnFail( hr );
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
if( hKey )
|
|
{
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
// Release the mutex
|
|
//
|
|
if( fMutex )
|
|
{
|
|
ReleaseMutex( m_hMutexRegistry );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CWMDMLogger::hrSetLogFileName(
|
|
LPSTR pszFilename
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fMutex = FALSE;
|
|
HKEY hKey = NULL;
|
|
LONG lRetVal;
|
|
|
|
//
|
|
// Make sure that the new file name can be copied; if it fails we want to retain the old file
|
|
// name and fail the call.
|
|
//
|
|
if(lstrlen(pszFilename) >= MAX_PATH )
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
// Coordinate access to the shared registry value
|
|
//
|
|
hr = hrWaitForAccess( m_hMutexRegistry );
|
|
ExitOnFail( hr );
|
|
|
|
fMutex = TRUE;
|
|
|
|
|
|
// Open the root WMDM registry key
|
|
//
|
|
lRetVal = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
REGKEY_WMDM_ROOT,
|
|
0,
|
|
KEY_SET_VALUE,
|
|
&hKey
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal )
|
|
{
|
|
ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
|
|
}
|
|
|
|
// Set the LogFilename value
|
|
//
|
|
lRetVal = RegSetValueEx(
|
|
hKey,
|
|
REGVAL_LOGFILE,
|
|
0L,
|
|
REG_SZ,
|
|
(LPBYTE)pszFilename,
|
|
lstrlen(pszFilename)+1
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal )
|
|
{
|
|
ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
|
|
}
|
|
|
|
// Set the local member data to the new log filename
|
|
//
|
|
hr = StringCbCopy(m_szFilename, sizeof(m_szFilename), pszFilename);
|
|
if(FAILED(hr))
|
|
{
|
|
// we need to undo the registry setting.
|
|
goto lExit;
|
|
|
|
}
|
|
|
|
lExit:
|
|
|
|
if( hKey )
|
|
{
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
// Release the mutex
|
|
//
|
|
if( fMutex )
|
|
{
|
|
ReleaseMutex( m_hMutexRegistry );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::hrCheckFileSize( void )
|
|
{
|
|
HRESULT hr;
|
|
BOOL fMutex = FALSE;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
HANDLE hFileTemp = INVALID_HANDLE_VALUE;
|
|
LPBYTE lpbData = NULL;
|
|
DWORD dwSize;
|
|
CHAR szTempPath[MAX_PATH];
|
|
CHAR szTempFile[MAX_PATH];
|
|
|
|
// Coordinate access to the shared logfile
|
|
//
|
|
hr = hrWaitForAccess( m_hMutexLogFile );
|
|
ExitOnFail( hr );
|
|
|
|
fMutex = TRUE;
|
|
|
|
// Open the logfile
|
|
//
|
|
hFile = CreateFile(
|
|
m_szFilename,
|
|
GENERIC_READ,
|
|
0,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
if( INVALID_HANDLE_VALUE == hFile )
|
|
{
|
|
ExitOnFail( hr = E_ACCESSDENIED );
|
|
}
|
|
|
|
// Get the current size of the logfile
|
|
//
|
|
dwSize = GetFileSize( hFile, NULL );
|
|
|
|
// Check if file needs to be trimmed
|
|
//
|
|
if( dwSize > m_dwMaxSize )
|
|
{
|
|
// Trim file to approximately m_dwShrinkToSize bytes
|
|
//
|
|
DWORD dwTrimBytes = dwSize - m_dwShrinkToSize;
|
|
DWORD dwRead;
|
|
DWORD dwWritten;
|
|
|
|
// Get the temp directory
|
|
//
|
|
if( 0 == GetTempPath(sizeof(szTempPath), szTempPath) )
|
|
{
|
|
ExitOnFail( hr = E_FAIL );
|
|
}
|
|
|
|
// Create a temp filename
|
|
//
|
|
if( 0 == GetTempFileName(szTempPath, "WMDM", 0, szTempFile) )
|
|
{
|
|
ExitOnFail( hr = E_FAIL );
|
|
}
|
|
|
|
// Open the temp file for writing
|
|
//
|
|
hFileTemp = CreateFile(
|
|
szTempFile,
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
if( INVALID_HANDLE_VALUE == hFileTemp )
|
|
{
|
|
ExitOnFail( hr = E_ACCESSDENIED );
|
|
}
|
|
|
|
// Set the read pointer of the existing logfile to the
|
|
// approximate trim position
|
|
///
|
|
SetFilePointer( hFile, dwTrimBytes, NULL, FILE_BEGIN );
|
|
|
|
// Allocate buffer for file reads
|
|
//
|
|
lpbData = (LPBYTE) CoTaskMemAlloc( READ_BUF_SIZE );
|
|
if( !lpbData )
|
|
{
|
|
ExitOnFail( hr = E_OUTOFMEMORY );
|
|
}
|
|
|
|
// Read in the first chunk of the file, and search for the end of
|
|
// the current line (a CRLF). Write everything after that CRLF to
|
|
// the temp file. If thee is no CRLF, then write the entire packet
|
|
// to the temp file.
|
|
//
|
|
if( ReadFile(hFile, lpbData, READ_BUF_SIZE, &dwRead, NULL) && dwRead > 0 )
|
|
{
|
|
LPBYTE lpb = lpbData;
|
|
|
|
while( ((DWORD_PTR)lpb-(DWORD_PTR)lpbData < dwRead-1) && (*lpb != '\r' && *(lpb+1) != '\n') )
|
|
{
|
|
lpb++;
|
|
}
|
|
if( (DWORD_PTR)lpb-(DWORD_PTR)lpbData < dwRead-1 )
|
|
{
|
|
// Must have found a CRLF... skip it
|
|
lpb += 2;
|
|
}
|
|
else
|
|
{
|
|
// No CRLF found... write entire packet to temp file
|
|
lpb = lpbData;
|
|
}
|
|
WriteFile(
|
|
hFileTemp,
|
|
lpb,
|
|
(DWORD)(dwRead - ( (DWORD_PTR)lpb - (DWORD_PTR)lpbData )),
|
|
&dwWritten,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
// Read the rest of the logfile and write it to the temp file
|
|
//
|
|
while( ReadFile(hFile, lpbData, READ_BUF_SIZE, &dwRead, NULL) && dwRead > 0 )
|
|
{
|
|
WriteFile(
|
|
hFileTemp,
|
|
lpbData,
|
|
dwRead,
|
|
&dwWritten,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
// Close the open file handles
|
|
//
|
|
CloseHandle( hFile );
|
|
hFile = INVALID_HANDLE_VALUE;
|
|
|
|
CloseHandle( hFileTemp );
|
|
hFileTemp = INVALID_HANDLE_VALUE;
|
|
|
|
// Replace the current logfile with the temp file
|
|
//
|
|
DeleteFile( m_szFilename );
|
|
MoveFile( szTempFile, m_szFilename );
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
// Close any open file handles
|
|
//
|
|
if( INVALID_HANDLE_VALUE != hFile )
|
|
{
|
|
CloseHandle( hFile );
|
|
}
|
|
if( INVALID_HANDLE_VALUE != hFileTemp )
|
|
{
|
|
CloseHandle( hFileTemp );
|
|
}
|
|
|
|
// Free any allocated memory
|
|
//
|
|
if( lpbData )
|
|
{
|
|
CoTaskMemFree( lpbData );
|
|
}
|
|
|
|
// Release the mutex
|
|
//
|
|
if( fMutex )
|
|
{
|
|
ReleaseMutex( m_hMutexLogFile );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::hrSetSizeParams(
|
|
DWORD dwMaxSize,
|
|
DWORD dwShrinkToSize
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fMutex = FALSE;
|
|
HKEY hKey = NULL;
|
|
LONG lRetVal;
|
|
|
|
// Coordinate access to the shared registry value
|
|
//
|
|
hr = hrWaitForAccess( m_hMutexRegistry );
|
|
ExitOnFail( hr );
|
|
|
|
fMutex = TRUE;
|
|
|
|
// Open the root WMDM registry key
|
|
//
|
|
lRetVal = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
REGKEY_WMDM_ROOT,
|
|
0,
|
|
KEY_SET_VALUE,
|
|
&hKey
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal )
|
|
{
|
|
ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
|
|
}
|
|
|
|
// Set the MaxSize value
|
|
//
|
|
lRetVal = RegSetValueEx(
|
|
hKey,
|
|
REGVAL_MAXSIZE,
|
|
0L,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwMaxSize,
|
|
sizeof(dwMaxSize)
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal )
|
|
{
|
|
ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
|
|
}
|
|
|
|
// Set the ShrinkToSize value
|
|
//
|
|
lRetVal = RegSetValueEx(
|
|
hKey,
|
|
REGVAL_SHRINKTOSIZE,
|
|
0L,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwShrinkToSize,
|
|
sizeof(dwShrinkToSize)
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal )
|
|
{
|
|
ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
|
|
}
|
|
|
|
// Set the local member data
|
|
//
|
|
m_dwMaxSize = dwMaxSize;
|
|
m_dwShrinkToSize = dwShrinkToSize;
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
if( hKey )
|
|
{
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
// Release the mutex
|
|
//
|
|
if( fMutex )
|
|
{
|
|
ReleaseMutex( m_hMutexRegistry );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CWMDMLogger::hrEnable(
|
|
BOOL fEnable
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fMutex = FALSE;
|
|
HKEY hKey = NULL;
|
|
DWORD dwEnable = ( fEnable ? 1L : 0L );
|
|
LONG lRetVal;
|
|
|
|
// Coordinate access to the shared registry value
|
|
//
|
|
hr = hrWaitForAccess( m_hMutexRegistry );
|
|
ExitOnFail( hr );
|
|
|
|
fMutex = TRUE;
|
|
|
|
// Open the root WMDM registry key
|
|
//
|
|
lRetVal = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
REGKEY_WMDM_ROOT,
|
|
0,
|
|
KEY_SET_VALUE,
|
|
&hKey
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal )
|
|
{
|
|
ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
|
|
}
|
|
|
|
// Set the Enabled value
|
|
//
|
|
lRetVal = RegSetValueEx(
|
|
hKey,
|
|
REGVAL_LOGENABLED,
|
|
0L,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwEnable,
|
|
sizeof(dwEnable)
|
|
);
|
|
if( ERROR_SUCCESS != lRetVal )
|
|
{
|
|
ExitOnFail( hr = HRESULT_FROM_WIN32(lRetVal) );
|
|
}
|
|
|
|
// Set the local member data
|
|
//
|
|
m_fEnabled = fEnable;
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
if( hKey )
|
|
{
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
// Release the mutex
|
|
//
|
|
if( fMutex )
|
|
{
|
|
ReleaseMutex( m_hMutexRegistry );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IWMDMLogger Methods
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CWMDMLogger::GetLogFileName(
|
|
LPSTR pszFilename,
|
|
UINT nMaxChars
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Check init error status
|
|
//
|
|
ExitOnFail( hr = m_hrInit );
|
|
|
|
// Check for invalid arguments
|
|
//
|
|
if( !pszFilename )
|
|
{
|
|
ExitOnFail( hr = E_INVALIDARG );
|
|
}
|
|
|
|
// Make sure the log filename will fit in the output buffer
|
|
//
|
|
if( (UINT)lstrlen(m_szFilename)+1 > nMaxChars )
|
|
{
|
|
//BUGBUG: better return code
|
|
ExitOnFail( hr = E_FAIL );
|
|
}
|
|
|
|
// Copy the log filename to output buffer
|
|
//
|
|
lstrcpy( pszFilename, m_szFilename );
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::SetLogFileName(
|
|
LPSTR pszFilename
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Check init error status
|
|
//
|
|
ExitOnFail( hr = m_hrInit );
|
|
|
|
// Check for invalid arguments
|
|
//
|
|
if( !pszFilename )
|
|
{
|
|
ExitOnFail( hr = E_INVALIDARG );
|
|
}
|
|
|
|
hr = hrSetLogFileName( pszFilename );
|
|
|
|
lExit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CWMDMLogger::GetSizeParams(
|
|
LPDWORD pdwMaxSize,
|
|
LPDWORD pdwShrinkToSize
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Check init error status
|
|
//
|
|
ExitOnFail( hr = m_hrInit );
|
|
|
|
if( pdwMaxSize )
|
|
{
|
|
*pdwMaxSize = m_dwMaxSize;
|
|
}
|
|
if( pdwShrinkToSize )
|
|
{
|
|
*pdwShrinkToSize = m_dwShrinkToSize;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::SetSizeParams(
|
|
DWORD dwMaxSize,
|
|
DWORD dwShrinkToSize
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Check init error status
|
|
//
|
|
ExitOnFail( hr = m_hrInit );
|
|
|
|
// Check params
|
|
//
|
|
if( dwShrinkToSize >= dwMaxSize )
|
|
{
|
|
ExitOnFail( hr = E_INVALIDARG );
|
|
}
|
|
|
|
hr = hrSetSizeParams( dwMaxSize, dwShrinkToSize );
|
|
|
|
lExit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::IsEnabled(
|
|
BOOL *pfEnabled
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Check init error status
|
|
//
|
|
ExitOnFail( hr = m_hrInit );
|
|
|
|
if( pfEnabled )
|
|
{
|
|
*pfEnabled = m_fEnabled;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::Enable(
|
|
BOOL fEnable
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Check init error status
|
|
//
|
|
ExitOnFail( hr = m_hrInit );
|
|
|
|
hr = hrEnable( fEnable );
|
|
|
|
lExit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::LogString(
|
|
DWORD dwFlags,
|
|
LPSTR pszSrcName,
|
|
LPSTR pszLog
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
BOOL fMutex = FALSE;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
DWORD dwWritten;
|
|
CHAR szPreLog[MAX_PATH];
|
|
|
|
// Check init error status
|
|
//
|
|
ExitOnFail( hr = m_hrInit );
|
|
|
|
// Coordinate access to the shared logfile
|
|
//
|
|
hr = hrWaitForAccess( m_hMutexLogFile );
|
|
ExitOnFail( hr );
|
|
|
|
fMutex = TRUE;
|
|
|
|
// Check the file size params and adjust the file appropriately
|
|
//
|
|
hr = hrCheckFileSize();
|
|
ExitOnFail( hr );
|
|
|
|
// Open the logfile
|
|
//
|
|
hFile = CreateFile(
|
|
m_szFilename,
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
if( INVALID_HANDLE_VALUE == hFile )
|
|
{
|
|
ExitOnFail( hr = E_ACCESSDENIED );
|
|
}
|
|
|
|
// Seek to the end of the logfile
|
|
//
|
|
SetFilePointer( hFile, 0, NULL, FILE_END );
|
|
|
|
// Put timestamp on log entry unless the flags say not to
|
|
//
|
|
if( !(dwFlags & WMDM_LOG_NOTIMESTAMP) )
|
|
{
|
|
CHAR szFormat[MAX_PATH];
|
|
SYSTEMTIME sysTime;
|
|
|
|
GetLocalTime( &sysTime );
|
|
|
|
LoadString( m_hInst, IDS_LOG_DATETIME, szFormat, sizeof(szFormat) );
|
|
|
|
wsprintf(
|
|
szPreLog, szFormat,
|
|
sysTime.wYear, sysTime.wMonth, sysTime.wDay,
|
|
sysTime.wHour, sysTime.wMinute, sysTime.wSecond
|
|
);
|
|
|
|
WriteFile( hFile, szPreLog, lstrlen(szPreLog), &dwWritten, NULL );
|
|
}
|
|
|
|
// Log the component name
|
|
//
|
|
if( pszSrcName )
|
|
{
|
|
CHAR szFormat[MAX_PATH];
|
|
|
|
LoadString( m_hInst, IDS_LOG_SRCNAME, szFormat, sizeof(szFormat) );
|
|
wsprintf( szPreLog, szFormat, pszSrcName );
|
|
|
|
WriteFile( hFile, szPreLog, lstrlen(szPreLog), &dwWritten, NULL );
|
|
}
|
|
|
|
// Log the severity
|
|
//
|
|
if( dwFlags & WMDM_LOG_SEV_ERROR )
|
|
{
|
|
LoadString( m_hInst, IDS_LOG_SEV_ERROR, szPreLog, sizeof(szPreLog) );
|
|
}
|
|
else if( dwFlags & WMDM_LOG_SEV_WARN )
|
|
{
|
|
LoadString( m_hInst, IDS_LOG_SEV_WARN, szPreLog, sizeof(szPreLog) );
|
|
}
|
|
else if( dwFlags & WMDM_LOG_SEV_INFO )
|
|
{
|
|
LoadString( m_hInst, IDS_LOG_SEV_INFO, szPreLog, sizeof(szPreLog) );
|
|
}
|
|
else
|
|
{
|
|
*szPreLog = '\0';
|
|
}
|
|
|
|
WriteFile( hFile, szPreLog, lstrlen(szPreLog), &dwWritten, NULL );
|
|
|
|
// Write the logstring to the logfile followed by a CRLF
|
|
//
|
|
if( pszLog )
|
|
{
|
|
WriteFile( hFile, pszLog, lstrlen(pszLog), &dwWritten, NULL );
|
|
}
|
|
|
|
// End with a carriage return and line feed
|
|
//
|
|
WriteFile( hFile, CRLF, lstrlen(CRLF), &dwWritten, NULL );
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
if( INVALID_HANDLE_VALUE != hFile )
|
|
{
|
|
CloseHandle( hFile );
|
|
}
|
|
|
|
// Release the mutex
|
|
//
|
|
if( fMutex )
|
|
{
|
|
ReleaseMutex( m_hMutexLogFile );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CWMDMLogger::LogDword(
|
|
DWORD dwFlags,
|
|
LPSTR pszSrcName,
|
|
LPSTR pszLogFormat,
|
|
DWORD dwLog
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
LPSTR pszLog = NULL;
|
|
|
|
// Check init error status
|
|
//
|
|
ExitOnFail( hr = m_hrInit );
|
|
|
|
// Check params
|
|
//
|
|
if( !pszLogFormat )
|
|
{
|
|
ExitOnFail( hr = E_INVALIDARG );
|
|
}
|
|
|
|
// Allocate space for the final log text
|
|
//
|
|
pszLog = (LPSTR) CoTaskMemAlloc( MAX_WSPRINTF_BUF );
|
|
if( !pszLog )
|
|
{
|
|
ExitOnFail( hr = E_OUTOFMEMORY );
|
|
}
|
|
|
|
// Create log string
|
|
//
|
|
wsprintf( pszLog, pszLogFormat, dwLog );
|
|
|
|
// Log the string
|
|
//
|
|
hr = LogString( dwFlags, pszSrcName, pszLog );
|
|
|
|
lExit:
|
|
|
|
if( pszLog )
|
|
{
|
|
CoTaskMemFree( pszLog );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWMDMLogger::Reset(
|
|
void
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
BOOL fMutex = FALSE;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
|
|
// Check init error status
|
|
//
|
|
ExitOnFail( hr = m_hrInit );
|
|
|
|
// Coordinate access to the shared logfile
|
|
//
|
|
hr = hrWaitForAccess( m_hMutexLogFile );
|
|
ExitOnFail( hr );
|
|
|
|
fMutex = TRUE;
|
|
|
|
// Open the logfile with CREATE_ALWAYS to truncate the file
|
|
//
|
|
hFile = CreateFile(
|
|
m_szFilename,
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
if( INVALID_HANDLE_VALUE == hFile )
|
|
{
|
|
ExitOnFail( hr = E_ACCESSDENIED );
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
lExit:
|
|
|
|
if( INVALID_HANDLE_VALUE != hFile )
|
|
{
|
|
CloseHandle( hFile );
|
|
}
|
|
|
|
// Release the mutex
|
|
//
|
|
if( fMutex )
|
|
{
|
|
ReleaseMutex( m_hMutexLogFile );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|