帮助:MS虚拟磁盘服务访问本地计算机上的卷和光盘

这里是我的代码,我成功地初始化VDS服务,并获得包,但当我调用IVdsPack对象上的QueryVolumes,我能够获得IEnumVdsObjects但无法通过IEnumVdsObject :: Next方法获得IUnknown *数组,它会重新S_FALSE与IUnkown * = NULL。 所以这个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); 

你需要在你的while循环里面枚举你的IVdsSwProviders。

我修改你的代码是为了我自己的目的。 你必须小心,因为我把它扔在一起进行测试,因此不关心内存泄漏和释放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; }