Leaked source code of windows server 2003
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.
 
 
 
 
 
 

481 lines
15 KiB

#pragma warning(disable:4290)
#include <stdlib.h>
#include <time.h>
#include <Nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <wchar.h>
#include <stdio.h>
#include <oleauto.h>
#include <stddef.h>
#include "vs_assert.hxx"
#include <atlbase.h>
#include "vs_idl.hxx"
#include "vswriter.h"
#include "vsbackup.h"
#include "bsstring.hxx"
enum {
PrepareForBackup = 0,
DoSnapshotSet = 1,
BackupComplete = 2,
PreRestore = 3,
PostRestore = 4,
GatherWriterMetadata = 5,
GatherWriterStatus = 6,
MaxOperations = 7
};
const wchar_t* operationCodes[MaxOperations] = { L"-pfb",
L"-dss",
L"-bc",
L"-prer",
L"-postr",
L"-gwm",
L"-gws" };
const wchar_t* timeCode = L"-time";
wchar_t* programName = L"canceltest.exe";
void checker(HRESULT error, wchar_t* string);
HRESULT cancelTest(IVssAsync* async, LONG cancelDelay);
HRESULT waitTest(IVssAsync* async);
void parse(int argc, wchar_t* argv[], bool* operations, long& waitTime);
int findParam(wchar_t* findee);
CComBSTR runBackupTest(bool* cancel, long cancelDelay);
void runRestoreTest(bool* cancel, long cancelDelay, CComBSTR xmlData);
const wchar_t* WszFromRestoreMethod(VSS_RESTOREMETHOD_ENUM method);
const wchar_t* WszFromUsageType(VSS_USAGE_TYPE usage);
const wchar_t* GetStringFromWriterStatus(VSS_WRITER_STATE eWriterStatus);
void checkMetadata(IVssBackupComponents* components);
void checkStatus(IVssBackupComponents* components);
CBsString helpString();
extern "C" INT __cdecl wmain(int argc, wchar_t* argv[])
{
try {
bool operations[MaxOperations];
long waitTime = 0;
parse(argc, argv, operations, waitTime);
checker(CoInitializeEx(NULL, COINIT_MULTITHREADED),
L"CoInitializeEx");
CComBSTR xmlData = runBackupTest(operations, waitTime);
runRestoreTest(operations, waitTime, xmlData);
} catch(CBsString thrown) {
fwprintf(stderr, thrown);
exit(1);
}
}
void parse(int argc, wchar_t* argv[], bool* operations, long& waitTime)
{
memset(operations, 0, sizeof(bool) * MaxOperations);
// parse each command-line argument
for (int x = 1; x < argc; x++) {
int index = findParam(argv[x]);
if (index == -1) {
if (wcscmp(argv[x], timeCode) != 0) {
CBsString throwString = L"Invalid command line parameter\n\n"+ helpString();
throw throwString;
}
if (x == argc - 1) {
CBsString throwString = L"no value given for time parameter\n\n" + helpString();
throw throwString;
}
waitTime = wcstol(argv[++x], NULL, 10);
} else {
operations[index] = true;
}
}
}
CBsString helpString()
{
CBsString help;
help += L"Usage: ";
help += programName;
help += L" [<option-list>]\n\n";
help += L"[<option-list>] is zero or more of the following options\n";
help += timeCode;
help += L" <milliseconds>\tspecify milliseconds to wait before cancelling\n";
help += operationCodes[PrepareForBackup];
help += L"\t\t\tcancel the asynchronous call to PrepareForBackup\n";
help += operationCodes[DoSnapshotSet];
help += L"\t\t\tcancel the asynchronous call to DoSnapshotSet\n";
help += operationCodes[BackupComplete];
help += L"\t\t\tcancel the asynchronous call to BackupComplete\n";
help += operationCodes[PreRestore];
help += L"\t\t\tcancel the asynchronous call to PreRestore\n";
help += operationCodes[PostRestore];
help += L"\t\t\tcancel the asynchronous call to PostRestore\n";
help += operationCodes[GatherWriterMetadata];
help += L"\t\t\tcancel the asynchronous calls to GatherWriterMetadata\n";
help += operationCodes[GatherWriterStatus];
help += L"\t\t\tcancel the asynchronous calls to GatherWriterStatus\n";
return help;
}
int findParam(wchar_t* findee)
{
// find the parameter in the list of accepted parameters
for (int x = 0; x < MaxOperations; x++) {
if (wcscmp(operationCodes[x], findee) == 0)
return x;
}
return -1;
}
// run a backup test
CComBSTR runBackupTest(bool cancel[MaxOperations], long cancelDelay)
{
CComPtr<IVssBackupComponents> components;
checker(::CreateVssBackupComponents(&components), L"CreateVssBackupComponents");
checker(components->InitializeForBackup(), L"InitializeForBackup");
checker(components->SetBackupState(false, true, VSS_BT_FULL, false), L"SetBackupState");
CComPtr<IVssAsync> async;
checker(components->GatherWriterMetadata(&async), L"GatherWriterMetadata");
checker(cancel[GatherWriterMetadata] ? cancelTest(async, cancelDelay) : waitTest(async),
L"GatherWriterMetadata async");
checkMetadata(components);
async = NULL;
VSS_ID setId = GUID_NULL;
VSS_ID snapshotId = GUID_NULL;
checker(components->StartSnapshotSet(&setId),
L"StartSnapshotSet");
fwprintf(stderr, L"\nWriter Status after SSS \n");
checker(components->GatherWriterStatus(&async), L"GatherWriterStatus");
checker(cancel[GatherWriterStatus] ? cancelTest(async, cancelDelay) : waitTest(async),
L"GatherWriterStatus async");
checkStatus(components);
async = NULL;
checker(components->AddToSnapshotSet(L"C:\\", GUID_NULL, &snapshotId),
L"AddToSnapshotSet");
checker(components->PrepareForBackup(&async), L"PrepareForBackup");
checker(cancel[PrepareForBackup] ? cancelTest(async, cancelDelay) : waitTest(async),
L"PrepareForBackup async");
async = NULL;
fwprintf(stderr, L"\nWriter Status after PrepareForBackup \n");
checker(components->GatherWriterStatus(&async), L"GatherWriterStatus");
checker(cancel[GatherWriterStatus] ? cancelTest(async, cancelDelay) : waitTest(async),
L"GatherWriterStatus async");
checkStatus(components);
async = NULL;
checker(components->DoSnapshotSet(&async), L"DoSnapshotSet");
checker(cancel[DoSnapshotSet] ? cancelTest(async, cancelDelay) : waitTest(async),
L"DoSnapshotSet async");
async = NULL;
fwprintf(stderr, L"\nWriter Status after DoSnapshotSet\n");
checker(components->GatherWriterStatus(&async), L"GatherWriterStatus");
checker(cancel[GatherWriterStatus] ? cancelTest(async, cancelDelay) : waitTest(async),
L"GatherWriterStatus async");
checkStatus(components);
async = NULL;
checker(components->BackupComplete(&async), L"BackupComplete");
checker(cancel[BackupComplete] ? cancelTest(async, cancelDelay) : waitTest(async),
L"BackupComplete async");
async = NULL;
fwprintf(stderr, L"\nWriter Status after BackupComplete\n");
checker(components->GatherWriterStatus(&async), L"GatherWriterStatus");
checker(cancel[GatherWriterStatus] ? cancelTest(async, cancelDelay) : waitTest(async),
L"GatherWriterStatus async");
checkStatus(components);
CComBSTR xmlData;
checker(components->SaveAsXML(&xmlData), L"SaveAsXML");
return xmlData;
}
// run a restore test
void runRestoreTest(bool cancel[MaxOperations], long cancelDelay, CComBSTR xmlData)
{
CComPtr<IVssBackupComponents> components;
checker(::CreateVssBackupComponents(&components), L"CreateVssBackupComponents");
checker(components->InitializeForRestore(xmlData), L"InitializeForRestore");
CComPtr<IVssAsync> async;
checker(components->GatherWriterMetadata(&async), L"GatherWriterMetadata");
checker(cancel[GatherWriterMetadata] ? cancelTest(async, cancelDelay) : waitTest(async),
L"GatherWriterMetadata async");
// select all writer components
UINT numComponents = 0;
checker(components->GetWriterComponentsCount(&numComponents), L"numComponents");
for (UINT x = 0; x < numComponents; x++) {
CComPtr<IVssWriterComponentsExt> writerComponents;
checker(components->GetWriterComponents(x, &writerComponents), L"GetWriterComponents");
VSS_ID idWriter, idInstance;
UINT cComponents;
checker(writerComponents->GetComponentCount(&cComponents), L"GetComponentCount");
checker(writerComponents->GetWriterInfo(&idInstance, &idWriter), L"GetWriterInfo");
for (UINT y = 0; y < cComponents; y++) {
CComPtr<IVssComponent> writerComponent;
checker(writerComponents->GetComponent(y, &writerComponent), L"GetComponent");
CComBSTR logicalPath, name;
VSS_COMPONENT_TYPE ct;
checker(writerComponent->GetLogicalPath(&logicalPath), L"GetLogicalPath");
checker(writerComponent->GetComponentName(&name), L"GetComponentName");
checker(writerComponent->GetComponentType(&ct), L"GetComponentType");
checker(components->SetSelectedForRestore(idWriter, ct, logicalPath, name, true),
L"SetSelectedForRestore");
}
}
async = NULL;
checker(components->PreRestore(&async), L"GatherWriterMetadata");
checker(cancel[PreRestore] ? cancelTest(async, cancelDelay) : waitTest(async),
L"GatherWriterMetadata async");
async = NULL;
fwprintf(stderr, L"\nWriter Status after PreRestore\n");
checker(components->GatherWriterStatus(&async), L"GatherWriterStatus");
checker(cancel[GatherWriterStatus] ? cancelTest(async, cancelDelay) : waitTest(async),
L"GatherWriterStatus async");
async = NULL;
checkStatus(components);
checker(components->PostRestore(&async), L"GatherWriterMetadata");
checker(cancel[PostRestore] ? cancelTest(async, cancelDelay) : waitTest(async),
L"GatherWriterMetadata async");
async = NULL;
fwprintf(stderr, L"\nWriter Status after PostRestore\n");
checker(components->GatherWriterStatus(&async), L"GatherWriterStatus");
checker(cancel[GatherWriterStatus] ? cancelTest(async, cancelDelay) : waitTest(async),
L"GatherWriterStatus async");
checkStatus(components);
}
// check a return code and throw upon failure
inline void checker(HRESULT error, wchar_t* string)
{
if (FAILED(error)) {
CBsString error;
error.Format(L"%s failed with error 0x%08lx", string, error);
throw error;
}
}
// wait on an async object
inline HRESULT waitTest(IVssAsync* async)
{
checker(async->Wait(), L"IVssAsync::Wait");
HRESULT hr;
async->QueryStatus(&hr, NULL);
// convert non-failure state codes to S_OK
return FAILED(hr) ? hr : S_OK;
}
// cancel an async object
inline HRESULT cancelTest(IVssAsync* async, long cancelDelay)
{
// put an upper limit on random delays
const int MaxRandDelay = 1000;
// wait for the requisite amount of time
if (cancelDelay != 0)
::Sleep((cancelDelay > 0) ? cancelDelay : rand() % MaxRandDelay);
async->Cancel();
HRESULT hr;
async->QueryStatus(&hr, NULL);
// convert non-failure state codes to S_OK
return FAILED(hr) ? hr : S_OK;
}
void checkMetadata(IVssBackupComponents* components)
{
UINT numWriters = 0;
checker(components->GetWriterMetadataCount(&numWriters),
L"GetWriterMetadataCount");
for (UINT x = 0; x < numWriters; x++) {
VSS_ID instance = GUID_NULL;
CComPtr<IVssExamineWriterMetadata> examineData;
checker(components->GetWriterMetadata(x, &instance, &examineData),
L"GetWriterMetadata");
VSS_ID outInstance = GUID_NULL, outClass = GUID_NULL;
BSTR outName;
VSS_USAGE_TYPE outUsage;
VSS_SOURCE_TYPE outSource;
checker(examineData->GetIdentity(&outInstance, &outClass, &outName, &outUsage, &outSource),
L"GetIdentity");
BS_ASSERT(outInstance == instance);
fwprintf (stderr, L"\nWriter name %s\n", outName);
fwprintf (stderr, L"usage type %s\n", WszFromUsageType(outUsage));
VSS_RESTOREMETHOD_ENUM restoreMethod;
BSTR service, userProc;
VSS_WRITERRESTORE_ENUM writerRestore;
bool reboot;
UINT mappings;
checker(examineData->GetRestoreMethod(&restoreMethod, &service, &userProc, &writerRestore, &reboot, &mappings),
L"GetIdentity");
fwprintf(stderr, L"restore method %s\n", WszFromRestoreMethod(restoreMethod));
fwprintf(stderr, L"reboot required %s\n", reboot ? L"true" : L"false");
UINT includes = 0, excludes = 0, components = 0;
checker(examineData->GetFileCounts(&includes, &excludes, &components),
L"GetFileCounts");
fwprintf(stderr, L"%d include files\n%d exclude files \n%d components\n", includes, excludes, components);
}
}
void checkStatus(IVssBackupComponents* components)
{
UINT numWriters = 0;
checker(components->GetWriterMetadataCount(&numWriters),
L"GetWriterMetadataCount");
UINT numStatus = 0;
checker(components->GetWriterStatusCount(&numStatus),
L"GetWriterMetadataCount");
BS_ASSERT(numStatus == numWriters);
for (UINT x = 0; x < numStatus; x++) {
VSS_ID instance, classWriter;
BSTR writerName;
VSS_WRITER_STATE state;
HRESULT failure = S_OK;
checker(components->GetWriterStatus(x, &instance, &classWriter, &writerName, &state, &failure),
L"GetWriterStatus");
fwprintf(stderr, L"\n writer name %s\n", writerName);
fwprintf(stderr, L"writer status %s\n", GetStringFromWriterStatus(state));
fwprintf(stderr, L"writer failure 0x%08lx\n", failure);
}
}
const wchar_t* WszFromUsageType(VSS_USAGE_TYPE usage)
{
switch(usage) {
default:
throw L"UNKOWN";
case VSS_UT_OTHER:
return L"OTHER";
case VSS_UT_BOOTABLESYSTEMSTATE:
return L"BOOTABLE_SYSTEM_STATE";
case VSS_UT_SYSTEMSERVICE:
return L"SYSTEM_SERVICE";
case VSS_UT_USERDATA:
return L"USER_DATA";
}
}
// convert from restore method to string
const wchar_t* WszFromRestoreMethod(VSS_RESTOREMETHOD_ENUM method)
{
switch(method) {
default:
return L"UNKNOWN";
case VSS_RME_RESTORE_IF_NOT_THERE:
return L"RESTORE_IF_NONE_THERE";
case VSS_RME_RESTORE_IF_CAN_REPLACE:
return L"RESTORE_IF_CAN_BE_REPLACED";
case VSS_RME_STOP_RESTORE_START:
return L"STOP_RESTART_SERVICE";
case VSS_RME_RESTORE_TO_ALTERNATE_LOCATION:
return L"RESTORE_TO_ALTERNATE_LOCATION";
case VSS_RME_RESTORE_AT_REBOOT:
return L"REPLACE_AT_REBOOT";
case VSS_RME_CUSTOM:
return L"CUSTOM";
}
}
const wchar_t* GetStringFromWriterStatus(VSS_WRITER_STATE eWriterStatus)
{
const wchar_t* pwszRetString = L"UNDEFINED";
switch (eWriterStatus)
{
case VSS_WS_STABLE: pwszRetString = L"STABLE"; break;
case VSS_WS_WAITING_FOR_FREEZE: pwszRetString = L"WAITING_FOR_FREEZE"; break;
case VSS_WS_WAITING_FOR_THAW: pwszRetString = L"WAITING_FOR_THAW"; break;
case VSS_WS_WAITING_FOR_POST_SNAPSHOT: pwszRetString = L"WAITING_FOR_POST_SNAPSHOT"; break;
case VSS_WS_WAITING_FOR_BACKUP_COMPLETE: pwszRetString = L"WAITING_FOR_BACKUP_COMPLETION"; break;
case VSS_WS_FAILED_AT_IDENTIFY: pwszRetString = L"FAILED_AT_IDENTIFY"; break;
case VSS_WS_FAILED_AT_PREPARE_BACKUP: pwszRetString = L"FAILED_AT_PREPARE_BACKUP";break;
case VSS_WS_FAILED_AT_PREPARE_SNAPSHOT: pwszRetString = L"FAILED_AT_PREPARE_SNAPSHOT"; break;
case VSS_WS_FAILED_AT_FREEZE: pwszRetString = L"FAILED_AT_FREEZE"; break;
case VSS_WS_FAILED_AT_THAW: pwszRetString = L"FAILED_AT_THAW"; break;
case VSS_WS_FAILED_AT_POST_SNAPSHOT: pwszRetString = L"FAILED_AT_POST_SNAPSHOT"; break;
case VSS_WS_FAILED_AT_BACKUP_COMPLETE: pwszRetString = L"FAILED_AT_BACKUP_COMPLETE"; break;
case VSS_WS_FAILED_AT_PRE_RESTORE: pwszRetString = L"FAILED_AT_PRE_RESTORE"; break;
case VSS_WS_FAILED_AT_POST_RESTORE: pwszRetString = L"FAILED_AT_POST_RESTORE"; break;
default:
break;
}
return (pwszRetString);
}