windows-nt/Source/XPSP1/NT/admin/pchealth/sr/nttest/srdiag/rpenum.cpp
2020-09-26 16:20:57 +08:00

261 lines
9 KiB
C++

/******************************************************************************
*
* Copyright (c) 2000 Microsoft Corporation
*
* Module Name:
* rplog.cpp
*
* Abstract:
* Tool for enumerating the restore points - forward/reverse
*
* Revision History:
* Brijesh Krishnaswami (brijeshk) 04/13/2000
* created
* 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.
*
*****************************************************************************/
//+---------------------------------------------------------------------------
//
// Common Includes
//
//----------------------------------------------------------------------------
#include <windows.h>
#include <shellapi.h>
#include <enumlogs.h>
#include <cab.h>
//+---------------------------------------------------------------------------
//
// Function Proto types
//
//----------------------------------------------------------------------------
void GetRPLogs(HFCI hc, char *szLogFile, WCHAR *szVolumePath);
void GetSRRPLogs(HFCI hc, WCHAR *szVolumePath, WCHAR *szRPDir, WCHAR *szFileName);
extern void GetRestoreGuid(char *szString); //Gets the restore point GUID, code in main.cpp
//+---------------------------------------------------------------------------
//
// Files to collect for each Restore Point, on all drives.
//
//----------------------------------------------------------------------------
WCHAR *wszRPFileList[] = { TEXT("restorepointsize"),
TEXT("drivetable.txt"),
TEXT("rp.log"),
TEXT("") };
//+---------------------------------------------------------------------------
//
// Types of restorepoints, based off of Brijesh's code
//
//----------------------------------------------------------------------------
WCHAR *szRPDescrip[] = { 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") };
//+---------------------------------------------------------------------------
//
// Simple Array's to say how to print the Month, and Day's
//
//----------------------------------------------------------------------------
WCHAR *szMonth[] = { TEXT("January"), TEXT("Feburary"), TEXT("March"), TEXT("April"), TEXT("May"), TEXT("June"),
TEXT("July"), TEXT("August"), TEXT("September"), TEXT("October"), TEXT("November"), TEXT("December") };
WCHAR *szDay[] = { TEXT("Sunday"), TEXT("Monday"), TEXT("Tuesday"), TEXT("Wednesday"), TEXT("Thursday"), TEXT("Friday"), TEXT("Saturday") };
//+---------------------------------------------------------------------------
//
// Function: RPEnumDrive
//
// 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 will get the restore point logs.
//
// Arguments: [hc] -- Handle to my current Cab
// [szLogFile] -- File name and path to where I log my restore point log information.
//
// Returns: void
//
// History: 9/21/00 SHeffner Created
//
//
//----------------------------------------------------------------------------
void RPEnumDrive(HFCI hc, char *szLogFile)
{
WCHAR szString[_MAX_PATH] = {TEXT("")}, szMount[_MAX_PATH] = {TEXT("")};
DWORD dLength = 0, dSize = 0;
HANDLE hVolume = 0, hMount = 0;
dLength = _MAX_PATH;
if( INVALID_HANDLE_VALUE != (hVolume = FindFirstVolume( szString, dLength)) )
{
do
{
dLength = dSize = _MAX_PATH;
//Check to make sure that this is a fixed volume, and then get the change log, else skip.
if ( DRIVE_FIXED == GetDriveType(szString) )
{
//First get the Friendly name for the current Volume, and get log
GetVolumePathNamesForVolumeName(szString, szMount, _MAX_PATH, &dSize);
GetRPLogs(hc, szLogFile, szMount);
}
} while (TRUE == FindNextVolume(hVolume, szString, dLength) );
}
//Cleanup code
FindVolumeClose(hVolume);
}
//+---------------------------------------------------------------------------
//
// Function: GetRPLogs
//
// Synopsis: This will enumerate the restore points on the volume path that is provided, writting
// this information out the logfile specified.
//
// Arguments: [hc] -- Handle to my current Cab
// [szLogFile] -- File name and path to where I log my restore point log information.
// [szVolumePath] -- Path to the Volume for the restore point API to work.
//
// Returns: void
//
// History: 9/21/00 SHeffner Created
//
//
//----------------------------------------------------------------------------
void GetRPLogs(HFCI hc, char *szLogFile, WCHAR *szVolumePath)
{
INT64 i64Size=0;
int iCount=0;
WCHAR szString[_MAX_PATH] = {TEXT("")};
char szRestoreGuid[_MAX_PATH] = {""};
RESTOREPOINTINFOW pRpinfo;
FILETIME *ft;
SYSTEMTIME st;
FILE *fStream = NULL, *fStream2 = NULL;
//Initialization of the Restore point
CRestorePointEnum RPEnum(szVolumePath, TRUE, FALSE);
CRestorePoint RP;
DWORD dwRc;
//Get restore GUID, and open up log file, and write out our mount point
GetRestoreGuid(szRestoreGuid);
fStream = fopen(szLogFile, "a");
fprintf(fStream, "\nProcessing Mount Point [%S]\n", szVolumePath);
// 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.
swprintf(szString, L"%sSystem Volume Information\\_restore%S\\%s\\restorepointsize", szVolumePath, szRestoreGuid, RP.GetDir());
if( NULL != (fStream2 = _wfopen(szString, L"r")) )
{
fread(&i64Size, sizeof(i64Size), 1, fStream2);
fclose(fStream2);
}
else {
i64Size=0;
}
if (RP.GetName() == NULL) // not system-drive
{
//format should be field=value, field=value, ...
fprintf(fStream, "DirectoryName=%S, Size=%I64ld, Number=%ul\n",
RP.GetDir(), i64Size, RP.GetNum());
}
else
{
//Get the time, and then convert it to localsystemtime, and then pump out the rest of the DataStructures
ft = RP.GetTime();
FileTimeToSystemTime( ft, &st);
//format should be field=value, field=value, ...
fprintf(fStream, "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(), szRPDescrip[RP.GetType()], RP.GetName(),
RP.IsDefunct() ? TEXT("[Cancelled]") : TEXT("[VALID]"), RP.GetNum(), szDay[st.wDayOfWeek],
szMonth[st.wMonth-1], st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond);
}
//Now Add-in the files needed per restore point
iCount = 0;
while ( NULL != *wszRPFileList[iCount] )
{
GetSRRPLogs(hc, szVolumePath, RP.GetDir(), wszRPFileList[iCount]);
iCount++;
}
} while (ERROR_SUCCESS == (dwRc = RPEnum.FindNextRestorePoint(RP)) );
RPEnum.FindClose();
}
else
{
fprintf(fStream, "No restore points for Mount Point [%S]\n", szVolumePath);
}
//Close up file Handle
fclose (fStream); //close out the file handle
}
//+---------------------------------------------------------------------------
//
// Function: GetSRRPLogs
//
// Synopsis: Routine will figure out 1) where the file in question is, 2) copy it to the temp directory
// with the new name, 3) add to cab, 4) nuke temp file
//
// Arguments: [hc] -- Handle to my current Cab
// [szVolumePath] -- File name and path to where I log my restore point log information.
// [szRPDir] -- Name of the restore point directory
// [szFileName] -- Name of the file in the restore point directory to collect
//
// Returns: void
//
// History: 9/21/00 SHeffner Created
//
//
//----------------------------------------------------------------------------
void GetSRRPLogs(HFCI hc, WCHAR *szVolumePath, WCHAR *szRPDir, WCHAR *szFileName)
{
char *szTest[1], *pszLoc;
char szRestoreGuid[_MAX_PATH];
char szTemp[_MAX_PATH], szSource[_MAX_PATH], szDest[_MAX_PATH];
//Get restore GUID, and build the source path
GetRestoreGuid(szRestoreGuid);
sprintf(szSource, "%SSystem Volume Information\\_restore%s\\%S\\%S", szVolumePath, szRestoreGuid, szRPDir, szFileName);
//Build Dest Path, swap out the \ and a : for a -
sprintf(szTemp, "%S%S-%S", szVolumePath, szRPDir, szFileName);
while(NULL != (pszLoc = strchr(szTemp, '\\')) )
*pszLoc = '-';
while(NULL != (pszLoc = strchr(szTemp, ':')) )
*pszLoc = '-';
sprintf(szDest, "%s\\%s", getenv("TEMP"), szTemp);
//Copy to new location, overwrite if it exists.
CopyFileA(szSource, szDest, FALSE);
//Now Add to file to the cab file.
szTest[0] = szDest;
test_fci(hc, 1, szTest, "");
DeleteFileA(szDest);
}