328 lines
8.3 KiB
C++
328 lines
8.3 KiB
C++
/****************************************************************************
|
|
|
|
Copyright (c) Microsoft Corporation 1998
|
|
All rights reserved
|
|
|
|
***************************************************************************/
|
|
|
|
#include "pch.h"
|
|
DEFINE_MODULE("RIPREP")
|
|
#define LOG_OUTPUT_BUFFER_SIZE 256
|
|
|
|
//
|
|
// CreateDirectoryPath( )
|
|
//
|
|
// Creates the directory tree.
|
|
//
|
|
HRESULT
|
|
CreateDirectoryPath(
|
|
LPWSTR DirectoryPath )
|
|
{
|
|
PWCHAR p;
|
|
BOOL f;
|
|
DWORD attributes;
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Find the \ that indicates the root directory. There should be at least
|
|
// one \, but if there isn't, we just fall through.
|
|
//
|
|
|
|
// skip \\server\reminst\ part
|
|
p = wcschr( DirectoryPath, L'\\' );
|
|
Assert(p);
|
|
p = wcschr( p + 1, L'\\' );
|
|
Assert(p);
|
|
p = wcschr( p + 1, L'\\' );
|
|
Assert(p);
|
|
p = wcschr( p + 1, L'\\' );
|
|
Assert(p);
|
|
p = wcschr( p + 1, L'\\' );
|
|
if ( p != NULL ) {
|
|
|
|
//
|
|
// Find the \ that indicates the end of the first level directory. It's
|
|
// probable that there won't be another \, in which case we just fall
|
|
// through to creating the entire path.
|
|
//
|
|
|
|
p = wcschr( p + 1, L'\\' );
|
|
while ( p != NULL ) {
|
|
|
|
//
|
|
// Terminate the directory path at the current level.
|
|
//
|
|
|
|
*p = 0;
|
|
|
|
//
|
|
// Create a directory at the current level.
|
|
//
|
|
|
|
attributes = GetFileAttributes( DirectoryPath );
|
|
if ( 0xFFFFffff == attributes ) {
|
|
DebugMsg( "Creating %s\n", DirectoryPath );
|
|
f = CreateDirectory( DirectoryPath, NULL );
|
|
if ( !f ) {
|
|
hr = THR( HRESULT_FROM_WIN32( GetLastError( ) ) );
|
|
goto Error;
|
|
}
|
|
} else if ( (attributes & FILE_ATTRIBUTE_DIRECTORY) == 0 ) {
|
|
hr = THR(E_FAIL);
|
|
goto Error;
|
|
}
|
|
|
|
//
|
|
// Restore the \ and find the next one.
|
|
//
|
|
|
|
*p = L'\\';
|
|
p = wcschr( p + 1, L'\\' );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Create the target directory.
|
|
//
|
|
|
|
attributes = GetFileAttributes( DirectoryPath );
|
|
if ( 0xFFFFffff == attributes ) {
|
|
f = CreateDirectory( DirectoryPath, NULL );
|
|
if ( !f ) {
|
|
hr = THR( HRESULT_FROM_WIN32( GetLastError( ) ) );
|
|
}
|
|
}
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// LogOpen( )
|
|
//
|
|
// This function:
|
|
// - initializes the log critical section
|
|
// - enters the log critical section assuring only one thread is
|
|
// writing to the log at a time
|
|
// - creates the directory tree to the log file (if needed)
|
|
// - initializes the log file by:
|
|
// - creating a new log file if one doesn't exist.
|
|
// - opens an existing log file (for append)
|
|
// - appends a time/date stamp that the log was (re)openned.
|
|
//
|
|
// Use LogClose() to exit the log critical section.
|
|
//
|
|
// If there is a failure inside this function, the log critical
|
|
// section will be released before returning.
|
|
//
|
|
// Returns: S_OK - log critical section held and log open successfully
|
|
// Otherwize HRESULT error code.
|
|
//
|
|
HRESULT
|
|
LogOpen( )
|
|
{
|
|
TCHAR szFilePath[ MAX_PATH ];
|
|
CHAR szBuffer[ LOG_OUTPUT_BUFFER_SIZE ];
|
|
DWORD dwWritten;
|
|
HANDLE hTemp;
|
|
HRESULT hr;
|
|
SYSTEMTIME SystemTime;
|
|
BOOL CloseLog = FALSE;
|
|
|
|
if ( !g_pLogCritSect ) {
|
|
PCRITICAL_SECTION pNewCritSect =
|
|
(PCRITICAL_SECTION) LocalAlloc( LPTR, sizeof(CRITICAL_SECTION) );
|
|
if ( !pNewCritSect ) {
|
|
DebugMsg( "Out of Memory. Logging disabled.\n " );
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
InitializeCriticalSection( pNewCritSect );
|
|
|
|
// Make sure we only have one log critical section
|
|
InterlockedCompareExchangePointer( (PVOID *)&g_pLogCritSect, pNewCritSect, 0 );
|
|
if ( g_pLogCritSect != pNewCritSect ) {
|
|
DebugMsg( "Another thread already created the CS. Deleting this one.\n ");
|
|
DeleteCriticalSection( pNewCritSect );
|
|
LocalFree( pNewCritSect );
|
|
}
|
|
}
|
|
|
|
Assert( g_pLogCritSect );
|
|
EnterCriticalSection( g_pLogCritSect );
|
|
|
|
// Make sure the log file is open
|
|
if ( g_hLogFile == INVALID_HANDLE_VALUE ) {
|
|
|
|
if (!*g_ServerName) {
|
|
wsprintf(
|
|
szFilePath,
|
|
L"%s\\%s",
|
|
g_WinntDirectory,
|
|
L"riprep.log");
|
|
CloseLog = TRUE;
|
|
} else {
|
|
|
|
// Place
|
|
wsprintf( szFilePath,
|
|
TEXT("\\\\%s\\REMINST\\Setup\\%s\\%s\\%s\\%s"),
|
|
g_ServerName,
|
|
g_Language,
|
|
REMOTE_INSTALL_IMAGE_DIR_W,
|
|
g_MirrorDir,
|
|
g_Architecture );
|
|
|
|
// Create the directory tree
|
|
DebugMsg( "Creating log at %s\n", szFilePath );
|
|
hr = CreateDirectoryPath( szFilePath );
|
|
if (FAILED( hr )) goto Error;
|
|
|
|
wcscat( szFilePath, L"\\riprep.log" );
|
|
|
|
}
|
|
|
|
g_hLogFile = CreateFile( szFilePath,
|
|
GENERIC_WRITE | GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
NULL,
|
|
NULL );
|
|
if ( g_hLogFile == INVALID_HANDLE_VALUE ) {
|
|
hr = THR( HRESULT_FROM_WIN32( GetLastError( ) ) );
|
|
goto Error;
|
|
}
|
|
|
|
// Seek to the end
|
|
SetFilePointer( g_hLogFile, 0, NULL, FILE_END );
|
|
g_dwLogFileStartLow = GetFileSize( g_hLogFile, &g_dwLogFileStartHigh );
|
|
|
|
// Write the time/date the log was (re)openned.
|
|
GetLocalTime( &SystemTime );
|
|
wsprintfA( szBuffer,
|
|
"*\r\n* %02u/%02u/%04u %02u:%02u:%02u\r\n*\r\n",
|
|
SystemTime.wMonth,
|
|
SystemTime.wDay,
|
|
SystemTime.wYear,
|
|
SystemTime.wHour,
|
|
SystemTime.wMinute,
|
|
SystemTime.wSecond );
|
|
|
|
if ( !WriteFile( g_hLogFile, szBuffer, lstrlenA(szBuffer), &dwWritten, NULL ) ) {
|
|
hr = THR( HRESULT_FROM_WIN32( GetLastError( ) ) );
|
|
goto Error;
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
if (CloseLog) {
|
|
CloseHandle( g_hLogFile );
|
|
g_hLogFile = INVALID_HANDLE_VALUE;
|
|
}
|
|
return hr;
|
|
Error:
|
|
DebugMsg( "LogOpen: Failed hr = 0x%08x\n", hr );
|
|
if ( g_hLogFile != INVALID_HANDLE_VALUE ) {
|
|
CloseHandle( g_hLogFile );
|
|
g_hLogFile = INVALID_HANDLE_VALUE;
|
|
}
|
|
LeaveCriticalSection( g_pLogCritSect );
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// LogClose( )
|
|
//
|
|
// This actually just leaves the log critical section.
|
|
//
|
|
HRESULT
|
|
LogClose( )
|
|
{
|
|
Assert( g_pLogCritSect );
|
|
LeaveCriticalSection( g_pLogCritSect );
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//
|
|
// LogMsg()
|
|
//
|
|
void
|
|
LogMsg(
|
|
LPCSTR pszFormat,
|
|
... )
|
|
{
|
|
va_list valist;
|
|
CHAR szBuf[ LOG_OUTPUT_BUFFER_SIZE ];
|
|
DWORD dwWritten;
|
|
|
|
#ifdef UNICODE
|
|
WCHAR szFormat[ LOG_OUTPUT_BUFFER_SIZE ];
|
|
WCHAR szTmpBuf[ LOG_OUTPUT_BUFFER_SIZE ];
|
|
|
|
mbstowcs( szFormat, pszFormat, lstrlenA( pszFormat ) + 1 );
|
|
|
|
va_start( valist, pszFormat );
|
|
wvsprintf( szTmpBuf, szFormat, valist);
|
|
va_end( valist );
|
|
|
|
wcstombs( szBuf, szTmpBuf, wcslen( szTmpBuf ) + 1 );
|
|
#else
|
|
va_start( valist, pszFormat );
|
|
wvsprintf( szBuf, pszFormat, valist);
|
|
va_end( valist );
|
|
#endif // UNICODE
|
|
|
|
if ( LogOpen( ) ) {
|
|
return;
|
|
}
|
|
|
|
WriteFile( g_hLogFile, szBuf, lstrlenA(szBuf), &dwWritten, NULL );
|
|
|
|
LogClose( );
|
|
}
|
|
|
|
//
|
|
// LogMsg()
|
|
//
|
|
void
|
|
LogMsg(
|
|
LPCWSTR pszFormat,
|
|
... )
|
|
{
|
|
va_list valist;
|
|
CHAR szBuf[ LOG_OUTPUT_BUFFER_SIZE ];
|
|
DWORD dwWritten;
|
|
|
|
#ifdef UNICODE
|
|
WCHAR szTmpBuf[ LOG_OUTPUT_BUFFER_SIZE ];
|
|
|
|
va_start( valist, pszFormat );
|
|
wvsprintf( szTmpBuf, pszFormat, valist);
|
|
va_end( valist );
|
|
|
|
wcstombs( szBuf, szTmpBuf, wcslen( szTmpBuf ) + 1 );
|
|
#else
|
|
CHAR szFormat[ LOG_OUTPUT_BUFFER_SIZE ];
|
|
|
|
wcstombs( szFormat, pszFormat, wcslen( pszFormat ) + 1 );
|
|
|
|
va_start( valist, pszFormat );
|
|
wvsprintf( szBuf, szFormat, valist);
|
|
va_end( valist );
|
|
|
|
#endif // UNICODE
|
|
|
|
if ( LogOpen( ) ) {
|
|
return;
|
|
}
|
|
|
|
WriteFile( g_hLogFile, szBuf, lstrlenA(szBuf), &dwWritten, NULL );
|
|
|
|
LogClose( );
|
|
}
|
|
|