Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

486 lines
12 KiB

/******************************************************************************
*
* Copyright (c) 2000 Microsoft Corporation
*
* Module Name:
* RPEnum.cxx
*
* Abstract:
* Tool for enumerating the restore points - forward/reverse
*
* Revision History:
*
* Brijesh Krishnaswami (brijeshk) 04/13/2000
* created
*
* Stephen Heffner (sheffner)
* I just copied this source, and using the existing API's so that
* srdiag will also be in sync as changes occur to the file
* structure.
*
* Weiyou Cui (weiyouc) 02-May-2001
* Rewritten
*
*****************************************************************************/
//+---------------------------------------------------------------------------
//
// Common Includes
//
//----------------------------------------------------------------------------
#include "SrHeader.hxx"
#include <shellapi.h>
#include <enumlogs.h>
#ifdef ARRAYSIZE
#undef ARRAYSIZE
#endif
#include "stdafx.h"
#include "srdiag.h"
//+---------------------------------------------------------------------------
//
// Function proto types
//
//----------------------------------------------------------------------------
HRESULT GetSRGuid(LPTSTR* pptszSRGuid);
HRESULT GetRPLogsOnVolume(MPC::Cabinet* pCab,
LPTSTR ptszLogFile,
LPTSTR ptszVolume);
//+---------------------------------------------------------------------------
//
// Simple Array's to say how to print the Months, Days
//
//----------------------------------------------------------------------------
LPCTSTR g_tszMonth[] =
{
TEXT("January"),
TEXT("Feburary"),
TEXT("March"),
TEXT("April"),
TEXT("May"),
TEXT("June"),
TEXT("July"),
TEXT("August"),
TEXT("September"),
TEXT("October"),
TEXT("November"),
TEXT("December")
};
LPCTSTR g_tszDay[] =
{
TEXT("Sunday"),
TEXT("Monday"),
TEXT("Tuesday"),
TEXT("Wednesday"),
TEXT("Thursday"),
TEXT("Friday"),
TEXT("Saturday")
};
//+---------------------------------------------------------------------------
//
// Files to collect for each Restore Point, on all drives.
//
//----------------------------------------------------------------------------
LPCTSTR g_tszRPFileList[] =
{
TEXT("restorepointsize"),
TEXT("drivetable.txt"),
TEXT("rp.log"),
};
//+---------------------------------------------------------------------------
//
// Types of restorepoints, based off of Brijesh's code
//
//----------------------------------------------------------------------------
LPCTSTR g_tszRPDescrip[] =
{
TEXT("APPLICATION_INSTALL"),
TEXT("APPLICATION_UNINSTALL"),
TEXT("DESKTOP_SETTING"),
TEXT("ACCESSIBILITY_SETTING"),
TEXT("OE_SETTING"),
TEXT("APPLICATION_RUN"),
TEXT("RESTORE"),
TEXT("CHECKPOINT"),
TEXT("WINDOWS_SHUTDOWN"),
TEXT("WINDOWS_BOOT"),
TEXT("DEVICE_DRIVER_CHANGE"),
TEXT("FIRSTRUN"),
TEXT("MODIFY_SETTINGS"),
TEXT("CANCELLED_OPERATION")
};
//+---------------------------------------------------------------------------
//
// Function: RPEnumDrives
//
// Synopsis: Via the FindFirstVolume, and FindNext get all of the valid
// volumes on the system. I then transulate this volume, to the
// actual path and then pass that information to GetRPLogs which
// gets the restore point logs.
//
// Arguments: [pCab] -- pointer to the cabinet file
// [ptszLogFile] -- The name of the log file
//
// Returns: HRESULT
//
// History: 02-May-2001
//
//
//----------------------------------------------------------------------------
HRESULT RPEnumDrives(MPC::Cabinet* pCab,
LPTSTR ptszLogFile)
{
HRESULT hr = S_OK;
DWORD dwSize = 0;
HANDLE hVolume = INVALID_HANDLE_VALUE;
BOOL fOK = FALSE;
TCHAR tszVolume[MAX_PATH];
TCHAR tszMount[MAX_PATH];
DH_VDATEPTRIN(pCab, MPC::Cabinet);
DH_VDATEPTRIN(ptszLogFile, TCHAR);
hVolume = FindFirstVolume(tszVolume, MAX_PATH);
if (INVALID_HANDLE_VALUE != hVolume)
{
do
{
dwSize = MAX_PATH;
//
// Check to make sure that this is a fixed volume, and then
// get the change log, else skip.
//
if (DRIVE_FIXED == GetDriveType(tszVolume))
{
//
// First get the Friendly name for the current Volume, and get log
//
fOK = GetVolumePathNamesForVolumeName(tszVolume,
tszMount,
MAX_PATH,
&dwSize);
DH_ABORTIF(!fOK,
HRESULT_FROM_WIN32(GetLastError()),
TEXT("GetVolumePathNamesForVolumeName"));
hr = GetRPLogsOnVolume(pCab,
ptszLogFile,
tszMount);
DH_HRCHECK_ABORT(hr, TEXT("GetRPLogsOnVolume"));
}
} while (FindNextVolume(hVolume, tszVolume, MAX_PATH));
}
ErrReturn:
if (INVALID_HANDLE_VALUE != hVolume)
{
FindVolumeClose(hVolume);
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: GetRPLogsOnVolume
//
// Synopsis: This will enumerate the restore points on the volume path
// that is provided, writting this information out to the logfile
// specified.
//
// Arguments: [pCab] -- Pointer to the cabinet object
// [ptszLogFile] -- Log file name
// [ptszVolume] -- Path to the Volume for the restore point API
// to work.
//
// Returns: HRESULT
//
// History: 02-May-2001 weiyouc Created
//
//----------------------------------------------------------------------------
HRESULT GetRPLogsOnVolume(MPC::Cabinet* pCab,
LPTSTR ptszLogFile,
LPTSTR ptszVolume)
{
HRESULT hr = S_OK;
INT64 i64Size = 0;
int iCount = 0;
LPTSTR ptszSRGuid = NULL;
FILE* fpLogFile = NULL;
FILE* fpRPLog = NULL;
FILETIME* pFileTime = NULL;
RESTOREPOINTINFOW pRpinfo;
SYSTEMTIME SysTime;
TCHAR tszString[MAX_PATH];
TCHAR tszSRFileName[MAX_PATH];
TCHAR tszFileNameInCab[MAX_PATH];
CRestorePoint RP;
DH_VDATEPTRIN(pCab, MPC::Cabinet*);
DH_VDATEPTRIN(ptszLogFile, TCHAR);
DH_VDATEPTRIN(ptszVolume, TCHAR);
//
// Initialization of the RestorePointEnum obejct
//
CRestorePointEnum RPEnum(ptszVolume, TRUE, FALSE);
//
// Get restore GUID
//
hr = GetSRGuid(&ptszSRGuid);
DH_HRCHECK_ABORT(hr, TEXT("GetSRGuid"));
//
// Open the log file for appending
//
fpLogFile = _tfopen(ptszLogFile, TEXT("a"));
DH_ABORTIF(NULL == fpLogFile,
E_FAIL,
TEXT("_tfopen"));
fprintf(fpLogFile, "\nProcessing Mount Point [%S]\n", ptszVolume);
//
// If we have a valid restore point, enumerate through all of them and
// log the results.
//
if (ERROR_SUCCESS == RPEnum.FindFirstRestorePoint(RP))
{
do
{
//Get RestorePoint Size for the restore point log.
_stprintf(tszString,
TEXT("%sSystem Volume Information\\_restore%S\\%s\\restorepointsize"),
ptszVolume,
ptszSRGuid,
RP.GetDir());
fpRPLog = _tfopen(tszString, TEXT("r"));
if (NULL != fpRPLog)
{
fread(&i64Size, sizeof(INT64), 1, fpRPLog);
fclose(fpRPLog);
}
else
{
i64Size=0;
}
//
// Get the time, and then convert it to localsystemtime,
// and then pump out the rest of the DataStructures
//
pFileTime = RP.GetTime();
FileTimeToSystemTime(pFileTime, &SysTime);
//
// format should be field=value, field=value, ...
//
fprintf(fpLogFile,
"DirectoryName=%S, "
"Size=%I64ld, "
"Type=%ld[%S], "
"RestorePointName=%S, "
"RestorePointStatus=%S, "
"Number=%ul, "
"Date=%S %S %lu, %lu %lu:%lu:%lu\n",
RP.GetDir(),
i64Size,
RP.GetType(),
g_tszRPDescrip[RP.GetType()],
RP.GetName(),
RP.IsDefunct() ? TEXT("[Cancelled]") : TEXT("[VALID]"),
RP.GetNum(),
g_tszDay[SysTime.wDayOfWeek],
g_tszMonth[SysTime.wMonth - 1],
SysTime.wDay,
SysTime.wYear,
SysTime.wHour,
SysTime.wMinute,
SysTime.wSecond);
//
// Now append the files needed per restore point
//
for (iCount = 0; iCount < ARRAYSIZE(g_tszRPFileList); iCount++)
{
//
// figure out which file we need to cab
//
_stprintf(tszSRFileName,
TEXT("%sSystem Volume Information\\_restore%s\\%s\\%s"),
ptszVolume,
ptszSRGuid,
RP.GetDir(),
g_tszRPFileList[iCount]);
//
// generate a new name for this file in the cab
//
//
// we also need to replace ":\" with "--"
//
_stprintf(tszFileNameInCab,
TEXT("%s"),
ptszVolume);
_stprintf((tszFileNameInCab + 1),
TEXT("--%s-%s"),
RP.GetDir(),
g_tszRPFileList[iCount]);
hr = pCab->AddFile(tszSRFileName, tszFileNameInCab);
DH_HRCHECK_ABORT(hr, TEXT("Cabinet::AddFile"));
iCount++;
}
} while (ERROR_SUCCESS == RPEnum.FindNextRestorePoint(RP));
RPEnum.FindClose();
}
else
{
fprintf(fpLogFile,
"No restore points for Mount Point [%S]\n",
ptszVolume);
}
ErrReturn:
if (NULL != fpLogFile)
{
fclose(fpLogFile);
}
if (NULL != fpRPLog)
{
fclose(fpRPLog);
}
CleanupTStr(&ptszSRGuid);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: GetSRGuid
//
// Synopsis: Get SR GUID.
//
// Arguments: [pptszSRGuid] -- The returned SR GUID
//
// Returns: HRESULT
//
// History: 02-May-2001
//
//
//----------------------------------------------------------------------------
HRESULT GetSRGuid(LPTSTR* pptszSRGuid)
{
HRESULT hr = S_OK;
long lResult = 0;
DWORD dwType = 0;
DWORD dwLength = MAX_PATH +1;
HKEY hKey = NULL;
TCHAR tszGuidStr[MAX_PATH + 1];
DH_VDATEPTROUT(pptszSRGuid, LPTSTR);
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
SR_CONFIG_REG_KEY,
0,
KEY_READ,
&hKey);
DH_ABORTIF(ERROR_SUCCESS != lResult,
E_FAIL,
TEXT("RegOpenKeyEx"));
lResult = RegQueryValueEx(hKey,
TEXT("MachineGuid"),
NULL,
&dwType,
(unsigned char*) tszGuidStr,
&dwLength);
DH_ABORTIF(ERROR_SUCCESS != lResult,
E_FAIL,
TEXT("RegQueryValueEx"));
hr = CopyString(tszGuidStr, pptszSRGuid);
DH_HRCHECK_ABORT(hr, TEXT("CopyString"));
ErrReturn:
if (NULL != hKey)
{
RegCloseKey(hKey);
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: GetDSOnSysVol
//
// Synopsis: Get the name of the data store on the system.
//
// Arguments: [pptszDsOnSys] -- data store name
//
// Returns: HRESULT
//
// History: 02-May-2001
//
//
//----------------------------------------------------------------------------
HRESULT GetDSOnSysVol(LPTSTR* pptszDsOnSys)
{
HRESULT hr = S_OK;
LPTSTR ptszSRGuid = NULL;
TCHAR tszDS[MAX_PATH + 1];
DH_VDATEPTROUT(pptszDsOnSys, LPTSTR);
hr = GetSRGuid(&ptszSRGuid);
DH_HRCHECK_ABORT(hr, TEXT("GetSRGuid"));
_stprintf(tszDS,
TEXT("%s\\System Volume Information\\_Restore%s\\"),
_tgetenv(TEXT("SYSTEMDRIVE")),
ptszSRGuid);
hr = CopyString(tszDS, pptszDsOnSys);
DH_HRCHECK_ABORT(hr, TEXT("CopyString"));
ErrReturn:
CleanupTStr(&ptszSRGuid);
return hr;
}