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.
 
 
 
 
 
 

670 lines
17 KiB

/*
**++
**
** Copyright (c) 2000-2001 Microsoft Corporation
**
**
** Module Name:
**
** simsnap.cpp
**
**
** Abstract:
**
** Test program to drive the VSS Writer Shim contained in VssAPI.DLL
**
**
** Author:
**
** Michael C. Johnson [mikejohn] 24-May-2000
**
**
** Revision History:
**
** X-5 MCJ Michael C. Johnson 18-Sep-2000
** 176860: Add the missing calling convention specifiers
**
** X-4 MCJ Michael C. Johnson 23-Jun-2000
** Set the writer failure status.
**
** X-3 MCJ Michael C. Johnson 15-Jun-2000
** Add some additional event routines and the ability to act
** as various types of writer.
**
** X-2 MCJ Michael C. Johnson 26-May-2000
** Add some extra tests to validate shim is properly sensitive
** to volume name array contents.
**--
*/
/*
** Defines
**
**
** C4290: C++ Exception Specification ignored
** warning C4511: 'CVssCOMApplication' : copy constructor could not be generated
** warning C4127: conditional expression is constant
*/
#pragma warning(disable:4290)
#pragma warning(disable:4511)
#pragma warning(disable:4127)
/*
** Includes
*/
#include <windows.h>
#include <wtypes.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <vss.h>
#include <vswriter.h>
#define GET_STATUS_FROM_BOOL(_bSucceeded) ((_bSucceeded) ? NOERROR : HRESULT_FROM_WIN32 (GetLastError()))
#define GET_STATUS_FROM_HANDLE(_handle) ((NULL != (_handle)) ? NOERROR : HRESULT_FROM_WIN32 (GetLastError()))
#define GET_STATUS_FROM_POINTER(_ptr) ((NULL != (_ptr)) ? NOERROR : E_OUTOFMEMORY)
#define SIZEOF_ARRAY(_aBase) (sizeof (_aBase) / sizeof ((_aBase)[0]))
typedef enum FAIL_PHASE
{
PHASE_UNDEFINED = 0,
PHASE_IDENTIFY,
PHASE_PREPARE_FOR_BACKUP,
PHASE_PREPARE_FOR_SNAPSHOT,
PHASE_FREEZE,
PHASE_THAW,
PHASE_ABORT,
PHASE_BACKUP_COMPLETE,
PHASE_RESTORE
} FAIL_PHASE;
HRESULT SelectFailureStatus (VOID)
{
HRESULT hrStatus;
switch (rand () / (RAND_MAX / 5))
{
case 0: hrStatus = VSS_E_WRITERERROR_INCONSISTENTSNAPSHOT; break;
case 1: hrStatus = VSS_E_WRITERERROR_OUTOFRESOURCES; break;
case 2: hrStatus = VSS_E_WRITERERROR_TIMEOUT; break;
case 3: hrStatus = VSS_E_WRITERERROR_NONRETRYABLE; break;
case 4: hrStatus = VSS_E_WRITERERROR_RETRYABLE; break;
default:
assert (FALSE);
break;
}
return (hrStatus);
}
LPCWSTR GetStringFromFailureType (HRESULT hrStatus)
{
LPCWSTR pwszFailureType;
switch (hrStatus)
{
case NOERROR: pwszFailureType = L""; break;
case VSS_E_WRITERERROR_INCONSISTENTSNAPSHOT: pwszFailureType = L"InconsistentSnapshot"; break;
case VSS_E_WRITERERROR_OUTOFRESOURCES: pwszFailureType = L"OutOfResources"; break;
case VSS_E_WRITERERROR_TIMEOUT: pwszFailureType = L"Timeout"; break;
case VSS_E_WRITERERROR_NONRETRYABLE: pwszFailureType = L"Non-Retryable"; break;
case VSS_E_WRITERERROR_RETRYABLE: pwszFailureType = L"Retryable"; break;
default: pwszFailureType = L"UNDEFINED"; break;
}
return (pwszFailureType);
}
LPCWSTR GetStringFromWriterType (VSS_USAGE_TYPE wtWriterType)
{
LPCWSTR pwszWriterType;
switch (wtWriterType)
{
case VSS_UT_BOOTABLESYSTEMSTATE: pwszWriterType = L"BootableSystemState"; break;
case VSS_UT_SYSTEMSERVICE: pwszWriterType = L"SystemServiceState"; break;
case VSS_UT_USERDATA: pwszWriterType = L"UserData"; break;
case VSS_UT_OTHER: pwszWriterType = L"Other"; break;
default: pwszWriterType = L"UNDEFINED"; break;
}
return (pwszWriterType);
}
LPCWSTR GetStringFromFailPhase (FAIL_PHASE fpFailPhase)
{
LPCWSTR pwszFailPhase;
switch (fpFailPhase)
{
case PHASE_IDENTIFY: pwszFailPhase = L"Identify"; break;
case PHASE_PREPARE_FOR_BACKUP: pwszFailPhase = L"PrepareForBackup"; break;
case PHASE_PREPARE_FOR_SNAPSHOT: pwszFailPhase = L"PrepareForSnapshot"; break;
case PHASE_FREEZE: pwszFailPhase = L"Freeze"; break;
case PHASE_THAW: pwszFailPhase = L"Thaw"; break;
case PHASE_ABORT: pwszFailPhase = L"Abort"; break;
case PHASE_BACKUP_COMPLETE: pwszFailPhase = L"BackupComplete"; break;
case PHASE_RESTORE: pwszFailPhase = L"Restore"; break;
default: pwszFailPhase = L"UNDEFINED"; break;
}
return (pwszFailPhase);
}
static volatile BOOL bContinue = TRUE;
static volatile FAIL_PHASE fpFailPhase = PHASE_FREEZE;
class CVssWriterFailSnap : public CVssWriter
{
public:
bool STDMETHODCALLTYPE OnIdentify (IVssCreateWriterMetadata *pIVssCreateWriterMetadata);
bool STDMETHODCALLTYPE OnPrepareBackup (IVssWriterComponents *pIVssWriterComponents);
bool STDMETHODCALLTYPE OnPrepareSnapshot ();
bool STDMETHODCALLTYPE OnFreeze ();
bool STDMETHODCALLTYPE OnThaw ();
bool STDMETHODCALLTYPE OnAbort ();
bool STDMETHODCALLTYPE OnBackupComplete (IVssWriterComponents *pIVssWriterComponents);
bool STDMETHODCALLTYPE OnPostRestore (IVssWriterComponents *pIVssWriterComponents);
};
bool STDMETHODCALLTYPE CVssWriterFailSnap::OnIdentify (IVssCreateWriterMetadata *pIVssCreateWriterMetadata)
{
bool bPhaseSucceeded = (PHASE_IDENTIFY != fpFailPhase);
HRESULT hrStatus = SelectFailureStatus ();
if (bPhaseSucceeded)
{
hrStatus = pIVssCreateWriterMetadata->AddComponent (VSS_CT_FILEGROUP,
NULL,
L"Failsnap Writer Component",
L"Failsnap Writer Caption",
NULL, // icon
0,
true,
false,
false);
bPhaseSucceeded = SUCCEEDED (hrStatus);
}
wprintf (L"\nThreadId 0x%04x - Received event - OnIdentify ()%s%s",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
SetWriterFailure (hrStatus);
}
return (bPhaseSucceeded);
}
bool STDMETHODCALLTYPE CVssWriterFailSnap::OnPrepareBackup (IVssWriterComponents *pIVssWriterComponents)
{
bool bPhaseSucceeded = (PHASE_PREPARE_FOR_BACKUP != fpFailPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnPrepareBackup ()%s%s",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
SetWriterFailure (hrStatus);
}
return (bPhaseSucceeded);
}
bool STDMETHODCALLTYPE CVssWriterFailSnap::OnPrepareSnapshot ()
{
bool bPhaseSucceeded = (PHASE_PREPARE_FOR_SNAPSHOT != fpFailPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnPrepareSnapshot ()%s%s",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
SetWriterFailure (hrStatus);
}
return (bPhaseSucceeded);
}
bool STDMETHODCALLTYPE CVssWriterFailSnap::OnFreeze ()
{
bool bPhaseSucceeded = (PHASE_FREEZE != fpFailPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnFreeze ()%s%s",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
SetWriterFailure (hrStatus);
}
return (bPhaseSucceeded);
}
bool STDMETHODCALLTYPE CVssWriterFailSnap::OnThaw ()
{
bool bPhaseSucceeded = (PHASE_THAW != fpFailPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnThaw ()%s%s",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
SetWriterFailure (hrStatus);
}
return (bPhaseSucceeded);
}
bool STDMETHODCALLTYPE CVssWriterFailSnap::OnAbort ()
{
bool bPhaseSucceeded = (PHASE_ABORT != fpFailPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnAbort ()%s%s",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
SetWriterFailure (hrStatus);
}
return (bPhaseSucceeded);
}
bool STDMETHODCALLTYPE CVssWriterFailSnap::OnBackupComplete (IVssWriterComponents *pIVssWriterComponents)
{
bool bPhaseSucceeded = (PHASE_BACKUP_COMPLETE != fpFailPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnBackupComplete ()%s%s",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
SetWriterFailure (hrStatus);
}
return (bPhaseSucceeded);
}
bool STDMETHODCALLTYPE CVssWriterFailSnap::OnPostRestore (IVssWriterComponents *pIVssWriterComponents)
{
bool bPhaseSucceeded = (PHASE_RESTORE != fpFailPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnPostRestore ()%s%s",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
SetWriterFailure (hrStatus);
}
return (bPhaseSucceeded);
}
static BOOL AssertPrivilege (LPCWSTR privName)
{
HANDLE tokenHandle;
BOOL stat = FALSE;
if (OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, &tokenHandle))
{
LUID value;
if (LookupPrivilegeValue (NULL, privName, &value))
{
TOKEN_PRIVILEGES newState;
DWORD error;
newState.PrivilegeCount = 1;
newState.Privileges[0].Luid = value;
newState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
/*
** We will always call GetLastError below, so clear
** any prior error values on this thread.
*/
SetLastError (ERROR_SUCCESS);
stat = AdjustTokenPrivileges (tokenHandle,
FALSE,
&newState,
(DWORD)0,
NULL,
NULL);
/*
** Supposedly, AdjustTokenPriveleges always returns TRUE
** (even when it fails). So, call GetLastError to be
** extra sure everything's cool.
*/
if ((error = GetLastError()) != ERROR_SUCCESS)
{
stat = FALSE;
}
if (!stat)
{
wprintf (L"AdjustTokenPrivileges for %s failed with 0x%08X",
privName,
error);
}
}
CloseHandle (tokenHandle);
}
return stat;
}
BOOL WINAPI CtrlC_HandlerRoutine (IN DWORD /* dwType */)
{
bContinue = FALSE;
// Mark that the break was handled.
return TRUE;
}
extern "C" int __cdecl wmain (int argc, WCHAR *argv[])
{
HRESULT hrStatus = NOERROR;
CVssWriterFailSnap *pCVssWriterFailSnap = NULL;
BOOL bSucceeded = FALSE;
BOOL bComInitialized = FALSE;
BOOL bSubscribed = FALSE;
VSS_USAGE_TYPE wtWriterType = VSS_UT_USERDATA;
const GUID guidIdWriter = {0xd335a99e,
0x57fb,
0x4b80,
{0x85, 0xb1, 0x15, 0xda, 0xa7, 0xc7, 0x4e, 0x14}};
srand ((unsigned)time (NULL));
SetConsoleCtrlHandler(CtrlC_HandlerRoutine, TRUE);
if ((argc >= 2) && (wcslen (argv[1]) > 0))
{
switch (*argv[1])
{
case L'I': case L'i': fpFailPhase = PHASE_IDENTIFY; break;
case L'B': case L'b': fpFailPhase = PHASE_PREPARE_FOR_BACKUP; break;
case L'S': case L's': fpFailPhase = PHASE_PREPARE_FOR_SNAPSHOT; break;
case L'F': case L'f': fpFailPhase = PHASE_FREEZE; break;
case L'T': case L't': fpFailPhase = PHASE_THAW; break;
case L'A': case L'a': fpFailPhase = PHASE_ABORT; break;
case L'C': case L'c': fpFailPhase = PHASE_BACKUP_COMPLETE; break;
case L'R': case L'r': fpFailPhase = PHASE_RESTORE; break;
default:
wprintf (L"\nFAILSNAP [phase] [writer type]"
L"\n\n\tFailPhases"
L"\n\t\ti - Identify"
L"\n\t\tb - PrepareForBackup"
L"\n\t\ts - PrepareForSnapshot"
L"\n\t\tf - Freeze (default)"
L"\n\t\tt - Thaw"
L"\n\t\ta - Abort"
L"\n\t\tc - BackupComplete"
L"\n\t\tr - PostRestore"
L"\n\n\tWriterTypes"
L"\n\t\tb - BootableState writer"
L"\n\t\ts - ServiceState writer"
L"\n\t\tu - UserData writer (default)"
L"\n\t\to - Other writer"
L"\n");
bContinue = FALSE;
break;
}
}
if ((argc >= 3) && (wcslen (argv[2]) > 0))
{
switch (*argv[2])
{
case L'B': case L'b': wtWriterType = VSS_UT_BOOTABLESYSTEMSTATE; break;
case L'S': case L's': wtWriterType = VSS_UT_SYSTEMSERVICE; break;
case L'U': case L'u': wtWriterType = VSS_UT_USERDATA; break;
case L'O': case L'o': wtWriterType = VSS_UT_OTHER; break;
default:
bContinue = FALSE;
break;
}
}
if (bContinue)
{
wprintf (L"\nSetting up %s writer to fail %s requests (ProcessId 0x%04x)",
GetStringFromWriterType (wtWriterType),
GetStringFromFailPhase (fpFailPhase),
GetCurrentProcessId ());
wprintf (L"\nChecking privileges");
bSubscribed = AssertPrivilege (SE_BACKUP_NAME);
hrStatus = GET_STATUS_FROM_BOOL (bSucceeded);
if (FAILED (hrStatus))
{
wprintf (L"\nAssertPrivilege returned error 0x%08X", hrStatus);
}
}
if (bContinue && SUCCEEDED (hrStatus))
{
wprintf (L"\nInitializing COM");
hrStatus = CoInitializeEx (NULL, COINIT_MULTITHREADED);
if (FAILED (hrStatus))
{
wprintf (L"\nCoInitialize() returned error 0x%08X", hrStatus);
}
else
{
bComInitialized = TRUE;
}
}
if (bContinue && SUCCEEDED (hrStatus))
{
wprintf (L"\nConstructing Writer");
pCVssWriterFailSnap = new CVssWriterFailSnap;
if (NULL == pCVssWriterFailSnap)
{
hrStatus = HRESULT_FROM_WIN32 (ERROR_NOT_ENOUGH_MEMORY);
wprintf (L"\nFailed to allocate CVssWriterFailSnap : 0x%08X", hrStatus);
}
}
if (bContinue && SUCCEEDED (hrStatus))
{
WCHAR awchWriterName [256];
wprintf (L"\nInitialising the writer");
_snwprintf (awchWriterName,
SIZEOF_ARRAY (awchWriterName),
L"Microsoft Test Writer - FailSnap (%s/%s/0x%04x)",
GetStringFromWriterType (wtWriterType),
GetStringFromFailPhase (fpFailPhase),
GetCurrentProcessId ());
hrStatus = pCVssWriterFailSnap->Initialize (guidIdWriter,
awchWriterName,
wtWriterType,
VSS_ST_OTHER);
if (FAILED (hrStatus))
{
wprintf (L"\nFailed to initialize the writer : 0x%08X", hrStatus);
}
}
if (bContinue && SUCCEEDED (hrStatus))
{
wprintf (L"\nSubscribing to snapshot events");
hrStatus = pCVssWriterFailSnap->Subscribe ();
if (FAILED (hrStatus))
{
wprintf (L"\nFailed to subscribe to snapshot events : 0x%08X", hrStatus);
}
else
{
bSubscribed = TRUE;
}
}
if (bContinue && SUCCEEDED (hrStatus))
{
wprintf (L"\nWaiting for snapshot events (or Ctrl-C)");
while (bContinue)
{
Sleep (100);
}
}
if (bSubscribed)
{
wprintf (L"\nUn-Subscribing from snapshot events");
pCVssWriterFailSnap->Unsubscribe ();
}
if (NULL != pCVssWriterFailSnap)
{
wprintf (L"\nDeconstructing Writer");
delete pCVssWriterFailSnap;
}
if (bComInitialized)
{
wprintf (L"\nUnInitialising COM");
CoUninitialize();
}
return (hrStatus);
}