草庐IT

windows - 帮助 : MS Virtual Disk Service to Access Volumes and Discs on Local Machine

coder 2024-06-15 原文

这是我的代码,通过它我成功初始化了 VDS 服务并获取了包,但是当我在 IVdsPack 对象上调用 QueryVolumes 时,我能够获取 IEnumVdsObjects 但无法通过 IEnumVdsObject::Next 方法获取 IUnknown* 数组,它用 IUnkown* = NULL 返回 S_FALSE。所以这个 IUnknown* 不能用于 IVdsVolume 的 QueryInterface

下面是我的代码

    HRESULT hResult;
IVdsService* pService = NULL;
IVdsServiceLoader *pLoader = NULL;

//Launch the VDS Service
hResult = CoInitialize(NULL);
if( SUCCEEDED(hResult) )
{
    hResult = CoCreateInstance( 
                                CLSID_VdsLoader,
                                NULL,
                                CLSCTX_LOCAL_SERVER,
                                IID_IVdsServiceLoader,
                                (void**) &pLoader
                                );

    //if succeeded load VDS on local machine
    if( SUCCEEDED(hResult) )
        pLoader->LoadService(NULL, &pService);

    //Done with Loader now release VDS Loader interface
    _SafeRelease(pLoader);

    if( SUCCEEDED(hResult) )
    {
        hResult = pService->WaitForServiceReady();
        if ( SUCCEEDED(hResult) )
        {
            AfxMessageBox(L"VDS Service Loaded");
            IEnumVdsObject* pEnumVdsObject = NULL;
            hResult = pService->QueryProviders(VDS_QUERY_SOFTWARE_PROVIDERS, &pEnumVdsObject);

            IUnknown* ppObjUnk ;
            IVdsSwProvider* pVdsSwProvider = NULL;
            IVdsPack* pVdsPack = NULL;
            IVdsVolume* pVdsVolume = NULL;
            ULONG ulFetched = 0;

            hResult = E_INVALIDARG;
            while(!SUCCEEDED(hResult))
            {
                hResult = pEnumVdsObject->Next(1, &ppObjUnk, &ulFetched);
                hResult = ppObjUnk->QueryInterface(IID_IVdsSwProvider, (void**)&pVdsSwProvider);
                if(!SUCCEEDED(hResult))
                    _SafeRelease(ppObjUnk);
            }
            _SafeRelease(pEnumVdsObject);
            _SafeRelease(ppObjUnk);

            hResult = pVdsSwProvider->QueryPacks(&pEnumVdsObject);

            hResult = E_INVALIDARG;
            while(!SUCCEEDED(hResult))
            {
                hResult = pEnumVdsObject->Next(1, &ppObjUnk, &ulFetched);
                hResult = ppObjUnk->QueryInterface(IID_IVdsPack, (void**)&pVdsPack);
                if(!SUCCEEDED(hResult))
                    _SafeRelease(ppObjUnk);
            }

            _SafeRelease(pEnumVdsObject);
            _SafeRelease(ppObjUnk);

            hResult = pVdsPack->QueryVolumes(&pEnumVdsObject);
            pEnumVdsObject->Reset();

            hResult = E_INVALIDARG;
            ulFetched = 0;
            BOOL bDone = FALSE;
            while(!SUCCEEDED(hResult))
            {
                hResult = pEnumVdsObject->Next(1, &ppObjUnk, &ulFetched);
                //hResult = ppObjUnk->QueryInterface(IID_IVdsVolume, (void**)&pVdsVolume);
                if(!SUCCEEDED(hResult))
                    _SafeRelease(ppObjUnk);
            }
            _SafeRelease(pEnumVdsObject);
            _SafeRelease(ppObjUnk);
            _SafeRelease(pVdsPack);
            _SafeRelease(pVdsSwProvider);

//              hResult = pVdsVolume->AddAccessPath(TEXT("G:\\"));
            if(SUCCEEDED(hResult))
                AfxMessageBox(L"Add Access Path Successfully");
            else
                AfxMessageBox(L"Unable to Add access path");

            //UUID of IVdsVolumeMF {EE2D5DED-6236-4169-931D-B9778CE03DC6}
            static const GUID GUID_IVdsVolumeMF = {0xEE2D5DED, 0x6236, 4169,{0x93, 0x1D, 0xB9, 0x77, 0x8C, 0xE0, 0x3D, 0XC6} };

            hResult = pService->GetObject(GUID_IVdsVolumeMF, VDS_OT_VOLUME, &ppObjUnk);
            if(hResult == VDS_E_OBJECT_NOT_FOUND)
                AfxMessageBox(L"Object Not found");
            if(hResult == VDS_E_INITIALIZED_FAILED)
                AfxMessageBox(L"Initialization failed");
//              pVdsVolume = reinterpret_cast<IVdsVolumeMF*>(ppObjUnk);
            if(SUCCEEDED(hResult))
            {
//                  hResult = pVdsVolume->AddAccessPath(TEXT("G:\\"));

                if(SUCCEEDED(hResult))
                {
                    IVdsAsync* ppVdsSync;
                    AfxMessageBox(L"Formatting is about to Start......");
//                      hResult = pVdsVolume->Format(VDS_FST_UDF, TEXT("UDF_FORMAT_TEST"), 2048, TRUE, FALSE, FALSE, &ppVdsSync);

                    if(SUCCEEDED(hResult))
                        AfxMessageBox(L"Formatting Started.......");
                    else
                    AfxMessageBox(L"Formatting Failed");
                }
                else
                    AfxMessageBox(L"Unable to Add Access Path");
            }
            _SafeRelease(pVdsVolume);
        }

        else
        {
            AfxMessageBox(L"VDS Service Cannot be Loaded");
        }
    }
}
_SafeRelease(pService);

最佳答案

您需要将其他循环移动到枚举 IVdsSwProviders 的 while 循环中。

我出于自己的目的修改了您的代码。你必须小心,因为我把它放在一起进行测试,因此不关心内存泄漏和释放 COM 对象。我也有很多调试打印:

#include "stdafx.h"
#include "initguid.h"
#include <vds.h>
#include <stdio.h>

#pragma comment( lib, "ole32.lib" )
#pragma comment( lib, "rpcrt4.lib" )

#define _SafeRelease(x) {if (NULL != x) { x->Release(); x = NULL; } }


void EnumerateDisks(IVdsPack* pPack)
{
    HRESULT hResult;
    ULONG ulFetched = 0;
    IUnknown* ppObjUnk ;
    IEnumVdsObject* pEnumVdsObject = NULL;  
    IVdsDisk* pVdsDisk = NULL;
    IVdsDisk2* pVdsDisk2 = NULL;
    IVdsAdvancedDisk* pVdsAdvancedDisk = NULL;

    if (pPack == 0)
        return;

    hResult = pPack->QueryDisks(&pEnumVdsObject);

    if (pEnumVdsObject == 0)
        return;

    while( true)
    {
        if (!pEnumVdsObject)
            break;

        hResult = pEnumVdsObject->Next(1, &ppObjUnk, &ulFetched);
        if (ulFetched == 0) break;

        hResult = ppObjUnk->QueryInterface(IID_IVdsDisk, (void**)&pVdsDisk);

        VDS_DISK_PROP diskProp;
        pVdsDisk->GetProperties(&diskProp);

        printf("----------------------------------------\n");
        wprintf(L"disk: %d\n", diskProp.status);
        wprintf(L"disk: %s\n", diskProp.pwszAdaptorName);
        wprintf(L"disk: %s\n", diskProp.pwszDevicePath);
        wprintf(L"disk: %s\n", diskProp.pwszFriendlyName);
        wprintf(L"disk: %s\n", diskProp.pwszName);
        wprintf(L"disk: %d\n", diskProp.dwDeviceType);
        wprintf(L"disk: %d\n", diskProp.dwMediaType);
        wprintf(L"disk: %d\n", diskProp.dwSignature);
        wprintf(L"disk: %d\n", diskProp.PartitionStyle);
        wprintf(L"disk: %d\n", diskProp.ReserveMode);
        wprintf(L"disk: %d\n", diskProp.ulFlags);

        VDS_PARTITION_PROP * pPropArray = NULL;
        LONG pNumberOfPartitions = 0;

        hResult = ppObjUnk->QueryInterface(IID_IVdsAdvancedDisk, (void**)&pVdsAdvancedDisk);        
        pVdsAdvancedDisk->QueryPartitions(&pPropArray, &pNumberOfPartitions);

        VDS_PARTITION_PROP * tmp = pPropArray;
        for (int i = 0; i < pNumberOfPartitions; ++i)
        {
            printf("Number: %d\n", tmp->ulPartitionNumber);
            printf("Style : %d\n", tmp->PartitionStyle);
            printf("Flags : %d\n", tmp->ulFlags);
            printf("Offset: %ull\n", tmp->ullOffset);
            printf("Size: %ull\n", tmp->ullSize);
            printf("MBR type: %d\n", tmp->Mbr.partitionType);
            printf("MBR type: %d\n", tmp->Mbr.bootIndicator);
            printf("MBR type: %d\n", tmp->Mbr.recognizedPartition);
            printf("MBR type: %d\n", tmp->Mbr.hiddenSectors);

            ++tmp;
        }
        CoTaskMemFree(pPropArray);
    }
}

void EnumerateVolumes(IVdsPack* pPack)
{
    HRESULT hResult;
    ULONG ulFetched = 0;
    IUnknown* ppObjUnk ;
    IEnumVdsObject* pEnumVdsObject = NULL;  
    IVdsVolume* pVdsVolume = NULL;

    if (pPack == 0)
        return;

    hResult = pPack->QueryVolumes(&pEnumVdsObject);

    if (pEnumVdsObject == 0)
        return;

    while( true)
    {
        hResult = pEnumVdsObject->Next(1, &ppObjUnk, &ulFetched);
        if (ulFetched == 0) break;

        hResult = ppObjUnk->QueryInterface(IID_IVdsVolume, (void**)&pVdsVolume);
        VDS_VOLUME_PROP volProp;
        pVdsVolume->GetProperties(&volProp);
        printf("Vol name  : %S\n", volProp.pwszName);
        printf("Vol health: %d\n", volProp.health);
    }
}

void EnumeratePacks(IVdsSwProvider* pProvider)
{
    HRESULT hResult;
    ULONG ulFetched = 0;
    IUnknown* ppObjUnk ;
    IEnumVdsObject* pEnumVdsObject = NULL;  
    IVdsPack* pVdsPack = NULL;

    if (pProvider == 0)
        return;

    hResult = pProvider->QueryPacks(&pEnumVdsObject);

    if (pEnumVdsObject == 0)
        return;

    while( true)
    {
        hResult = pEnumVdsObject->Next(1, &ppObjUnk, &ulFetched);
        if (ulFetched == 0) break;

        hResult = ppObjUnk->QueryInterface(IID_IVdsPack, (void**)&pVdsPack);
        VDS_PACK_PROP packProp;
        pVdsPack->GetProperties(&packProp);
        if (packProp.status == VDS_PS_ONLINE) {
            printf("Pack name  : %S\n", packProp.pwszName);
            printf("Pack status: %d\n", packProp.status);
            printf("Pack flags : %d\n", packProp.ulFlags);
            EnumerateDisks(pVdsPack);
            EnumerateVolumes(pVdsPack);
        }
    }
}


void EnumerateSoftwareProviders(IVdsService* pService)
{
    HRESULT hResult;
    ULONG ulFetched = 0;
    IUnknown* ppObjUnk ;
    IEnumVdsObject* pEnumVdsObject = NULL;
    IVdsSwProvider* pVdsSwProvider = NULL;

    hResult = pService->QueryProviders(VDS_QUERY_SOFTWARE_PROVIDERS, &pEnumVdsObject);
    while( true)
    {
        hResult = pEnumVdsObject->Next(1, &ppObjUnk, &ulFetched);
        if (ulFetched == 0) break;

        hResult = ppObjUnk->QueryInterface(IID_IVdsSwProvider,(void**)&pVdsSwProvider);
        EnumeratePacks(pVdsSwProvider);
    }
}


int __cdecl main(void) 
{
    //////////////////////////////////////////////////////////////////
    HRESULT hResult;
    IVdsService* pService = NULL;
    IVdsServiceLoader *pLoader = NULL;
    //Launch the VDS Service
    hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    // Initialize COM security
    CoInitializeSecurity(
        NULL,       // Allow *all* VSS writers to communicate back!
        -1,        // Default COM authentication service
        NULL,       // Default COM authorization service
        NULL,       // reserved parameter
        RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // Strongest COM authentication level
        RPC_C_IMP_LEVEL_IMPERSONATE,  // Minimal impersonation abilities 
        NULL,       // Default COM authentication settings
        EOAC_NONE,      // No special options
        NULL       // Reserved parameter
        );

    if( SUCCEEDED(hResult) )
    {
        hResult = CoCreateInstance( 
            CLSID_VdsLoader,
            NULL,
            CLSCTX_LOCAL_SERVER,
            IID_IVdsServiceLoader,
            (void**) &pLoader
            );

        //if succeeded load VDS on local machine
        if( SUCCEEDED(hResult) )
            pLoader->LoadService(NULL, &pService);
        //Done with Loader now release VDS Loader interface
        _SafeRelease(pLoader);

        if( SUCCEEDED(hResult) )
        {
            hResult = pService->WaitForServiceReady();
            if ( SUCCEEDED(hResult) )
            {
                EnumerateSoftwareProviders(pService);
                return 0;       
            }
        }
    }
    return -1;
}

关于windows - 帮助 : MS Virtual Disk Service to Access Volumes and Discs on Local Machine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2831846/

有关windows - 帮助 : MS Virtual Disk Service to Access Volumes and Discs on Local Machine的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  3. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  4. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  5. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  6. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  7. ruby-on-rails - 需要帮助最大化多个相似对象中的 3 个因素并适当排序 - 2

    我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night

  8. ruby - 帮助使用 Ruby 中的 "Whenever"gem 来执行 cron 任务 - 2

    我以前没有使用过cron,所以我不能确定我这样做是对的。我想要自动化的任务似乎没有运行。我在终端中执行了这些步骤:sudogeminstall每当切换到应用程序目录无论何时。(这创建了文件schedule.rb)我将此代码添加到schedule.rb:every10.minutesdorunner"User.vote",environment=>"development"endevery:hourdorunner"Digest.rss",:environment=>"development"end我将此代码添加到deploy.rb:after"deploy:symlink","depl

  9. ruby - 如何在 Ruby 中执行 Windows CLI 命令? - 2

    我在目录“C:\DocumentsandSettings\test.exe”中有一个文件,但是当我用单引号编写命令时`C:\DocumentsandSettings\test.exe(我无法在此框中显示),用于在Ruby中执行命令,我无法这样做,我收到的错误是找不到文件或目录。我尝试用“//”和“\”替换“\”,但似乎没有任何效果。我也使用过系统、IO.popen和exec命令,但所有的努力都是徒劳的。exec命令还使程序退出,这是我不想发生的。提前致谢。 最佳答案 反引号环境就像双引号,所以反斜杠用于转义。此外,Ruby会将空格解

  10. ruby - 错误 : Failed to build gem native extension on Windows - 2

    我在安装“redcarpet”gem时遇到以下错误。它在我friend的机器上安装没有问题。(我想安装它来运行yard)ruby版本:1.9.3命令输出:D:\Learning\Common_POM_FW\SampleProjects>yard[error]:Missing'redcarpet'gemforMarkdownformatting.Installitwith`geminstallredcarpet`D:\Learning\Common_POM_FW\SampleProjects>geminstallredcarpetTemporarilyenhancingPATHtoinc

随机推荐