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.
 
 
 
 
 
 

685 lines
17 KiB

/*
**++
**
** Copyright (c) 2000-2001 Microsoft Corporation
**
**
** Module Name:
**
** waitsnap.cpp
**
**
** Abstract:
**
** Test program that starts a VSS writer and waits upon receiving a specific event
**
** Author:
**
** Charles Chung [cchung] 04-Dec-2001
**
**
** Revision History:
** 1.0 Altered from Failsnap.cpp
**
**--
*/
/*
** 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);
}
void ForceSleep(INT sec)
{
wprintf(L"\tGoing to sleep for %d seconds...\n", sec) ;
while(sec>0) {
Sleep(1000) ;
sec-- ;
if(sec%10==0) {
wprintf(L"\tSeconds left=%d\n", sec) ;
}
}
wprintf(L"\tAwaken!\n") ;
}
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 GetStringFromWaitPhase (FAIL_PHASE fpWaitPhase)
{
LPCWSTR pwszWaitPhase;
switch (fpWaitPhase)
{
case PHASE_IDENTIFY: pwszWaitPhase = L"Identify"; break;
case PHASE_PREPARE_FOR_BACKUP: pwszWaitPhase = L"PrepareForBackup"; break;
case PHASE_PREPARE_FOR_SNAPSHOT: pwszWaitPhase = L"PrepareForSnapshot"; break;
case PHASE_FREEZE: pwszWaitPhase = L"Freeze"; break;
case PHASE_THAW: pwszWaitPhase = L"Thaw"; break;
case PHASE_ABORT: pwszWaitPhase = L"Abort"; break;
case PHASE_BACKUP_COMPLETE: pwszWaitPhase = L"BackupComplete"; break;
case PHASE_RESTORE: pwszWaitPhase = L"Restore"; break;
default: pwszWaitPhase = L"UNDEFINED"; break;
}
return (pwszWaitPhase);
}
static volatile BOOL bContinue = TRUE;
static volatile FAIL_PHASE fpWaitPhase = PHASE_FREEZE;
static volatile INT nWaitTime = 10 ;
class CVssWriterWaitsnap : 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 CVssWriterWaitsnap::OnIdentify (IVssCreateWriterMetadata *pIVssCreateWriterMetadata)
{
bool bPhaseSucceeded = (PHASE_IDENTIFY != fpWaitPhase);
HRESULT hrStatus = SelectFailureStatus ();
if (bPhaseSucceeded)
{
hrStatus = pIVssCreateWriterMetadata->AddComponent (VSS_CT_FILEGROUP,
NULL,
L"Waitsnap Writer Component",
L"Waitsnap Writer Caption",
NULL, // icon
0,
true,
false,
false);
bPhaseSucceeded = SUCCEEDED (hrStatus);
}
wprintf (L"\nThreadId 0x%04x - Received event - OnIdentify ()%s%s\n",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
ForceSleep(nWaitTime) ;
}
return (TRUE);
}
bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnPrepareBackup (IVssWriterComponents *pIVssWriterComponents)
{
bool bPhaseSucceeded = (PHASE_PREPARE_FOR_BACKUP != fpWaitPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnPrepareBackup ()%s%s\n",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
ForceSleep(nWaitTime) ;
}
return (TRUE);
}
bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnPrepareSnapshot ()
{
bool bPhaseSucceeded = (PHASE_PREPARE_FOR_SNAPSHOT != fpWaitPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnPrepareSnapshot ()%s%s\n",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
ForceSleep(nWaitTime) ;
}
return (TRUE);
}
bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnFreeze ()
{
bool bPhaseSucceeded = (PHASE_FREEZE != fpWaitPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnFreeze ()%s%s\n",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
ForceSleep(nWaitTime) ;
}
return (TRUE);
}
bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnThaw ()
{
bool bPhaseSucceeded = (PHASE_THAW != fpWaitPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnThaw ()%s%s\n",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
ForceSleep(nWaitTime) ;
}
return (TRUE);
}
bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnAbort ()
{
bool bPhaseSucceeded = (PHASE_ABORT != fpWaitPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnAbort ()%s%s\n",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
ForceSleep(nWaitTime) ;
}
return (TRUE);
}
bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnBackupComplete (IVssWriterComponents *pIVssWriterComponents)
{
bool bPhaseSucceeded = (PHASE_BACKUP_COMPLETE != fpWaitPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnBackupComplete ()%s%s\n",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
ForceSleep(nWaitTime) ;
}
return (TRUE);
}
bool STDMETHODCALLTYPE CVssWriterWaitsnap::OnPostRestore (IVssWriterComponents *pIVssWriterComponents)
{
bool bPhaseSucceeded = (PHASE_RESTORE != fpWaitPhase);
HRESULT hrStatus = bPhaseSucceeded ? NOERROR : SelectFailureStatus ();
wprintf (L"\nThreadId 0x%04x - Received event - OnPostRestore ()%s%s\n",
GetCurrentThreadId (),
bPhaseSucceeded ? L"" : L" - FAILED ",
GetStringFromFailureType (hrStatus));
if (!bPhaseSucceeded)
{
ForceSleep(nWaitTime) ;
}
return (TRUE);
}
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;
CVssWriterWaitsnap *pCVssWriterWaitsnap = 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))
{
//get the stage which the writer is to fail
switch (*argv[1])
{
case L'I': case L'i': fpWaitPhase = PHASE_IDENTIFY; break;
case L'B': case L'b': fpWaitPhase = PHASE_PREPARE_FOR_BACKUP; break;
case L'S': case L's': fpWaitPhase = PHASE_PREPARE_FOR_SNAPSHOT; break;
case L'F': case L'f': fpWaitPhase = PHASE_FREEZE; break;
case L'T': case L't': fpWaitPhase = PHASE_THAW; break;
case L'A': case L'a': fpWaitPhase = PHASE_ABORT; break;
case L'C': case L'c': fpWaitPhase = PHASE_BACKUP_COMPLETE; break;
case L'R': case L'r': fpWaitPhase = PHASE_RESTORE; break;
default:
wprintf (L"\nWAITSNAP [phase] [writer type] [sec to wait]"
L"\n\n\tWaitPhases"
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;
}
//get the amount of time the stage is to wait
}
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;
}
}
//get the amount of seconds to wait
if ((argc >= 4) && (wcslen (argv[3]) > 0))
{
nWaitTime=_wtoi(argv[3]) ;
}
if (bContinue)
{
wprintf (L"\nSetting up %s writer to wait %s requests (ProcessId 0x%04x) for %d seconds",
GetStringFromWriterType (wtWriterType),
GetStringFromWaitPhase (fpWaitPhase),
GetCurrentProcessId (),
nWaitTime);
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");
pCVssWriterWaitsnap = new CVssWriterWaitsnap;
if (NULL == pCVssWriterWaitsnap)
{
hrStatus = HRESULT_FROM_WIN32 (ERROR_NOT_ENOUGH_MEMORY);
wprintf (L"\nFailed to allocate CVssWriterWaitsnap : 0x%08X", hrStatus);
}
}
if (bContinue && SUCCEEDED (hrStatus))
{
WCHAR awchWriterName [256];
wprintf (L"\nInitialising the writer");
_snwprintf (awchWriterName,
SIZEOF_ARRAY (awchWriterName),
L"Microsoft Test Writer - Waitsnap (%s/%s/0x%04x)",
GetStringFromWriterType (wtWriterType),
GetStringFromWaitPhase (fpWaitPhase),
GetCurrentProcessId ());
hrStatus = pCVssWriterWaitsnap->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 = pCVssWriterWaitsnap->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");
pCVssWriterWaitsnap->Unsubscribe ();
}
if (NULL != pCVssWriterWaitsnap)
{
wprintf (L"\nDeconstructing Writer");
delete pCVssWriterWaitsnap;
}
if (bComInitialized)
{
wprintf (L"\nUnInitialising COM");
CoUninitialize();
}
return (hrStatus);
}