无法访问卷影复制服务快照卷

时间:2017-01-13 22:10:38

标签: c++ qt volume-shadow-service

您好我无法让卷影复制服务适用于使用QT编写的C ++程序。快照已成功创建,但我无法通过我的程序或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 01:42 PM错误:无法打开源文件   \\?\ GLOBALROOT \设备\ HarddiskVolumeShadowCopy38 \用户\乔希\桌面\ awef \ awef3 \ awefawefawef    - 复制(10)waefawefawefawefawefawef - Copyawefawefawefawefawefwefawefawef.docx。

     

01-13-2017 01:42 PM错误:   找不到网络路径。

     

01-13-2017 01:44 PM错误:无法打开源文件   \设备\ HarddiskVolumeShadowCopy40 \用户\乔希\桌面\ awef \ awef3 \ awefawefawef    - 复制(10)waefawefawefawefawefawef - Copyawefawefawefawefawefwefawefawef.docx。

     

01-13-2017 01:44 PM错误:   系统找不到指定的路径。

当我尝试从运行提示符中打开相同的文件时,它只是说Windows无法找到 filename 等。

我验证了快照是使用带有此输出的vssadmin列表阴影创建的:

  

卷影副本集ID的内容:   {968d9034-3aee-494b-ae78-82af04a15686}包含1个卷影副本   创作时间:2017年1月13日下午1:40:09         卷影副本ID:{1109bad9-7d01-40f2-9141-cda25b313810}            原始卷:(C:)\?\卷{b3fc9fb7-0000-0000-0000-100000000000}            卷影复制卷:\?\ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy38            始发机:joshdesktop10            服务机器:joshdesktop10            提供商:&#39; Microsoft Software Shadow Copy提供程序1.0&#39;            键入:FileShareRollback            属性:没有作家,差异

     

卷影副本集ID的内容:{d6519b09-8325-4c1c-90bc-935a39f2189a}   创建时包含1个卷影副本:1/13/2017 1:44:07 PM         卷影副本ID:{21e1b83e-db79-4a29-95b0-65cc5c7d08a8}            原始卷:(C:)\?\卷{b3fc9fb7-0000-0000-0000-100000000000}            卷影复制卷:\?\ GLOBALROOT \ Device \ HarddiskVolumeShadowCopy40            始发机:joshdesktop10            服务机器:joshdesktop10            提供商:&#39; Microsoft Software Shadow Copy提供程序1.0&#39;            键入:FileShareRollback            属性:没有作家,差异

正如您所看到的那样,它们是差异备份......这可能是问题吗?

任何想法?谢谢!

1 个答案:

答案 0 :(得分:0)

Google启发了我... here如果不使用Win32 API函数FindFirstFile / FindNextFile,则无法访问VSS快照卷。有一种解决方法...将快照卷安装为符号链接并使用该链接访问文件。这是我使用的代码:

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"));

还要小心删除符号目录链接,如here所述。