430 lines
10 KiB
C++
430 lines
10 KiB
C++
/******************************************************************************
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
logfile.cpp
|
|
|
|
Abstract:
|
|
This file contains the implementation of the ValidateLogFile() function,
|
|
which reads and validate restore operations log file.
|
|
|
|
Revision History:
|
|
Seong Kook Khang (SKKhang) 08/20/99
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
#include "stdwin.h"
|
|
#include "rstrpriv.h"
|
|
#include "srui_htm.h"
|
|
#include "rstrmgr.h"
|
|
#include "srapi.h"
|
|
|
|
static LPCWSTR s_cszLogPath = L"%SystemRoot%\\system32\\restore\\rstrlog.dat";
|
|
static LPCWSTR s_cszWinInitErr = L"%SystemRoot%\\wininit.err";
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL ReadStrAlign4( HANDLE hFile, LPWSTR pszStr )
|
|
{
|
|
BOOL fRet = FALSE;
|
|
DWORD dwLen;
|
|
DWORD dwRead;
|
|
|
|
if ( !::ReadFile( hFile, &dwLen, sizeof(DWORD), &dwRead, NULL ) || dwRead != sizeof(DWORD) )
|
|
{
|
|
goto Exit;
|
|
}
|
|
if ( dwRead > MAX_PATH+4 )
|
|
{
|
|
// Broken log file...
|
|
goto Exit;
|
|
}
|
|
if ( dwLen > 0 )
|
|
{
|
|
if ( !::ReadFile( hFile, pszStr, dwLen, &dwRead, NULL ) || dwRead != dwLen )
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
return( fRet );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CMappedFileRead class
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
class CMappedFileRead
|
|
{
|
|
public:
|
|
CMappedFileRead();
|
|
~CMappedFileRead();
|
|
|
|
// Operations
|
|
public:
|
|
void Close();
|
|
BOOL Open( LPCWSTR cszPath );
|
|
BOOL Read( LPVOID pBuf, DWORD cbBuf );
|
|
BOOL Read( DWORD *pdw );
|
|
BOOL ReadDynStr( LPWSTR szBuf, DWORD cchMax );
|
|
|
|
protected:
|
|
|
|
// Attributes
|
|
public:
|
|
DWORD GetAvail() { return( m_dwAvail ); }
|
|
|
|
protected:
|
|
WCHAR m_szPath[MAX_PATH];
|
|
DWORD m_dwSize;
|
|
HANDLE m_hFile;
|
|
HANDLE m_hMap;
|
|
LPBYTE m_pBuf;
|
|
LPBYTE m_pCur;
|
|
DWORD m_dwAvail;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMappedFileRead construction / destruction
|
|
|
|
CMappedFileRead::CMappedFileRead()
|
|
{
|
|
m_szPath[0] = L'\0';
|
|
m_dwSize = 0;
|
|
m_hFile = INVALID_HANDLE_VALUE;
|
|
m_hMap = INVALID_HANDLE_VALUE;
|
|
m_pBuf = NULL;
|
|
}
|
|
|
|
CMappedFileRead::~CMappedFileRead()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMappedFileRead operations
|
|
|
|
void CMappedFileRead::Close()
|
|
{
|
|
TraceFunctEnter("CMappedFileRead::Close");
|
|
|
|
if ( m_pBuf != NULL )
|
|
{
|
|
::UnmapViewOfFile( m_pBuf );
|
|
m_pBuf = NULL;
|
|
}
|
|
if ( m_hMap != INVALID_HANDLE_VALUE )
|
|
{
|
|
::CloseHandle( m_hMap );
|
|
m_hMap = INVALID_HANDLE_VALUE;
|
|
}
|
|
if ( m_hFile != INVALID_HANDLE_VALUE )
|
|
{
|
|
::CloseHandle( m_hFile );
|
|
m_hFile = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CMappedFileRead::Open( LPCWSTR cszPath )
|
|
{
|
|
TraceFunctEnter("CMappedFileRead::Open");
|
|
BOOL fRet = FALSE;
|
|
LPCWSTR cszErr;
|
|
|
|
Close();
|
|
|
|
m_hFile = ::CreateFile( cszPath, GENERIC_READ,
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
|
NULL, OPEN_EXISTING, 0, NULL );
|
|
if ( m_hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
cszErr = ::GetSysErrStr();
|
|
ErrorTrace(0, "::CreateFile failed - %ls", cszErr);
|
|
goto Exit;
|
|
}
|
|
m_dwSize = ::GetFileSize( m_hFile, NULL );
|
|
if ( m_dwSize == 0xFFFFFFFF )
|
|
{
|
|
cszErr = ::GetSysErrStr();
|
|
ErrorTrace(0, "::GetFileSize failed - %ls", cszErr);
|
|
goto Exit;
|
|
}
|
|
|
|
m_hMap = ::CreateFileMapping( m_hFile, NULL, PAGE_READONLY, 0, 0, NULL );
|
|
if ( m_hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
cszErr = ::GetSysErrStr();
|
|
ErrorTrace(0, "::CreateFileMapping failed - %ls", cszErr);
|
|
goto Exit;
|
|
}
|
|
|
|
m_pBuf = (LPBYTE)::MapViewOfFile( m_hMap, FILE_MAP_READ, 0, 0, 0 );
|
|
if ( m_pBuf == NULL )
|
|
{
|
|
cszErr = ::GetSysErrStr();
|
|
ErrorTrace(0, "::MapViewOfFile failed - %ls", cszErr);
|
|
goto Exit;
|
|
}
|
|
|
|
::lstrcpy( m_szPath, cszPath );
|
|
m_pCur = m_pBuf;
|
|
m_dwAvail = m_dwSize;
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
if ( !fRet )
|
|
Close();
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CMappedFileRead::Read( LPVOID pBuf, DWORD cbBuf )
|
|
{
|
|
TraceFunctEnter("CMappedFileRead::Read(LPVOID,DWORD)");
|
|
BOOL fRet = FALSE;
|
|
|
|
if ( cbBuf > m_dwAvail )
|
|
{
|
|
ErrorTrace(0, "Insufficient data - %d bytes (need=%d bytes)\n", m_dwAvail, cbBuf);
|
|
goto Exit;
|
|
}
|
|
|
|
::CopyMemory( pBuf, m_pCur, cbBuf );
|
|
|
|
m_pCur += cbBuf;
|
|
m_dwAvail -= cbBuf;
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CMappedFileRead::Read( DWORD *pdw )
|
|
{
|
|
TraceFunctEnter("CMappedFileRead::Read(DWORD*)");
|
|
BOOL fRet = FALSE;
|
|
|
|
if ( sizeof(DWORD) > m_dwAvail )
|
|
{
|
|
ErrorTrace(0, "Insufficient data - %d bytes (need=%d bytes)\n", m_dwAvail, sizeof(DWORD));
|
|
goto Exit;
|
|
}
|
|
|
|
*pdw = *((LPDWORD)m_pCur);
|
|
|
|
m_pCur += sizeof(DWORD);
|
|
m_dwAvail -= sizeof(DWORD);
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL CMappedFileRead::ReadDynStr( LPWSTR szBuf, DWORD cchMax )
|
|
{
|
|
TraceFunctEnter("CMappedFileRead::Read(LPWSTR,DWORD)");
|
|
BOOL fRet = FALSE;
|
|
DWORD dwLen;
|
|
|
|
// note, this "length" is in bytes, not chars.
|
|
if ( !Read( &dwLen ) )
|
|
goto Exit;
|
|
|
|
if ( dwLen == 0 )
|
|
{
|
|
szBuf[0] = L'\0';
|
|
goto Done;
|
|
}
|
|
|
|
if ( dwLen > cchMax*sizeof(WCHAR) )
|
|
{
|
|
ErrorTrace(0, "Invalid string length - %d (max=%d)\n", dwLen, cchMax);
|
|
goto Exit;
|
|
}
|
|
|
|
if ( !Read( szBuf, dwLen ) )
|
|
goto Exit;
|
|
|
|
Done:
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ValidateLogFile function
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
struct SRFINode
|
|
{
|
|
PSRFI pRFI;
|
|
SRFINode *pNext;
|
|
};
|
|
|
|
BOOL ValidateLogFile( BOOL *pfSilent, BOOL *pfUndo )
|
|
{
|
|
TraceFunctEnter("ValidateLogFile");
|
|
BOOL fRet = FALSE;
|
|
WCHAR szLogPath[MAX_PATH];
|
|
CMappedFileRead cMFR;
|
|
SRstrLogHdrBase sHdr1;
|
|
SRstrLogHdrV3 sHdr2;
|
|
SRstrLogHdrV3Ex sHdr3;
|
|
SRstrEntryHdr sEntHdr;
|
|
DWORD i;
|
|
DWORD dwFlags;
|
|
WCHAR szBuf1[SR_MAX_FILENAME_LENGTH];
|
|
WCHAR szBuf2[SR_MAX_FILENAME_LENGTH];
|
|
WCHAR szBuf3[SR_MAX_FILENAME_LENGTH];
|
|
PSRFI pRFI;
|
|
|
|
::ExpandEnvironmentStrings( s_cszLogPath, szLogPath, MAX_PATH );
|
|
|
|
if ( !cMFR.Open( szLogPath ) )
|
|
goto Exit;
|
|
|
|
if ( !cMFR.Read( &sHdr1, sizeof(sHdr1) ) )
|
|
goto Exit;
|
|
if ( ( sHdr1.dwSig1 != RSTRLOG_SIGNATURE1 ) ||
|
|
( sHdr1.dwSig2 != RSTRLOG_SIGNATURE2 ) )
|
|
{
|
|
ErrorTrace(0, "Invalid restore log file signature...");
|
|
goto Exit;
|
|
}
|
|
if ( HIWORD(sHdr1.dwVer) != RSTRLOG_VER_MAJOR )
|
|
{
|
|
ErrorTrace(0, "Unknown restore log file version - %d (0x%08X)\n", HIWORD(sHdr1.dwVer), sHdr1.dwVer);
|
|
goto Exit;
|
|
}
|
|
|
|
if ( !cMFR.Read( &sHdr2, sizeof(sHdr2) ) )
|
|
goto Exit;
|
|
if ( pfSilent != NULL )
|
|
*pfSilent = ( ( sHdr2.dwFlags & RLHF_SILENT ) != 0 );
|
|
if ( pfUndo != NULL )
|
|
*pfUndo = ( ( sHdr2.dwFlags & RLHF_UNDO ) != 0 );
|
|
|
|
g_pRstrMgr->SetRPsUsed( sHdr2.dwRPNum, sHdr2.dwRPNew );
|
|
DebugTrace(0, "RP ID = %d, # of Drives = %d, New RP=%d", sHdr2.dwRPNum, sHdr2.dwDrives, sHdr2.dwRPNew);
|
|
|
|
for ( i = 0; i < sHdr2.dwDrives; i++ )
|
|
{
|
|
if ( !cMFR.Read( &dwFlags ) )
|
|
goto Exit;
|
|
if ( !cMFR.ReadDynStr( szBuf1, MAX_PATH ) )
|
|
goto Exit;
|
|
if ( !cMFR.ReadDynStr( szBuf2, MAX_PATH ) )
|
|
goto Exit;
|
|
if ( !cMFR.ReadDynStr( szBuf3, MAX_PATH ) )
|
|
goto Exit;
|
|
DebugTrace(0, "Drv#%d - %08X, %ls, %ls, %ls", i, dwFlags, szBuf1, szBuf2, szBuf3);
|
|
// Just ignore drive table...
|
|
}
|
|
|
|
//if ( !cMFR.Read( &sHdr3, sizeof(sHdr3) ) )
|
|
// goto Exit;
|
|
//DebugTrace(0, "New RP ID = %d, # of Entries = %d", sHdr3.dwRPNew, sHdr3.dwCount);
|
|
|
|
for ( i = 0; cMFR.GetAvail() > 0; i++ )
|
|
{
|
|
if ( !cMFR.Read( &sEntHdr, sizeof(sEntHdr) ) )
|
|
goto Exit;
|
|
|
|
if ( sEntHdr.dwRes == RSTRRES_FAIL )
|
|
goto Exit;
|
|
|
|
if ( ( sEntHdr.dwID == RSTRLOGID_STARTUNDO ) ||
|
|
( sEntHdr.dwID == RSTRLOGID_ENDOFUNDO ) )
|
|
continue;
|
|
|
|
if ( sEntHdr.dwID == RSTRLOGID_ENDOFMAP )
|
|
{
|
|
if ( cMFR.GetAvail() > 0 )
|
|
{
|
|
ErrorTrace(0, "Unknown trailing data after the EndOfMap marker...");
|
|
// but ignore and continue...
|
|
}
|
|
break;
|
|
}
|
|
|
|
if ( !cMFR.ReadDynStr( szBuf1, SR_MAX_FILENAME_LENGTH ) )
|
|
goto Exit;
|
|
if ( !cMFR.ReadDynStr( szBuf2, SR_MAX_FILENAME_LENGTH ) )
|
|
goto Exit;
|
|
if ( !cMFR.ReadDynStr( szBuf3, SR_MAX_FILENAME_LENGTH ) )
|
|
goto Exit;
|
|
|
|
if ( sEntHdr.dwID == RSTRLOGID_COLLISION )
|
|
{
|
|
pRFI = new SRenamedFolderInfo;
|
|
if ( pRFI == NULL )
|
|
{
|
|
FatalTrace(0, "Insufficient memory...");
|
|
goto Exit;
|
|
}
|
|
pRFI->strOld = ::PathFindFileName( szBuf1 );
|
|
pRFI->strNew = ::PathFindFileName( szBuf2 );
|
|
::PathRemoveFileSpec( szBuf2 );
|
|
pRFI->strLoc = szBuf2;
|
|
|
|
if ( !g_pRstrMgr->AddRenamedFolder( pRFI ) )
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
cMFR.Close();
|
|
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
BOOL CheckWininitErr()
|
|
{
|
|
TraceFunctEnter("CheckWininitErr");
|
|
BOOL fRet = FALSE;
|
|
WCHAR szWinInitErr[MAX_PATH+1];
|
|
|
|
::ExpandEnvironmentStrings( s_cszWinInitErr, szWinInitErr, MAX_PATH );
|
|
if ( ::GetFileAttributes( szWinInitErr ) != 0xFFFFFFFF )
|
|
{
|
|
DebugTrace(TRACE_ID, "WININIT.ERR file exists");
|
|
goto Exit;
|
|
}
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
|
|
// end of file
|