Корректный поток резервного копирования VSS — ошибка VSS_E_BAD_STATE

#c #c #windows #winapi

#c #c #Windows #winapi

Вопрос:

У меня возникли проблемы с получением задания резервного копирования, работающего в VSS и C . Сейчас он находится на этапе работы и резервного копирования файлов, но при вызове происходит сбой BackupComplete() с результатом VSS_E_BAD_STATE , поэтому я хотел бы услышать мнение любого, кто знаком с VSS, о том, корректен ли мой поток. В настоящее время я делаю следующее:

 if( !CHECK_HRESULT(::CreateVssBackupComponents(amp;m_pBackupComponents))  )
{
    throw;
}

if( !CHECK_HRESULT((hr = m_pBackupComponents->InitializeForBackup())) )
{
    throw;
}

WCHAR wszVolumePathName[MAX_PATH];
GUID snapshotId;
BOOL supported = TRUE;
HRESULT hr;
SnapshotMap::iterator it;
BOOL bWorked = ::GetVolumePathName(path.c_str(), wszVolumePathName, MAX_PATH); 

if( !bWorked )
{
    throw;
}

if( !CHECK_HRESULT((hr = m_pBackupComponents->IsVolumeSupported(GUID_NULL, wszVolumePathName, amp;supported))) || !supported )
{
    throw;
}

GUID snapshotSetId;
if( !CHECK_HRESULT((hr = m_pBackupComponents->StartSnapshotSet(amp;snapshotSetId))) )
{
    throw;
}

m_SnapshotIdList.push_back(snapshotId);

if( !CHECK_HRESULT((hr = m_pBackupComponents->AddToSnapshotSet(wszVolumePathName, GUID_NULL, amp;snapshotId))) )
{
    throw;
}

if( !CHECK_HRESULT((hr = m_pBackupComponents->SetBackupState(FALSE, FALSE, VSS_BT_COPY, FALSE))) )
{
    throw;
}

CComPtr<IVssAsync> pPrepareForBackupResults; 
if( !CHECK_HRESULT((hr = m_pBackupComponents->PrepareForBackup(amp;pPrepareForBackupResults))) )
{
    throw;
}

if( !CHECK_HRESULT((hr = pPrepareForBackupResults->Wait())) )
{
    pPrepareForBackupResults.Release();
    throw;
}

HRESULT hrPrepareForBackupResults; 
if( !CHECK_HRESULT((hr = pPrepareForBackupResults->QueryStatus(amp;hrPrepareForBackupResults, NULL))) )
{
    pPrepareForBackupResults.Release();
    throw;
}

pPrepareForBackupResults.Release();
if( hrPrepareForBackupResults != VSS_S_ASYNC_FINISHED )
{
    throw;
}

CComPtr<IVssAsync> pDoSnapshotSetResults;
if( !CHECK_HRESULT((hr = m_pBackupComponents->DoSnapshotSet(amp;pDoSnapshotSetResults))) )
{
    throw;
}

m_VssSyncList.push_back(pDoSnapshotSetResults);

VSS_SNAPSHOT_PROP snapshotProperties;
if( !CHECK_HRESULT((hr = m_pBackupComponents->GetSnapshotProperties(snapshotId, amp;snapshotProperties))) )
{
    throw;
}

TSTRING newPath(snapshotProperties.m_pwszSnapshotDeviceObject);
m_SnapshotMap.insert(SnapshotMap_Entry(TSTRING(wszVolumePathName), newPath));
newPath.append(path.substr(2));

<Backup files here>

::VssFreeSnapshotProperties(amp;snapshotProperties);

for( SnapshotIdList::iterator it = m_SnapshotIdList.begin(); it != m_SnapshotIdList.end(); it   )
{
    LONG cDeletedSnapshots; 
    GUID nonDeletedSnapshotId;
    m_pBackupComponents->DeleteSnapshots(*it, VSS_OBJECT_SNAPSHOT_SET, TRUE, amp;cDeletedSnapshots, amp;nonDeletedSnapshotId); 
}

m_SnapshotIdList.clear();

for( VssSyncList::iterator it = m_VssSyncList.begin(); it != m_VssSyncList.end(); it   )
{
    (*it).Release();
}

m_VssSyncList.clear();

CComPtr<IVssAsync> pBackupCompleteResults;
if( !CHECK_HRESULT((hr = m_pBackupComponents->BackupComplete(amp;pBackupCompleteResults))) )
{
    throw;
}
else
{
    if( !CHECK_HRESULT((hr = pBackupCompleteResults->Wait())) )
    {
        throw;
    }

    HRESULT hrBackupCompleteResults; 
    if( CHECK_HRESULT(pBackupCompleteResults->QueryStatus(amp;hrBackupCompleteResults, NULL)) )
    {
        if( hrBackupCompleteResults != VSS_S_ASYNC_FINISHED )
        {
            throw;
        }
    }

    pBackupCompleteResults.Release();
}

m_SnapshotMap.clear();
  

Кажется, что что-то, что я вызываю, находится в неправильном порядке, но, просматривая документацию и различные источники, я не могу понять, что находится в неправильном порядке.

Есть ли что-то ослепительно очевидное, что я пропустил?

Ответ №1:

Вызываете ли вы SetBackupSucceeded после обработки каждого компонента и до вызова BackupComplete??

Комментарии:

1. Я не использую режим компонента. Первый параметр SetBackupState равен FALSE, что, я считаю, правильно для простого резервного копирования файлов

2. Обновлено, чтобы содержать фактический источник.

Ответ №2:

Я сталкивался с этими ошибками, когда изучал VSS, в основном ошибка была связана с вызовом последовательности VSS с помощью CoInitialize (). Пожалуйста, проверьте, есть ли у вас CoInitialize и CoUninitialize до и после последовательности VSS.

Комментарии:

1. Это многопоточное приложение, и я вызываю CoInitializeEx() в основном потоке запуска. Без этого все вызовы функций завершаются неудачей.