802 lines
20 KiB
C++
802 lines
20 KiB
C++
|
/******************************************************************************
|
||
|
*
|
||
|
* Copyright (c) 2000 Microsoft Corporation
|
||
|
*
|
||
|
* Module Name:
|
||
|
* respoint.cpp
|
||
|
*
|
||
|
* Abstract:
|
||
|
* CRestorePoint, CRestorePointEnum class functions
|
||
|
*
|
||
|
* Revision History:
|
||
|
* Brijesh Krishnaswami (brijeshk) 03/17/2000
|
||
|
* created
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
#include "srapi.h"
|
||
|
|
||
|
#ifdef THIS_FILE
|
||
|
#undef THIS_FILE
|
||
|
#endif
|
||
|
static char __szTraceSourceFile[] = __FILE__;
|
||
|
#define THIS_FILE __szTraceSourceFile
|
||
|
|
||
|
|
||
|
// constructors
|
||
|
|
||
|
// use this constructor to read in an existing rp
|
||
|
// then need to call Read() to initialize rp members
|
||
|
|
||
|
CRestorePoint::CRestorePoint()
|
||
|
{
|
||
|
m_pRPInfo = NULL;
|
||
|
lstrcpy(m_szRPDir, L"");
|
||
|
m_itCurChgLogEntry = m_ChgLogList.end();
|
||
|
m_fForward = TRUE;
|
||
|
m_fDefunct = FALSE;
|
||
|
}
|
||
|
|
||
|
// initialize
|
||
|
|
||
|
BOOL
|
||
|
CRestorePoint::Load(RESTOREPOINTINFOW *prpinfo)
|
||
|
{
|
||
|
if (prpinfo)
|
||
|
{
|
||
|
if (! m_pRPInfo)
|
||
|
{
|
||
|
m_pRPInfo = (RESTOREPOINTINFOW *) SRMemAlloc(sizeof(RESTOREPOINTINFOW));
|
||
|
if (! m_pRPInfo)
|
||
|
return FALSE;
|
||
|
}
|
||
|
CopyMemory(m_pRPInfo, prpinfo, sizeof(RESTOREPOINTINFOW));
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
// destructor
|
||
|
// call FindClose here
|
||
|
// if no enumeration was done, this is a no-op
|
||
|
|
||
|
CRestorePoint::~CRestorePoint()
|
||
|
{
|
||
|
if (m_pRPInfo)
|
||
|
SRMemFree(m_pRPInfo);
|
||
|
|
||
|
FindClose();
|
||
|
}
|
||
|
|
||
|
|
||
|
// return first/last change log entry in this restore point
|
||
|
// assumes Read() has already been called
|
||
|
|
||
|
DWORD
|
||
|
CRestorePoint::FindFirstChangeLogEntry(
|
||
|
LPWSTR pszDrive,
|
||
|
BOOL fForward,
|
||
|
CChangeLogEntry& cle)
|
||
|
{
|
||
|
DWORD dwRc = ERROR_SUCCESS;
|
||
|
WCHAR szChgLogPrefix[MAX_PATH];
|
||
|
WIN32_FIND_DATA FindData;
|
||
|
INT64 llSeqNum;
|
||
|
WCHAR szPath[MAX_PATH];
|
||
|
|
||
|
TENTER("CRestorePoint::FindFirstChangeLogEntry");
|
||
|
|
||
|
m_fForward = fForward;
|
||
|
lstrcpy(m_szDrive, pszDrive);
|
||
|
|
||
|
// read the first/last change log in this restore point
|
||
|
// all entries inside a change log will always be read in forward order
|
||
|
|
||
|
MakeRestorePath(szPath, m_szDrive, m_szRPDir);
|
||
|
wsprintf(szChgLogPrefix, L"%s\\%s", szPath, s_cszChangeLogPrefix);
|
||
|
|
||
|
if (! m_FindFile._FindFirstFile(szChgLogPrefix,
|
||
|
s_cszChangeLogSuffix,
|
||
|
&FindData,
|
||
|
m_fForward,
|
||
|
FALSE))
|
||
|
{
|
||
|
TRACE(0, "No changelog in %S", szPath);
|
||
|
dwRc = ERROR_NO_MORE_ITEMS;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
lstrcat(szPath, L"\\");
|
||
|
lstrcat(szPath, FindData.cFileName);
|
||
|
|
||
|
// build list of entries in increasing order of sequence number
|
||
|
|
||
|
dwRc = BuildList(szPath);
|
||
|
if (ERROR_SUCCESS != dwRc)
|
||
|
{
|
||
|
TRACE(0, "! BuildList : %ld", dwRc);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
TRACE(0, "Enumerating %S in %S", FindData.cFileName, m_szRPDir);
|
||
|
|
||
|
// if there was no entry in this change log, go to the next
|
||
|
|
||
|
if (m_ChgLogList.empty())
|
||
|
{
|
||
|
dwRc = FindNextChangeLogEntry(cle);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
// get the first/last entry
|
||
|
|
||
|
if (m_fForward)
|
||
|
{
|
||
|
m_itCurChgLogEntry = m_ChgLogList.begin();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_itCurChgLogEntry = m_ChgLogList.end();
|
||
|
m_itCurChgLogEntry--;
|
||
|
}
|
||
|
|
||
|
// read in the change log entry into the object
|
||
|
|
||
|
cle.Load(*m_itCurChgLogEntry, m_szRPDir);
|
||
|
|
||
|
done:
|
||
|
TLEAVE();
|
||
|
return dwRc;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// return next/prev change log entry in this restore point
|
||
|
// assumes Read() has already been called
|
||
|
|
||
|
DWORD
|
||
|
CRestorePoint::FindNextChangeLogEntry(
|
||
|
CChangeLogEntry& cle)
|
||
|
{
|
||
|
DWORD dwRc = ERROR_SUCCESS;
|
||
|
WCHAR szPath[MAX_PATH];
|
||
|
WCHAR szChangeLogPath[MAX_PATH];
|
||
|
WCHAR szChgLogPrefix[MAX_PATH];
|
||
|
WIN32_FIND_DATA FindData;
|
||
|
INT64 llSeqNum;
|
||
|
|
||
|
TENTER("CRestorePoint::FindNextChangeLogEntry");
|
||
|
|
||
|
// go to the next entry in the list
|
||
|
|
||
|
m_fForward ? m_itCurChgLogEntry++ : m_itCurChgLogEntry--;
|
||
|
|
||
|
|
||
|
// check if we've reached the end of this change log
|
||
|
// end is the same for both forward and reverse enumeration
|
||
|
|
||
|
if (m_itCurChgLogEntry == m_ChgLogList.end())
|
||
|
{
|
||
|
// if so, read the next change log into memory
|
||
|
|
||
|
// nuke the current list
|
||
|
FindClose();
|
||
|
|
||
|
|
||
|
MakeRestorePath(szPath, m_szDrive, m_szRPDir);
|
||
|
wsprintf(szChgLogPrefix, L"%s\\%s", szPath, s_cszChangeLogPrefix);
|
||
|
|
||
|
while (m_ChgLogList.empty())
|
||
|
{
|
||
|
if (FALSE == m_FindFile._FindNextFile(szChgLogPrefix,
|
||
|
s_cszChangeLogSuffix,
|
||
|
&FindData))
|
||
|
{
|
||
|
dwRc = ERROR_NO_MORE_ITEMS;
|
||
|
TRACE(0, "No more change logs");
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
lstrcpy(szChangeLogPath, szPath);
|
||
|
lstrcat(szChangeLogPath, L"\\");
|
||
|
lstrcat(szChangeLogPath, FindData.cFileName);
|
||
|
|
||
|
dwRc = BuildList(szChangeLogPath);
|
||
|
if (ERROR_SUCCESS != dwRc)
|
||
|
{
|
||
|
TRACE(0, "BuildList : error=%ld", dwRc);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
TRACE(0, "Enumerating %S in %S", FindData.cFileName, m_szRPDir);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// get the first/last entry
|
||
|
|
||
|
if (m_fForward)
|
||
|
{
|
||
|
m_itCurChgLogEntry = m_ChgLogList.begin();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_itCurChgLogEntry = m_ChgLogList.end();
|
||
|
m_itCurChgLogEntry--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// read in the change log entry fields into the object
|
||
|
|
||
|
cle.Load(*m_itCurChgLogEntry, m_szRPDir);
|
||
|
|
||
|
done:
|
||
|
TLEAVE();
|
||
|
return dwRc;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
CRestorePoint::BuildList(
|
||
|
LPWSTR pszChgLog)
|
||
|
{
|
||
|
DWORD dwRc = ERROR_INTERNAL_ERROR;
|
||
|
HANDLE hChgLog = INVALID_HANDLE_VALUE;
|
||
|
DWORD dwRead;
|
||
|
DWORD dwEntrySize;
|
||
|
PVOID pBlob = NULL;
|
||
|
SR_LOG_ENTRY* pEntry = NULL;
|
||
|
PSR_LOG_HEADER pLogHeader = NULL;
|
||
|
DWORD cbSize;
|
||
|
|
||
|
TENTER("CChangeLogEntry::BuildList");
|
||
|
|
||
|
if (FALSE==IsFileOwnedByAdminOrSystem(pszChgLog))
|
||
|
{
|
||
|
// this is not a valid log.
|
||
|
// ignore this log and go to the next one
|
||
|
TRACE(0, "Change log %S not owned by admin or system", pszChgLog);
|
||
|
dwRc = ERROR_SUCCESS;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
hChgLog = CreateFile(pszChgLog, // file name
|
||
|
GENERIC_READ, // access mode
|
||
|
FILE_SHARE_READ, // share mode
|
||
|
NULL, // SD
|
||
|
OPEN_EXISTING, // how to create
|
||
|
FILE_ATTRIBUTE_NORMAL, // file attributes
|
||
|
NULL);
|
||
|
|
||
|
if (INVALID_HANDLE_VALUE == hChgLog)
|
||
|
{
|
||
|
dwRc = GetLastError();
|
||
|
TRACE(0, "! CreateFile on %S : %ld", pszChgLog, dwRc);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
// read header size
|
||
|
|
||
|
if (FALSE == ReadFile(hChgLog,
|
||
|
&cbSize,
|
||
|
sizeof(DWORD),
|
||
|
&dwRead,
|
||
|
NULL) || dwRead == 0 || cbSize == 0)
|
||
|
{
|
||
|
// if the file could not be read,
|
||
|
// assume that it is a 0-sized log, and go to the next log
|
||
|
|
||
|
dwRc = GetLastError();
|
||
|
TRACE(0, "Zero sized log : %ld", pszChgLog, dwRc);
|
||
|
dwRc = ERROR_SUCCESS;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
pLogHeader = (SR_LOG_HEADER *) SRMemAlloc(cbSize);
|
||
|
if (! pLogHeader)
|
||
|
{
|
||
|
TRACE(0, "Out of memory");
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
// read header
|
||
|
|
||
|
pLogHeader->Header.RecordSize = cbSize;
|
||
|
if (FALSE == ReadFile(hChgLog,
|
||
|
(PVOID) ( ((BYTE *) pLogHeader) + sizeof(DWORD)),
|
||
|
cbSize - sizeof(DWORD),
|
||
|
&dwRead,
|
||
|
NULL))
|
||
|
{
|
||
|
dwRc = GetLastError();
|
||
|
TRACE(0, "! ReadFile on %S : %ld", pszChgLog, dwRc);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
// check log's integrity
|
||
|
|
||
|
if( pLogHeader->LogVersion != SR_LOG_VERSION ||
|
||
|
pLogHeader->MagicNum != SR_LOG_MAGIC_NUMBER )
|
||
|
{
|
||
|
TRACE(0, "! LogHeader for %S : invalid or corrupt", pszChgLog);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
// now read the entries
|
||
|
|
||
|
do
|
||
|
{
|
||
|
// get the size of the entry
|
||
|
|
||
|
if (FALSE == ReadFile(hChgLog, &dwEntrySize, sizeof(DWORD), &dwRead, NULL))
|
||
|
{
|
||
|
TRACE(0, "ReadFile failed, error=%ld", GetLastError());
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (0 == dwRead) // end of file
|
||
|
{
|
||
|
TRACE(0, "End of file");
|
||
|
dwRc = ERROR_NO_MORE_ITEMS;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (dwRead != sizeof(DWORD)) // error reading entry
|
||
|
{
|
||
|
TRACE(0, "Readfile could not read a DWORD");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (0 == dwEntrySize) // reached the last entry
|
||
|
{
|
||
|
TRACE(0, "No more entries");
|
||
|
dwRc = ERROR_NO_MORE_ITEMS;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
// get the entry itself
|
||
|
|
||
|
pEntry = (SR_LOG_ENTRY *) SRMemAlloc(dwEntrySize);
|
||
|
if (! pEntry)
|
||
|
{
|
||
|
TRACE(0, "Out of memory");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
pEntry->Header.RecordSize = dwEntrySize;
|
||
|
|
||
|
// skip the size field
|
||
|
|
||
|
pBlob = (PVOID) ((PBYTE) pEntry + sizeof(dwEntrySize));
|
||
|
|
||
|
if (FALSE == ReadFile(hChgLog, pBlob, dwEntrySize - sizeof(dwEntrySize), &dwRead, NULL))
|
||
|
{
|
||
|
TRACE(0, "! ReadFile on %S : %ld", pszChgLog, GetLastError());
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (dwRead != dwEntrySize - sizeof(dwEntrySize)) // error reading entry
|
||
|
{
|
||
|
TRACE(0, "! Readfile: ToRead=%ld, Read=%ld bytes",
|
||
|
dwEntrySize - sizeof(dwEntrySize), dwRead);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// insert entry into list
|
||
|
|
||
|
dwRc = InsertEntryIntoList(pEntry);
|
||
|
|
||
|
} while (ERROR_SUCCESS == dwRc);
|
||
|
|
||
|
if (ERROR_NO_MORE_ITEMS == dwRc)
|
||
|
{
|
||
|
dwRc = ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
if (INVALID_HANDLE_VALUE != hChgLog)
|
||
|
CloseHandle(hChgLog);
|
||
|
|
||
|
SRMemFree(pLogHeader);
|
||
|
|
||
|
TLEAVE();
|
||
|
return dwRc;
|
||
|
}
|
||
|
|
||
|
|
||
|
// release memory and empty the list
|
||
|
|
||
|
DWORD CRestorePoint::FindClose()
|
||
|
{
|
||
|
// nuke the list
|
||
|
|
||
|
for (m_itCurChgLogEntry = m_ChgLogList.begin();
|
||
|
m_itCurChgLogEntry != m_ChgLogList.end();
|
||
|
m_itCurChgLogEntry++)
|
||
|
{
|
||
|
SRMemFree(*m_itCurChgLogEntry);
|
||
|
}
|
||
|
|
||
|
m_ChgLogList.clear();
|
||
|
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
// insert change log entry into list
|
||
|
|
||
|
DWORD
|
||
|
CRestorePoint::InsertEntryIntoList(
|
||
|
SR_LOG_ENTRY* pEntry)
|
||
|
{
|
||
|
TENTER("CRestorePoint::InsertEntryIntoList");
|
||
|
|
||
|
m_ChgLogList.push_back(pEntry);
|
||
|
|
||
|
TLEAVE();
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
// populate members
|
||
|
|
||
|
DWORD
|
||
|
CRestorePoint::ReadLog()
|
||
|
{
|
||
|
DWORD dwRc = ERROR_SUCCESS;
|
||
|
WCHAR szLog[MAX_PATH];
|
||
|
WCHAR szSystemDrive[MAX_PATH];
|
||
|
DWORD dwRead;
|
||
|
|
||
|
TENTER("CRestorePoint::ReadLog");
|
||
|
|
||
|
// construct path of rp.log
|
||
|
|
||
|
GetSystemDrive(szSystemDrive);
|
||
|
MakeRestorePath(szLog, szSystemDrive, m_szRPDir);
|
||
|
lstrcat(szLog, L"\\");
|
||
|
lstrcat(szLog, s_cszRestorePointLogName);
|
||
|
|
||
|
HANDLE hFile = CreateFile (szLog, // file name
|
||
|
GENERIC_READ, // file access
|
||
|
FILE_SHARE_READ, // share mode
|
||
|
NULL, // SD
|
||
|
OPEN_EXISTING, // how to create
|
||
|
0, // file attributes
|
||
|
NULL); // handle to template file
|
||
|
if (INVALID_HANDLE_VALUE == hFile)
|
||
|
{
|
||
|
dwRc = GetLastError();
|
||
|
trace(0, "! CreateFile on %S : %ld", szLog, dwRc);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
|
||
|
// read the restore point info
|
||
|
|
||
|
if (! m_pRPInfo)
|
||
|
{
|
||
|
m_pRPInfo = (RESTOREPOINTINFOW *) SRMemAlloc(sizeof(RESTOREPOINTINFOW));
|
||
|
if (! m_pRPInfo)
|
||
|
{
|
||
|
dwRc = ERROR_OUTOFMEMORY;
|
||
|
trace(0, "SRMemAlloc failed");
|
||
|
goto done;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (FALSE == ReadFile(hFile, m_pRPInfo, sizeof(RESTOREPOINTINFOW), &dwRead, NULL) ||
|
||
|
dwRead != sizeof(RESTOREPOINTINFOW))
|
||
|
{
|
||
|
dwRc = GetLastError();
|
||
|
trace(0, "! ReadFile on %S : %ld", szLog, dwRc);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
m_fDefunct = (m_pRPInfo->dwRestorePtType == CANCELLED_OPERATION);
|
||
|
|
||
|
// read the creation time
|
||
|
if (FALSE == ReadFile(hFile, &m_Time, sizeof(m_Time), &dwRead, NULL) ||
|
||
|
dwRead != sizeof(m_Time))
|
||
|
{
|
||
|
dwRc = GetLastError();
|
||
|
trace(0, "! ReadFile on %S : %ld", szLog, dwRc);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
|
||
|
done:
|
||
|
if (INVALID_HANDLE_VALUE != hFile)
|
||
|
CloseHandle(hFile);
|
||
|
|
||
|
TLEAVE();
|
||
|
return dwRc;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
CRestorePoint::WriteLog()
|
||
|
{
|
||
|
DWORD dwRc = ERROR_SUCCESS;
|
||
|
WCHAR szLog[MAX_PATH];
|
||
|
WCHAR szSystemDrive[MAX_PATH];
|
||
|
DWORD dwWritten;
|
||
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||
|
|
||
|
TENTER("CRestorePoint::WriteLog");
|
||
|
|
||
|
if (! m_pRPInfo)
|
||
|
{
|
||
|
ASSERT(0);
|
||
|
dwRc = ERROR_INTERNAL_ERROR;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
// set the creation time to the current time
|
||
|
|
||
|
GetSystemTimeAsFileTime(&m_Time);
|
||
|
|
||
|
// construct path of rp.log
|
||
|
|
||
|
GetSystemDrive(szSystemDrive);
|
||
|
MakeRestorePath(szLog, szSystemDrive, m_szRPDir);
|
||
|
lstrcat(szLog, L"\\");
|
||
|
lstrcat(szLog, s_cszRestorePointLogName);
|
||
|
|
||
|
hFile = CreateFile (szLog, // file name
|
||
|
GENERIC_WRITE, // file access
|
||
|
0, // share mode
|
||
|
NULL, // SD
|
||
|
CREATE_ALWAYS, // how to create
|
||
|
FILE_FLAG_WRITE_THROUGH, // file attributes
|
||
|
NULL); // handle to template file
|
||
|
if (INVALID_HANDLE_VALUE == hFile)
|
||
|
{
|
||
|
dwRc = GetLastError();
|
||
|
trace(0, "! CreateFile on %S : %ld", szLog, dwRc);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
// write the restore point info
|
||
|
if (FALSE == WriteFile(hFile, m_pRPInfo, sizeof(RESTOREPOINTINFOW), &dwWritten, NULL))
|
||
|
{
|
||
|
dwRc = GetLastError();
|
||
|
trace(0, "! WriteFile on %S : %ld", szLog, dwRc);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
// write the creation time
|
||
|
if (FALSE == WriteFile(hFile, &m_Time, sizeof(m_Time), &dwWritten, NULL))
|
||
|
{
|
||
|
dwRc = GetLastError();
|
||
|
trace(0, "! WriteFile on %S : %ld", szLog, dwRc);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
|
||
|
done:
|
||
|
if (INVALID_HANDLE_VALUE != hFile)
|
||
|
CloseHandle(hFile);
|
||
|
|
||
|
TLEAVE();
|
||
|
return dwRc;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
CRestorePoint::DeleteLog()
|
||
|
{
|
||
|
WCHAR szLog[MAX_PATH];
|
||
|
WCHAR szSystemDrive[MAX_PATH];
|
||
|
|
||
|
GetSystemDrive(szSystemDrive);
|
||
|
MakeRestorePath(szLog, szSystemDrive, m_szRPDir);
|
||
|
lstrcat(szLog, L"\\");
|
||
|
lstrcat(szLog, s_cszRestorePointLogName);
|
||
|
|
||
|
return DeleteFile(szLog);
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
CRestorePoint::Cancel()
|
||
|
{
|
||
|
if (m_pRPInfo)
|
||
|
{
|
||
|
m_pRPInfo->dwRestorePtType = CANCELLED_OPERATION;
|
||
|
return WriteLog();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT(0);
|
||
|
return ERROR_INTERNAL_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
CRestorePoint::GetNum()
|
||
|
{
|
||
|
return GetID(m_szRPDir);
|
||
|
}
|
||
|
|
||
|
// read the size of the restore point folder from file
|
||
|
|
||
|
DWORD CRestorePoint::ReadSize (const WCHAR *pwszDrive, INT64 *pllSize)
|
||
|
{
|
||
|
DWORD dwErr = ERROR_SUCCESS;
|
||
|
DWORD cbRead = 0;
|
||
|
WCHAR wcsPath[MAX_PATH];
|
||
|
|
||
|
MakeRestorePath(wcsPath, pwszDrive, m_szRPDir);
|
||
|
lstrcat(wcsPath, L"\\");
|
||
|
lstrcat (wcsPath, s_cszRestorePointSize);
|
||
|
|
||
|
HANDLE hFile = CreateFileW ( wcsPath, // file name
|
||
|
GENERIC_READ, // file access
|
||
|
FILE_SHARE_READ, // share mode
|
||
|
NULL, // SD
|
||
|
OPEN_EXISTING, // how to create
|
||
|
0, // file attributes
|
||
|
NULL); // handle to template file
|
||
|
|
||
|
if (INVALID_HANDLE_VALUE == hFile)
|
||
|
{
|
||
|
dwErr = GetLastError();
|
||
|
return dwErr;
|
||
|
}
|
||
|
|
||
|
if (FALSE == ReadFile (hFile, (BYTE *) pllSize, sizeof(*pllSize),
|
||
|
&cbRead, NULL))
|
||
|
{
|
||
|
dwErr = GetLastError();
|
||
|
}
|
||
|
|
||
|
CloseHandle (hFile);
|
||
|
return dwErr;
|
||
|
}
|
||
|
|
||
|
|
||
|
// write the size of the restore point folder to file
|
||
|
|
||
|
DWORD CRestorePoint::WriteSize (const WCHAR *pwszDrive, INT64 llSize)
|
||
|
{
|
||
|
DWORD dwErr = ERROR_SUCCESS;
|
||
|
DWORD cbWritten = 0;
|
||
|
WCHAR wcsPath[MAX_PATH];
|
||
|
|
||
|
MakeRestorePath(wcsPath, pwszDrive, m_szRPDir);
|
||
|
lstrcat(wcsPath, L"\\");
|
||
|
lstrcat (wcsPath, s_cszRestorePointSize);
|
||
|
|
||
|
HANDLE hFile = CreateFileW ( wcsPath, // file name
|
||
|
GENERIC_WRITE, // file access
|
||
|
0, // share mode
|
||
|
NULL, // SD
|
||
|
CREATE_ALWAYS, // how to create
|
||
|
0, // file attributes
|
||
|
NULL); // handle to template file
|
||
|
|
||
|
if (INVALID_HANDLE_VALUE == hFile)
|
||
|
{
|
||
|
dwErr = GetLastError();
|
||
|
return dwErr;
|
||
|
}
|
||
|
|
||
|
if (FALSE == WriteFile (hFile, (BYTE *) &llSize, sizeof(llSize),
|
||
|
&cbWritten, NULL))
|
||
|
{
|
||
|
dwErr = GetLastError();
|
||
|
}
|
||
|
|
||
|
CloseHandle (hFile);
|
||
|
return dwErr;
|
||
|
}
|
||
|
|
||
|
|
||
|
// populate a changelogentry object
|
||
|
|
||
|
void
|
||
|
CChangeLogEntry::Load(SR_LOG_ENTRY *pentry, LPWSTR pszRPDir)
|
||
|
{
|
||
|
PSR_LOG_DEBUG_INFO pDebugRec = NULL;
|
||
|
|
||
|
_pentry = pentry;
|
||
|
|
||
|
_pszPath1 = _pszPath2 = _pszTemp = _pszProcess = _pszShortName = NULL;
|
||
|
_pbAcl = NULL;
|
||
|
_cbAcl = 0;
|
||
|
_fAclInline = FALSE;
|
||
|
lstrcpy(_pszRPDir, pszRPDir);
|
||
|
|
||
|
BYTE *pRec = (PBYTE) & _pentry->SubRecords;
|
||
|
|
||
|
//
|
||
|
// get source path
|
||
|
//
|
||
|
|
||
|
_pszPath1 = (LPWSTR) (pRec + sizeof(RECORD_HEADER));
|
||
|
|
||
|
//
|
||
|
// get temp path if exists
|
||
|
//
|
||
|
|
||
|
if (_pentry->EntryFlags & ENTRYFLAGS_TEMPPATH)
|
||
|
{
|
||
|
pRec += RECORD_SIZE(pRec);
|
||
|
_pszTemp = (LPWSTR) (pRec + sizeof(RECORD_HEADER));
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get second path if exists
|
||
|
//
|
||
|
|
||
|
if (_pentry->EntryFlags & ENTRYFLAGS_SECONDPATH)
|
||
|
{
|
||
|
pRec += RECORD_SIZE(pRec);
|
||
|
_pszPath2 = (LPWSTR) (pRec + sizeof(RECORD_HEADER));
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get acl info if exists
|
||
|
//
|
||
|
|
||
|
if (_pentry->EntryFlags & ENTRYFLAGS_ACLINFO)
|
||
|
{
|
||
|
pRec += RECORD_SIZE(pRec);
|
||
|
if (RECORD_TYPE(pRec) == RecordTypeAclInline)
|
||
|
{
|
||
|
_fAclInline = TRUE;
|
||
|
}
|
||
|
|
||
|
_pbAcl = (BYTE *) (pRec + sizeof(RECORD_HEADER));
|
||
|
_cbAcl = RECORD_SIZE(pRec) - sizeof(RECORD_HEADER);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get debug info if exists
|
||
|
//
|
||
|
|
||
|
if (_pentry->EntryFlags & ENTRYFLAGS_DEBUGINFO)
|
||
|
{
|
||
|
pRec += RECORD_SIZE(pRec);
|
||
|
pDebugRec = (PSR_LOG_DEBUG_INFO) pRec;
|
||
|
_pszProcess = (LPWSTR) (pDebugRec->ProcessName);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get shortname if exists
|
||
|
//
|
||
|
|
||
|
if (_pentry->EntryFlags & ENTRYFLAGS_SHORTNAME)
|
||
|
{
|
||
|
pRec += RECORD_SIZE(pRec);
|
||
|
_pszShortName = (LPWSTR) (pRec + sizeof(RECORD_HEADER));
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
// this function will check if any filepath length exceeds
|
||
|
// the max length that restore supports
|
||
|
// if so, it will return FALSE
|
||
|
BOOL
|
||
|
CChangeLogEntry::CheckPathLengths()
|
||
|
{
|
||
|
if (_pszPath1 && lstrlen(_pszPath1) > SR_MAX_FILENAME_PATH-1)
|
||
|
return FALSE;
|
||
|
if (_pszPath2 && lstrlen(_pszPath2) > SR_MAX_FILENAME_PATH-1)
|
||
|
return FALSE;
|
||
|
if (_pszTemp && lstrlen(_pszTemp) > SR_MAX_FILENAME_PATH-1)
|
||
|
return FALSE;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|