#include <windows.h> #include <lsapi.h> #include "debug.h" #include "request.h" #include "provider.h" #include "messages.h" #ifdef UNICODE # pragma message( "!! Windows 95 does not support UNICODE system APIs !!" ) #endif #define LOG_FILE_LINE_LENGTH ( 75 ) #define LS_MAX_COMMENT_LENGTH ( 256 ) static void ErrorBox( LPSTR pszMessageBoxText, LPSTR FileName, ULONG LineNumber ); void DebugAssert( LPSTR FailedAssertion, LPSTR FileName, ULONG LineNumber, LPSTR Message ) { #if DBG TCHAR szMessageBoxText[ 1024 ]; if ( NULL != Message ) { wsprintf( szMessageBoxText, TEXT("%hs\n\nAssertion failure: %hs\n\nFile %hs, line %lu."), Message, FailedAssertion, FileName, LineNumber ); } else { wsprintf( szMessageBoxText, TEXT("Assertion failure: %hs\n\nFile %hs, line %lu."), FailedAssertion, FileName, LineNumber ); } ErrorBox( szMessageBoxText, FileName, LineNumber ); #endif LogAddDwordEx( LOG_ERROR, LS_INTERNAL_ERROR, FileName, LineNumber, 0 ); } static void ErrorBox( LPSTR pszMessageBoxText, LPSTR FileName, ULONG LineNumber ) { MessageBox( NULL, pszMessageBoxText, TEXT( "License System Error in MSLSP32.DLL" ), MB_ICONEXCLAMATION | MB_OK | MB_DEFAULT_DESKTOP_ONLY ); } static char l_szSourceName[ 80 ] = ""; static HANDLE l_hEventLog = NULL; static HINSTANCE l_hEventDll = NULL; static FARPROC l_pRegisterEventSource = NULL; static FARPROC l_pReportEvent = NULL; static FARPROC l_pDeregisterEventSource = NULL; static char l_szLogFile[ MAX_PATH ] = ""; static BOOL l_bLogIsFile = TRUE; LS_STATUS_CODE LogCreate( LS_STR * pszSourceName ) { UINT uChars; if ( NULL == l_hEventLog ) { // try using event log (will fail on Win95) l_hEventDll = LoadLibrary( TEXT( "advapi32.dll" ) ); if ( NULL != l_hEventDll ) { l_pRegisterEventSource = GetProcAddress( l_hEventDll, TEXT( "RegisterEventSourceA" ) ); if ( NULL != l_pRegisterEventSource ) { l_pReportEvent = GetProcAddress( l_hEventDll, TEXT( "ReportEventA" ) ); if ( NULL != l_pReportEvent ) { l_pDeregisterEventSource = GetProcAddress( l_hEventDll, TEXT( "DeregisterEventSource" ) ); if ( NULL != l_pDeregisterEventSource ) { l_hEventLog = (void *) ( * l_pRegisterEventSource )( NULL, pszSourceName ); if ( NULL != l_hEventLog ) { l_bLogIsFile = FALSE; } } } } if ( NULL == l_hEventLog ) { FreeLibrary( l_hEventDll ); } } } if ( NULL == l_hEventLog ) { // try using a file ZeroMemory( l_szLogFile, sizeof( l_szLogFile ) ); uChars = GetSystemDirectory( l_szLogFile, sizeof( l_szLogFile ) / sizeof( l_szLogFile[0] ) ); if ( ( 0 != uChars ) && ( uChars + sizeof( "\\LLS\\" ) + lstrlen( pszSourceName ) <= sizeof( l_szLogFile ) / sizeof( l_szLogFile[0] ) ) ) { // create %SystemRoot%\System32\LLS, if it doesn't already exist lstrcat( l_szLogFile, TEXT( "\\LLS" ) ); CreateDirectory( l_szLogFile, NULL ); lstrcat( l_szLogFile, TEXT( "\\" ) ); lstrcat( l_szLogFile, pszSourceName ); lstrcat( l_szLogFile, ".log" ); l_hEventLog = CreateFile( l_szLogFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL ); if ( NULL != l_hEventLog ) { lstrcpy( l_szSourceName, pszSourceName ); l_bLogIsFile = TRUE; } } } #if DBG if ( NULL == l_hEventLog ) { ErrorBox( "Failed to initialize logging system.", __FILE__, __LINE__ ); } #endif return ( NULL != l_hEventLog ) ? LS_SUCCESS : LS_SYSTEM_ERROR; } LS_VOID LogDestroy( LS_VOID ) { if ( NULL != l_hEventLog ) { if ( l_bLogIsFile ) { if ( 0 == GetFileSize( l_hEventLog, NULL ) ) { CloseHandle( l_hEventLog ); DeleteFile( l_szLogFile ); } else { CloseHandle( l_hEventLog ); } } else { (* l_pDeregisterEventSource)( l_hEventLog ); FreeLibrary( l_hEventDll ); } l_hEventLog = NULL; } } LS_STATUS_CODE LogAddDwordEx( LOG_SEVERITY lsSeverity, LS_STATUS_CODE lsscError, LS_STR * pszFileName, DWORD dwLine, DWORD dwCode ) { char szLogMessage[ 1024 ]; BOOL ok; DWORD dwBytesWritten; char chSeverity; SYSTEMTIME stTime; WORD wSeverity; if ( NULL != l_hEventLog ) { if ( l_bLogIsFile ) { // use file switch ( lsSeverity ) { case LOG_INFORMATION: chSeverity = 'I'; break; case LOG_WARNING: chSeverity = 'W'; break; case LOG_ERROR: chSeverity = 'E'; break; default: chSeverity = '?'; break; } GetLocalTime( &stTime ); wsprintf( szLogMessage, "[%04d/%02d/%02d %02d:%02d:%02d.%03d] {%c} Message 0x%lX, code 0x%lX @ %ld/%ld\n", (int) stTime.wYear, (int) stTime.wMonth, (int) stTime.wDay, (int) stTime.wHour, (int) stTime.wMinute, (int) stTime.wSecond, (int) stTime.wMilliseconds, chSeverity, lsscError, dwCode, dwLine >> 24, dwLine ); ok = WriteFile( l_hEventLog, szLogMessage, lstrlen( szLogMessage ), &dwBytesWritten, NULL ); } else { // use event log * ( (DWORD *) szLogMessage ) = dwCode; * ( ( (DWORD *) szLogMessage ) + 1 ) = dwLine; switch ( lsSeverity ) { case LOG_INFORMATION: wSeverity = EVENTLOG_INFORMATION_TYPE; break; case LOG_WARNING: wSeverity = EVENTLOG_WARNING_TYPE; break; case LOG_ERROR: default: wSeverity = EVENTLOG_ERROR_TYPE; break; } ok = (BOOL) (* l_pReportEvent)( l_hEventLog, wSeverity, 0, lsscError, NULL, 0, 2 * sizeof( DWORD ), NULL, szLogMessage ); } #if DBG if ( ok ) { wsprintf( szLogMessage, "Log message 0x%lX generated with code 0x%lX.\n%s / %d", lsscError, dwCode, pszFileName, dwLine ); ErrorBox( szLogMessage, __FILE__, __LINE__ ); } else { wsprintf( szLogMessage, "Failed to generate %s log entry, error %ld:\n\n" "Message 0x%lX, code 0x%lX,\n" "%s / %d", l_bLogIsFile ? "file" : "event", GetLastError(), lsscError, dwCode, pszFileName, dwLine ); ErrorBox( szLogMessage, __FILE__, __LINE__ ); } #endif } return lsscError; } LS_VOID LogAddGrant( LS_HANDLE lshHandle, LS_STATUS_CODE lsscGrantStatus, LS_STR * pszComment ) { LS_STATUS_CODE lsscError; TCHAR szLogMessage[ 1024 ]; BOOL ok; DWORD dwBytesWritten; SYSTEMTIME stTime; DWORD nChars; LS_REQUEST_INFO * plsriRequestInfo; TCHAR szAppName[ MAX_PATH ] = TEXT("?"); TCHAR szUnitsReserved[ 32 ] = TEXT("?"); TCHAR szPublisherName[ LS_PUBLISHER_UNIQUE_SUBSTR_LENGTH ] = TEXT("?"); TCHAR szProductName[ LS_PRODUCT_UNIQUE_SUBSTR_LENGTH ] = TEXT("?"); TCHAR szVersion[ LS_VERSION_UNIQUE_SUBSTR_LENGTH ] = TEXT("?"); TCHAR szComment[ LS_MAX_COMMENT_LENGTH ] = TEXT(""); LPTSTR apszStrings[] = { szAppName, szUnitsReserved, szPublisherName, szProductName, szVersion, szComment }; DWORD dwMsgID; if ( NULL != l_hEventLog ) { // derive message id dwMsgID = ( LS_SUCCESS == lsscGrantStatus ) ? MSG_LS_GRANT_SUCCESS : ( 0x4000 | lsscGrantStatus ); // get name of running application nChars = GetModuleFileName( NULL, szAppName, sizeof( szAppName ) / sizeof( szAppName[0] ) ); lsscError = RequestListLock(); ASSERT( LS_SUCCESS == lsscError ); if ( LS_SUCCESS == lsscError ) { // look up the license request lsscError = RequestListGet( lshHandle, &plsriRequestInfo ); if ( LS_SUCCESS == lsscError ) { // get number of units requested wsprintf( szUnitsReserved, "%d", plsriRequestInfo->lsulUnitsReserved ); lsscError = LicenseListLock(); ASSERT( LS_SUCCESS == lsscError ); if ( LS_SUCCESS == lsscError ) { lsscError = LicenseNameGet( plsriRequestInfo->lslhLicenseHandle, szPublisherName, szProductName, szVersion ); ASSERT( LS_SUCCESS == lsscError ); LicenseListUnlock(); } } RequestListUnlock(); } // get comment if ( NULL != pszComment ) { ZeroMemory( szComment, sizeof( szComment ) ); lstrcpyn( szComment, pszComment, sizeof( szComment ) / sizeof( szComment[0] ) - 1 ); } if ( l_bLogIsFile ) { // use file GetLocalTime( &stTime ); wsprintf( szLogMessage, "[%04d/%02d/%02d %02d:%02d:%02d.%03d] {%c} ", (int) stTime.wYear, (int) stTime.wMonth, (int) stTime.wDay, (int) stTime.wHour, (int) stTime.wMinute, (int) stTime.wSecond, (int) stTime.wMilliseconds, ( MSG_LS_GRANT_SUCCESS == dwMsgID ) ? (TCHAR)'I' : (TCHAR)'E' ); nChars = lstrlen( szLogMessage ); // note that the last parameter is arbitrarily cast to a va_list * // this is to avoid a compiler warning; the FORMAT_MESSAGE_ARGUMENT_ARRAY // tells FormatMessage() that the parameter is a char **, but the function // prototype simply defines the parameter as a va_list *, generating a // warning on Alphas nChars = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY | LOG_FILE_LINE_LENGTH, ProviderModuleGet(), dwMsgID, GetSystemDefaultLangID(), &szLogMessage[ nChars ], sizeof( szLogMessage ) / sizeof( szLogMessage[0] ) - nChars - 2, (va_list *) apszStrings ); ASSERT( nChars > 0 ); if ( 0 == nChars ) { ok = FALSE; } else { lstrcat( szLogMessage, TEXT("\n\n") ); ok = WriteFile( l_hEventLog, szLogMessage, lstrlen( szLogMessage ), &dwBytesWritten, NULL ); } } else { ok = (BOOL) (* l_pReportEvent)( l_hEventLog, ( MSG_LS_GRANT_SUCCESS == dwMsgID ) ? EVENTLOG_INFORMATION_TYPE : EVENTLOG_ERROR_TYPE, 0, dwMsgID, NULL, 6, 0, apszStrings, NULL ); } #if DBG if ( !ok ) { wsprintf( szLogMessage, "Failed to generate %s log entry, error %ld:\n\n" "Grant status 0x%lX", l_bLogIsFile ? "file" : "event", GetLastError(), lsscGrantStatus ); ErrorBox( szLogMessage, __FILE__, __LINE__ ); } #endif } }