Esempio n. 1
0
// Delete the given shadow copy set 
void VssClient::DeleteSnapshotSet(VSS_ID snapshotSetID)
{
    FunctionTracer ft(DBG_INFO);

    // Print the deleted shadow copy...
    ft.WriteLine(L"- Deleting shadow copy set " WSTR_GUID_FMT L" ...", GUID_PRINTF_ARG(snapshotSetID));

    // Perform the actual deletion
    LONG lSnapshots = 0;
    VSS_ID idNonDeletedSnapshotID = GUID_NULL;
    HRESULT hr = m_pVssObject->DeleteSnapshots(
        snapshotSetID, 
        VSS_OBJECT_SNAPSHOT_SET,
        FALSE,
        &lSnapshots,
        &idNonDeletedSnapshotID);

    if (FAILED(hr))
    {
        ft.WriteLine(L"Error while deleting shadow copies...");
        ft.WriteLine(L"- Last shadow copy that could not be deleted: " WSTR_GUID_FMT, GUID_PRINTF_ARG(idNonDeletedSnapshotID));
        CHECK_COM_ERROR(hr, L"m_pVssObject->DeleteSnapshots(snapshotSetID, VSS_OBJECT_SNAPSHOT_SET,FALSE,&lSnapshots,&idNonDeleted)");
    }
}
Esempio n. 2
0
// Make the volumes in this list read-write using VDS API
void VssClient::MakeVolumesReadWrite(vector<wstring> snapshotVolumes)
{
    FunctionTracer ft(DBG_INFO);

    ft.Trace(DBG_INFO, L"Clearing read-only on %d volumes ... ", snapshotVolumes.size());

    // Get the VDS loader
    CComPtr<IVdsServiceLoader> pLoader;
    CHECK_COM(CoCreateInstance(CLSID_VdsLoader,
        NULL,
        CLSCTX_LOCAL_SERVER,
        __uuidof(IVdsServiceLoader),
        (void **)&pLoader));

    // Get the service interface pointer
    CComPtr<IVdsService> pService;
    CHECK_COM(pLoader->LoadService(NULL, &pService));

    CHECK_COM(pService->WaitForServiceReady());

    vector<wstring> clearedVolumes;

    // Get the unique volume names for the cached snapshot volume names 
    // which might change after the break
    vector<wstring> snapshotVolumeUniqueNames;
    for (unsigned i = 0; i < snapshotVolumes.size( ); i++)
        snapshotVolumeUniqueNames.push_back(GetUniqueVolumeNameForMountPoint(snapshotVolumes[i]));


    // Enumerate the Software providers
    HRESULT hr;
    CComPtr<IEnumVdsObject> pEnumProvider;
    CHECK_COM(pService->QueryProviders(VDS_QUERY_SOFTWARE_PROVIDERS,&pEnumProvider));
    vector< CComPtr<IUnknown> > providers = EnumerateVdsObjects(pEnumProvider);
    for(unsigned iProvider = 0; iProvider < providers.size(); iProvider++)
    {
        // QueryInterface for IVdsSwProvider
        CComQIPtr<IVdsSwProvider> pSwProvider = providers[iProvider];

        ft.Trace(DBG_INFO, L"- Provider %d", iProvider);

        // Enumerate packs for this provider
        CComPtr<IEnumVdsObject> pEnumPack;
        CHECK_COM(pSwProvider->QueryPacks(&pEnumPack));
        vector< CComPtr<IUnknown> > packs = EnumerateVdsObjects(pEnumPack);
        for(unsigned iPack = 0; iPack < packs.size(); iPack++)
        {
            // QueryInterface for IVdsPack
            CComQIPtr<IVdsPack> pPack = packs[iPack];

            ft.Trace(DBG_INFO, L"- Pack %d/%d", iPack, iProvider);

            // Enumerate volumes
            CComPtr<IEnumVdsObject> pEnumVolumes;
            hr = pPack->QueryVolumes(&pEnumVolumes);
            if (FAILED(hr)) {
                if (hr == VDS_E_INVALID_PACK) {
                    hr = S_OK;
                } else ft.Trace( DBG_INFO, L"COM Error: GetProperties for VDS pack failed. hr = 0x%08lx", hr);
                continue;
            }

            vector< CComPtr<IUnknown> > volumes = EnumerateVdsObjects(pEnumVolumes);
            for(unsigned iVol = 0; iVol < volumes.size(); iVol++)
            {
                // QueryInterface for IVdsVolumeMF and IVdsVolume
                CComQIPtr<IVdsVolume> pVolume = volumes[iVol];

                // Get volume properties. Ignore deleted volumes
                VDS_VOLUME_PROP volProp;
                HRESULT innerHR = pVolume->GetProperties(&volProp);
                if (innerHR == VDS_E_OBJECT_DELETED )
                    continue;

                CHECK_COM_ERROR(innerHR, L"pVolume->GetProperties(&volProp)");

                // Skip failed volumes
                if ( (volProp.status == VDS_VS_FAILED) && (volProp.health == VDS_H_FAILED) || !volProp.pwszName)
                    continue;

                // Skip hidden volumes (it fails GetVolumeNameForMountPoint)
                if (volProp.ulFlags & VDS_VF_HIDDEN)
                    continue;

                // Automatically call CoTaskMemFree on this pointer at the end of scope
                CAutoComPointer ptrAutoCleanup(volProp.pwszName);

                // Get the initial device name (normally with the format \\?\GLOBALROOT\Device\HarddiskVolumeXX)
                wstring name = volProp.pwszName;

                // Get the unique volume guid name for this device name.
                wstring uniqueVolumeName = GetUniqueVolumeNameForMountPoint(name);

                ft.Trace(DBG_INFO, L"- Found volume %s [device = %s] in %d/%d", 
                    uniqueVolumeName.c_str(), name.c_str(), iPack, iProvider);

                // Check to see if this is one of our volumes. If not, continue
                if (!FindStringInList(uniqueVolumeName, snapshotVolumeUniqueNames))
                    continue;

                // Clear the read-only flag
                ft.WriteLine(L"- Clearing read-only flag for volume %s [%s] ...", uniqueVolumeName.c_str(), name.c_str());

                CHECK_COM(pVolume->ClearFlags(VDS_VF_READONLY));

                // Force-dismounts the volume 
                // since we want to re-mount the file system as read-write
                CComQIPtr<IVdsVolumeMF> pVolumeMF = pVolume;
                ft.WriteLine(L"- Dismounting volume %s ...", name.c_str());
                CHECK_COM(pVolumeMF->Dismount(TRUE, FALSE));

                clearedVolumes.push_back(uniqueVolumeName);
            }
        }
    }

    // Check that all volumes have been cleared ...
    if (clearedVolumes.size() != snapshotVolumeUniqueNames.size())
    {
        ft.WriteLine(L"WARNING: some volumes were not succesfully converted to read-write!");

        for (unsigned i = 0; i < snapshotVolumeUniqueNames.size(); i++)
            if (!FindStringInList(snapshotVolumeUniqueNames[i], clearedVolumes))
                ft.WriteLine(L"- Volume %s not found on the system. Clearing the read-only flag failed on it.",
                    snapshotVolumeUniqueNames[i].c_str());
    }
}
Esempio n. 3
0
// Delete all the shadow copies in the system
void VssClient::DeleteAllSnapshots()
{
    FunctionTracer ft(DBG_INFO);

    // Get list all shadow copies. 
    CComPtr<IVssEnumObject> pIEnumSnapshots;
    HRESULT hr = m_pVssObject->Query( GUID_NULL, 
            VSS_OBJECT_NONE, 
            VSS_OBJECT_SNAPSHOT, 
            &pIEnumSnapshots );

    CHECK_COM_ERROR(hr, L"m_pVssObject->Query(GUID_NULL, VSS_OBJECT_NONE, VSS_OBJECT_SNAPSHOT, &pIEnumSnapshots )")

    // If there are no shadow copies, just return
    if (hr == S_FALSE) 
    {
        ft.WriteLine(L"\nThere are no shadow copies on the system\n");
        return;
    } 

    // Enumerate all shadow copies. Delete each one
    VSS_OBJECT_PROP Prop;
    VSS_SNAPSHOT_PROP& Snap = Prop.Obj.Snap;
    
    while(true)
    {
        // Get the next element
        ULONG ulFetched;
        hr = pIEnumSnapshots->Next( 1, &Prop, &ulFetched );
        CHECK_COM_ERROR(hr, L"pIEnumSnapshots->Next( 1, &Prop, &ulFetched )")

        // We reached the end of list
        if (ulFetched == 0)
            break;

        // Automatically call VssFreeSnapshotProperties on this structure at the end of scope
        CAutoSnapPointer snapAutoCleanup(&Snap);

        // Print the deleted shadow copy...
        ft.WriteLine(L"- Deleting shadow copy " WSTR_GUID_FMT L" on %s from provider " WSTR_GUID_FMT L" [0x%08lx]...", 
            GUID_PRINTF_ARG(Snap.m_SnapshotId),
            Snap.m_pwszOriginalVolumeName,
            GUID_PRINTF_ARG(Snap.m_ProviderId),
            Snap.m_lSnapshotAttributes);

        // Perform the actual deletion
        LONG lSnapshots = 0;
        VSS_ID idNonDeletedSnapshotID = GUID_NULL;
        hr = m_pVssObject->DeleteSnapshots(
            Snap.m_SnapshotId, 
            VSS_OBJECT_SNAPSHOT,
            FALSE,
            &lSnapshots,
            &idNonDeletedSnapshotID);

        if (FAILED(hr))
        {
            ft.WriteLine(L"Error while deleting shadow copies...");
            ft.WriteLine(L"- Last shadow copy that could not be deleted: " WSTR_GUID_FMT, GUID_PRINTF_ARG(idNonDeletedSnapshotID));
            CHECK_COM_ERROR(hr, L"m_pVssObject->DeleteSnapshots(Snap.m_SnapshotId, VSS_OBJECT_SNAPSHOT,FALSE,&lSnapshots,&idNonDeleted)");
        }
    }
}