// Check the status for all selected writers bool VSSClientGeneric::CheckWriterStatus() { /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vss/base/ivssbackupcomponents_startsnapshotset.asp */ IVssBackupComponents* pVssObj = (IVssBackupComponents*)m_pVssObject; if (!pVssObj) { Jmsg(m_jcr, M_FATAL, 0, "Cannot get IVssBackupComponents pointer.\n"); errno = ENOSYS; return false; } DestroyWriterInfo(); if (m_bWriterStatusCurrent) { m_bWriterStatusCurrent = false; pVssObj->FreeWriterStatus(); } // Gather writer status to detect potential errors CComPtr<IVssAsync> pAsync; HRESULT hr = pVssObj->GatherWriterStatus(&pAsync.p); if (FAILED(hr)) { JmsgVssApiStatus(m_jcr, M_FATAL, hr, "GatherWriterStatus"); errno = b_errno_win32; return false; } // Waits for the async operation to finish and checks the result if (!WaitAndCheckForAsyncOperation(pAsync.p)) { errno = b_errno_win32; return false; } m_bWriterStatusCurrent = true; unsigned cWriters = 0; hr = pVssObj->GetWriterStatusCount(&cWriters); if (FAILED(hr)) { JmsgVssApiStatus(m_jcr, M_FATAL, hr, "GatherWriterStatusCount"); errno = b_errno_win32; return false; } int nState; POOLMEM *szBuf = get_pool_memory(PM_FNAME); // Enumerate each writer for (unsigned iWriter = 0; iWriter < cWriters; iWriter++) { VSS_ID idInstance = GUID_NULL; VSS_ID idWriter= GUID_NULL; VSS_WRITER_STATE eWriterStatus = VSS_WS_UNKNOWN; CComBSTR bstrWriterName; HRESULT hrWriterFailure = S_OK; // Get writer status hr = pVssObj->GetWriterStatus(iWriter, &idInstance, &idWriter, &bstrWriterName, &eWriterStatus, &hrWriterFailure); if (FAILED(hr)) { /* Api failed */ JmsgVssApiStatus(m_jcr, M_WARNING, hr, "GetWriterStatus"); nState = 0; /* Unknown writer state -- API failed */ } else { switch(eWriterStatus) { case VSS_WS_FAILED_AT_IDENTIFY: case VSS_WS_FAILED_AT_PREPARE_BACKUP: case VSS_WS_FAILED_AT_PREPARE_SNAPSHOT: case VSS_WS_FAILED_AT_FREEZE: case VSS_WS_FAILED_AT_THAW: case VSS_WS_FAILED_AT_POST_SNAPSHOT: case VSS_WS_FAILED_AT_BACKUP_COMPLETE: case VSS_WS_FAILED_AT_PRE_RESTORE: case VSS_WS_FAILED_AT_POST_RESTORE: #if defined(B_VSS_W2K3) || defined(B_VSS_VISTA) case VSS_WS_FAILED_AT_BACKUPSHUTDOWN: #endif /* Writer status problem */ wchar_2_UTF8(&szBuf, bstrWriterName.p); JmsgVssWriterStatus(m_jcr, M_WARNING, eWriterStatus, szBuf); nState = -1; /* bad writer state */ break; default: /* ok */ nState = 1; /* Writer state OK */ } } /* store text info */ char str[1000]; bstrncpy(str, "\"", sizeof(str)); wchar_2_UTF8(&szBuf, bstrWriterName.p); bstrncat(str, szBuf, sizeof(str)); bstrncat(str, "\", State: 0x", sizeof(str)); itoa(eWriterStatus, szBuf, sizeof_pool_memory(szBuf)); bstrncat(str, szBuf, sizeof(str)); bstrncat(str, " (", sizeof(str)); wchar_2_UTF8(&szBuf, GetStringFromWriterStatus(eWriterStatus)); bstrncat(str, szBuf, sizeof(str)); bstrncat(str, ")", sizeof(str)); AppendWriterInfo(nState, (const char *)str); } free_pool_memory(szBuf); errno = 0; return true; }
// Check the status for all selected writers BOOL VSSClientGeneric::CheckWriterStatus() { /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vss/base/ivssbackupcomponents_startsnapshotset.asp */ IVssBackupComponents* pVss = (IVssBackupComponents*) m_pVssObject; DestroyWriterInfo(); // Gather writer status to detect potential errors CComPtr<IVssAsync> pAsync; HRESULT hr = pVss->GatherWriterStatus(&pAsync.p); if (FAILED(hr)) { errno = b_errno_win32; return FALSE; } // Waits for the async operation to finish and checks the result WaitAndCheckForAsyncOperation(pAsync.p); unsigned cWriters = 0; hr = pVss->GetWriterStatusCount(&cWriters); if (FAILED(hr)) { errno = b_errno_win32; return FALSE; } int nState; // Enumerate each writer for (unsigned iWriter = 0; iWriter < cWriters; iWriter++) { VSS_ID idInstance = GUID_NULL; VSS_ID idWriter= GUID_NULL; VSS_WRITER_STATE eWriterStatus = VSS_WS_UNKNOWN; CComBSTR bstrWriterName; HRESULT hrWriterFailure = S_OK; // Get writer status hr = pVss->GetWriterStatus(iWriter, &idInstance, &idWriter, &bstrWriterName, &eWriterStatus, &hrWriterFailure); if (FAILED(hr)) { /* unknown */ nState = 0; } else { switch(eWriterStatus) { case VSS_WS_FAILED_AT_IDENTIFY: case VSS_WS_FAILED_AT_PREPARE_BACKUP: case VSS_WS_FAILED_AT_PREPARE_SNAPSHOT: case VSS_WS_FAILED_AT_FREEZE: case VSS_WS_FAILED_AT_THAW: case VSS_WS_FAILED_AT_POST_SNAPSHOT: case VSS_WS_FAILED_AT_BACKUP_COMPLETE: case VSS_WS_FAILED_AT_PRE_RESTORE: case VSS_WS_FAILED_AT_POST_RESTORE: #if defined(B_VSS_W2K3) || defined(B_VSS_VISTA) case VSS_WS_FAILED_AT_BACKUPSHUTDOWN: #endif /* failed */ nState = -1; break; default: /* ok */ nState = 1; } } /* store text info */ char str[1000]; char szBuf1[200]; char szBuf2[200]; char szBuf3[200]; wchar_2_UTF8(szBuf1, bstrWriterName.p, sizeof(szBuf1)); itoa(eWriterStatus, szBuf2, sizeof(szBuf2)); wchar_2_UTF8(szBuf3, GetStringFromWriterStatus(eWriterStatus), sizeof(szBuf3)); snprintf(str, sizeof(str), "\"%s\", State: 0x%s (%s)", szBuf1, szBuf2, szBuf3); AppendWriterInfo(nState, (const char *)str); } hr = pVss->FreeWriterStatus(); if (FAILED(hr)) { errno = b_errno_win32; return FALSE; } errno = 0; return TRUE; }
bool VSSClientGeneric::CloseBackup() { bool bRet = false; HRESULT hr; BSTR xml; IVssBackupComponents* pVssObj = (IVssBackupComponents*)m_pVssObject; if (!m_pVssObject) { Jmsg(m_jcr, M_FATAL, 0, "VssOject is NULL.\n"); errno = ENOSYS; return bRet; } CComPtr<IVssAsync> pAsync; SetVSSPathConvert(NULL, NULL); m_bBackupIsInitialized = false; hr = pVssObj->BackupComplete(&pAsync.p); if (SUCCEEDED(hr)) { // Waits for the async operation to finish and checks the result WaitAndCheckForAsyncOperation(pAsync.p); bRet = true; } else { JmsgVssApiStatus(m_jcr, M_ERROR, hr, "BackupComplete"); errno = b_errno_win32; pVssObj->AbortBackup(); } /* get latest info about writer status */ CheckWriterStatus(); hr = pVssObj->SaveAsXML(&xml); if (SUCCEEDED(hr)) { m_metadata = xml; } else { m_metadata = NULL; } /* FIXME?: The docs http://msdn.microsoft.com/en-us/library/aa384582%28v=VS.85%29.aspx say this isn't required... */ if (m_uidCurrentSnapshotSet != GUID_NULL) { VSS_ID idNonDeletedSnapshotID = GUID_NULL; LONG lSnapshots; pVssObj->DeleteSnapshots( m_uidCurrentSnapshotSet, VSS_OBJECT_SNAPSHOT_SET, false, &lSnapshots, &idNonDeletedSnapshotID); m_uidCurrentSnapshotSet = GUID_NULL; } if (m_bWriterStatusCurrent) { m_bWriterStatusCurrent = false; pVssObj->FreeWriterStatus(); } pVssObj->Release(); m_pVssObject = NULL; // Call CoUninitialize if the CoInitialize was performed sucesfully if (m_bCoInitializeCalled) { CoUninitialize(); m_bCoInitializeCalled = false; } return bRet; }