I'm experiencing the same problem seen on this question, i have a lot of vhdx disk listed that seens that are not being properly "removed", even after detaching and deleting them.
There's no answer on the mentioned question as the OP "solved" the issue by rebooting the system.
I'm able to find these "ghost" disks with a call to QueryVDisks, pVDisk->Open
works on them, but im not sure what the proper way to completly "release" the disk, i tried calling dettach again but it result in the error:
0x80042935
VDS_E_VD_ALREADY_DETACHED
What is the proper way to completly remove a virtual disk created?
void detachVirtualDisk(const std::wstring& diskPath)
{
CComPtr<IVdsService> pSvc;
CComPtr<IVdsServiceLoader> pLoader;
CComQIPtr<IVdsVdProvider> pProv;
hr = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
hr = pLoader.CoCreateInstance(CLSID_VdsLoader, nullptr, CLSCTX_LOCAL_SERVER);
if (SUCCEEDED(hr))
{
hr = pLoader->LoadService(nullptr, &pSvc);
pLoader.Release();
}
if (!pSvc)
{
wprintf_s(L"Could not connect to VDS, error 0x%X\n", hr);
return;
}
pSvc->WaitForServiceReady();
CComPtr<IEnumVdsObject> pEnum;
hr = E_FAIL;
hr = pSvc->QueryProviders(VDS_QUERY_VIRTUALDISK_PROVIDERS, &pEnum);
if (SUCCEEDED(hr))
{
ULONG cFetched = 0;
for (CComPtr<IUnknown> pUnk; pEnum->Next(1, &pUnk, &cFetched) == S_OK; pUnk.Release())
{
VDS_PROVIDER_PROP vpp{};
CComQIPtr<IVdsProvider> provider(pUnk);
hr = provider->GetProperties(&vpp);
if (SUCCEEDED(hr))
{
CoTaskMemFree(vpp.pwszName);
CoTaskMemFree(vpp.pwszVersion);
if (IsEqualGUID(VDS_VIRTUAL_DISK_PROVIDER, vpp.id))
{
hr = provider->QueryInterface(IID_PPV_ARGS(&pProv));
break;
}
}
}
}
if (FAILED(hr) || !pProv)
{
wprintf_s(L"Failed to obtain IVdsVdProvider interface, error was 0x%X\n", hr);
return;
}
// Enumerate virtual disks
CComPtr<IEnumVdsObject> pDiskEnum;
hr = pProv->QueryVDisks(&pDiskEnum);
if (FAILED(hr))
{
wprintf_s(L"Failed to enumerate virtual disks, error was 0x%X\n", hr);
return;
}
ULONG cFetched = 0;
for (CComPtr<IUnknown> pUnk; pDiskEnum->Next(1, &pUnk, &cFetched) == S_OK; pUnk.Release())
{
CComQIPtr<IVdsVDisk> pVDisk(pUnk);
if (!pVDisk)
continue;
VDS_VDISK_PROPERTIES props{};
hr = pVDisk->GetProperties(&props);
if (FAILED(hr) || props.pPath != diskPath)
continue;
CComPtr<IVdsOpenVDisk> pVdsOpenVDisk;
hr = pVDisk->Open(VIRTUAL_DISK_ACCESS_ALL, OPEN_VIRTUAL_DISK_FLAG_NONE, OPEN_VIRTUAL_DISK_RW_DEPTH_DEFAULT, &pVdsOpenVDisk);
if (FAILED(hr) || !pVdsOpenVDisk)
continue;
hr = pVdsOpenVDisk->Detach(DETACH_VIRTUAL_DISK_FLAG_NONE, 0);
}
}