Невозможно получить доступ к тому. Снимок тома службы теневого копирования

Привет, у меня проблемы с получением службы теневого копирования томов для моей программы, написанной на C++ с QT. Снимок создан успешно, однако я не могу получить к нему доступ ни через свою программу, ни через приглашение Windows (не уверен, если это вообще возможно). Я попытался получить доступ к снимку, используя оба префикса \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy27\ и \Device\HarddiskVolumeShadowCopy28\ (сгенерированные из моей программы с нужным номером в конце). Также снимки выглядят так, как будто они являются дифференциальными снимками, хотя я использовал VSS_BT_COPY и VSS_BT_FULL в качестве состояния. Я пытался использовать VSS_CTX_NAS_ROLLBACK в качестве контекста, который создавал постоянные моментальные снимки, поэтому я попытался удалить их все, прежде чем снова попытаться получить доступ к моментальным снимкам в программе, но на этот раз с контекстом VSS_CTX_FILE_SHARE_BACKUP, но безуспешно. Вот код создания снимка (обработка ошибок удалена):

void Worker::setupVSS(BackupJob &job)
{
    HRESULT result;
    //backupComponents is a class member variable
    //IVssBackupComponents *backupComponents;

    result = CreateVssBackupComponents(&backupComponents);

    VSS_ID snapshotSetId;
    result = backupComponents->InitializeForBackup();

    //tried both of these
    //result = backupComponents->SetBackupState(FALSE, FALSE, VSS_BT_COPY);
    result = backupComponents->SetBackupState(FALSE, FALSE, VSS_BT_FULL);

    //tried both of these
    //result = backupComponents->SetContext(VSS_CTX_NAS_ROLLBACK);
    result = backupComponents->SetContext(VSS_CTX_FILE_SHARE_BACKUP);

    result = backupComponents->StartSnapshotSet(&snapshotSetId);

    VSS_ID snapshotId;
    wchar_t *source;
    //this line gets the drive letter with : and \
    QString driveLetter = job.getSource().mid(0,3);
    driveLetter.toWCharArray(source);
    //QString("D:\\").toWCharArray(source);
    result = backupComponents->AddToSnapshotSet(source, GUID_NULL, &snapshotId);

    IVssAsync *async;
    result = backupComponents->DoSnapshotSet(&async);

    result = async->Wait();
    async->Release();

    VSS_SNAPSHOT_PROP prop;
    result = backupComponents->GetSnapshotProperties(snapshotId, &prop);

    QString vssPrefix = QString::fromWCharArray(prop.m_pwszSnapshotDeviceObject);
    job.setVSSPrefix(vssPrefix);
}

А вот и файл с открытым кодом:

QString sourceFileString = job.getCurrentFileSource(fileCount);
if (job.getVSS())
{
    QString prefix = job.getVSSPrefix();
    //tried this comment to remove ? and globalroot from prefix without success
    //prefix = prefix.mid(prefix.indexOf("\\Device"));
    prefix.append("\\");
    prefix = QDir::fromNativeSeparators(prefix);
    sourceFileString.replace(0,3,prefix);
}
QFile sourceFile(sourceFileString);
if (!sourceFile.open(QIODevice::ReadOnly))
{
    updateStatus("<font color=\"red\">ERROR: Couldn't open source file " + QDir::toNativeSeparators(sourceFile.fileName()) + ".</font>");
    updateStatus("<font color=\"red\">ERROR: " + sourceFile.errorString() + "</font>");
    errorsFound = true;
    break;
}

Вот ошибки, которые дает QT из-за неудачной попытки открытия файла:

01-13-2017 13:42 ОШИБКА: Не удалось открыть исходный файл \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy38\Users\Josh\Desktop\awef\awef3\awefawefawef - Копировать (10)waefawefawefawefawefawef - Copyawefawefawefawefawewewewewewewewewewe.wef

01-13-2017 13:42 ОШИБКА: Сетевой путь не найден.

13.01.2017 13:44 ОШИБКА: Не удалось открыть исходный файл \Device\HarddiskVolumeShadowCopy40\Users\Josh\Desktop\awef\awef3\awefawefawef - Копировать (10)waefawefawefawefawefawef - Copyawefawefawefawefawefwefawefawefweocwexwex.

01-13-2017 13:44 ОШИБКА: Система не может найти указанный путь.

Когда я пытаюсь открыть те же файлы из командной строки, он просто говорит, что Windows не может найти имя файла и т.д..

Я проверил, что моментальные снимки создаются с использованием теней списка vssadmin с таким выводом:

Содержимое идентификатора набора теневых копий: {968d9034-3aee-494b-ae78-82af04a15686} Содержит 1 теневую копию во время создания: 13.01.2017 13:40:09 Идентификатор теневой копии: {1109bad9-7d01-40f2-9141-cda25b313810} Исходный том: (C:)\?\Volume{b3fc9fb7-0000-0000-0000-100000000000}\ Том теневого копирования: \?\GLOBALROOT\Device\HarddiskVolumeShadowCopy38 Исходный компьютер: joshdesktop10 Сервисный компьютер: joshdesktop10 Поставщик: "Microsoft" Поставщик Shadow Copy 1.0'Тип: FileShareRollback Атрибуты: Нет авторов, Дифференциальный

Содержимое идентификатора набора теневых копий: {d6519b09-8325-4c1c-90bc-935a39f2189a} Содержит 1 теневую копию во время создания: 13.01.2017 13:44:07 Идентификатор теневой копии: {21e1b83e-db79-4a29-95b0-65cc5c7d08a8} Исходный том: (C:)\?\Volume{b3fc9fb7-0000-0000-0000-100000000000}\ Том теневого копирования: \?\GLOBALROOT\Device\HarddiskVolumeShadowCopy40 Исходный компьютер: joshdesktop10 Сервисный компьютер: joshdesktop10 Поставщик Microsoft: Поставщик Shadow Copy 1.0'Тип: FileShareRollback Атрибуты: Нет авторов, Дифференциальный

Как вы можете видеть, они являются дифференциальными резервными копиями... может ли это быть проблемой?

Есть идеи?? Спасибо!

1 ответ

Google просветил меня... так как здесь вы не можете получить доступ к томам снимков VSS без использования функций Win32 API FindFirstFile/FindNextFile. Существует обходной путь... смонтируйте том снимка как символическую ссылку и используйте ссылку для доступа к файлам. Вот код, который я использовал:

VSS_SNAPSHOT_PROP prop;
result = backupComponents->GetSnapshotProperties(snapshotId, &prop);    
wchar_t *snapVol = prop.m_pwszSnapshotDeviceObject;
wcsncat(snapVol, L"\\", 1);
if (QDir("C:\\repVSSVol").exists())
    RemoveDirectory(L"C:\\repVSSVol");
if (CreateSymbolicLink(L"C:\\repVSSVol", snapVol, SYMBOLIC_LINK_FLAG_DIRECTORY) == 0)
    win32Error(TEXT("CreateSymbolicLink"));

Также будьте осторожны при удалении символических ссылок на каталоги, как описано здесь.

Другие вопросы по тегам