Expose Snapshot?

Mar 24, 2009 at 10:19 PM
How do you expose a snapshot to a Drive letter? I can't get it to work with exposed locally. This is what I have:

oVSSImpl = VssUtils.LoadImplementation();
                oVSS = oVSSImpl.CreateVssBackupComponents();
                oVSS.InitializeForBackup(null);
                oVSS.SetBackupState(false, true, VssBackupType.Full, false);

                using (IVssAsync async = oVSS.GatherWriterMetadata())
                {
                    async.Wait();
                }

                gSet = oVSS.StartSnapshotSet();

                gSnapshot = oVSS.AddToSnapshotSet(strDriveToCapture, Guid.Empty);

                using (IVssAsync async = oVSS.PrepareForBackup())
                {
                    async.Wait();
                }

                using (IVssAsync async = oVSS.DoSnapshotSet())
                {
                    async.Wait();
                }

                oProps = oVSS.GetSnapshotProperties(gSnapshot);
string drive = oVSS.ExposeSnapshot(gSnapshot, null, VssVolumeSnapshotAttributes.ExposedLocally, null);

It gives me a value range exceeded error message. The exposed remotely arttibute works but not the locally attribute. I am using Vista x64

Any Ideas?

Thanks,
Kaleb
Coordinator
Mar 29, 2009 at 12:14 PM
There are a couple of problems with your code, which can be found out by reading the MSDN documentation (for once ;).

The first is that the last parameter to ExposeSnapshot must not be null unless exposing remotely (as a share).

The second problem is that only persistent shadow copies can be exposed as a drive letter (unless I'm mistaken) so you need to include a call to eg. SetContext(VssSnapshotContext.AppRollback) or similar.

Hope this helps!

Sincerely,
Peter
May 25, 2009 at 8:22 AM

Hello, I am trying to expose a snapshot and I'm also unable to. I'm receiving the range exceeded error on the ExposeSnapshot call.

I have tried setting the Context to RollbackRecovery, but I'm not sure I should even be doing this.
I have tried several variants on the exposesnapshot call, and I always receive the same error.

Please have a look if you can.

Regards,
Jochen

        Dim _sourcePath As String = "c:\"
        Dim oVSSImpl As Alphaleonis.Win32.Vss.IVssImplementation
        Dim oVSS As Alphaleonis.Win32.Vss.IVssBackupComponents
        Dim sVolume As String
        Dim oFI As New IO.DirectoryInfo(_sourcePath)
        Dim gSnapshot As Guid
        Dim gSnapshotSet As Guid
        'Dim oProps As Alphaleonis.Win32.Vss.VssSnapshotProperties
        Dim exposedDrive As String = "x:"
        Dim sleepTime As Integer = 20
        Try

            ' Load the Implementation specifi for this machine i.e Windowx XP , Vista, 32 or 64 Bit
            oVSSImpl = Alphaleonis.Win32.Vss.VssUtils.LoadImplementation()

            ' This is the main man for VSS Backups.
            Console.WriteLine("Initializing VssBackupComponents Object")
            oVSS = oVSSImpl.CreateVssBackupComponents
            oVSS.InitializeForBackup(Nothing)

            ' Setting backup context, do I need this to expose the copy later?
            oVSS.SetContext(Alphaleonis.Win32.Vss.VssVolumeSnapshotAttributes.RollbackRecovery)

            ' Tell VSS that we are requesting a backup with particular options
            Console.WriteLine("Setting Backup State")
            oVSS.SetBackupState(False, True, Alphaleonis.Win32.Vss.VssBackupType.Full, False)

            ' Tell all VSS Writers that we want their MetaData. We wait until all Writers have responded.
            Console.WriteLine("Waiting for VSS Writers to return their Metadata")
            Using async As Alphaleonis.Win32.Vss.IVssAsync = oVSS.GatherWriterMetadata()
                async.Wait()
            End Using
            ' INFO ONLY : Enumerate who responded to our GatherWriterMetadata request

            ' Create the Snapshot Set that we will place all our Snapshotted volumes into. (even tho here will only snapshot one volume)
            Console.WriteLine("Starting Snapshot Set")

            gSnapshotSet = oVSS.StartSnapshotSet()

            ' Add a Snapshot for the required Volume
            sVolume = oFI.Root.Name
            Console.WriteLine("Adding Volume " & sVolume & " to the Snapshot Set.")
            gSnapshot = oVSS.AddToSnapshotSet(sVolume, Guid.Empty)

            ' Notify all VSS Writers that the backup is about to start, we wait untuil they have indicated they are ready.
            Console.WriteLine("Informing VSS Writers that they should prepare for a Backup.")
            Using async As Alphaleonis.Win32.Vss.IVssAsync = oVSS.PrepareForBackup()
                async.Wait()
            End Using

            'Request that the Snapshot are created and wait until they are ready.
            Console.WriteLine("Tell VSS to create the actual Volume Shadow Copy.")
            Using async As Alphaleonis.Win32.Vss.IVssAsync = oVSS.DoSnapshotSet
                async.Wait()
            End Using
            Using async As Alphaleonis.Win32.Vss.IVssAsync = oVSS.BackupComplete
                async.Wait()
            End Using

            'oProps = oVSS.GetSnapshotProperties(gSnapshot)
            Console.WriteLine("Exposing the snapshot to " & exposedDrive)

            oVSS.ExposeSnapshot(gSnapshot, Nothing, Alphaleonis.Win32.Vss.VssVolumeSnapshotAttributes.ExposedLocally, exposedDrive)
            Console.WriteLine("Sleeping " & sleepTime & " seconds.")
            System.Threading.Thread.Sleep(sleepTime)


            Console.WriteLine("Deleting Snapshot Set.")
            oVSS.DeleteSnapshotSet(gSnapshotSet, True)
        Catch ex As Exception
            Console.WriteLine(ex.ToString & vbCrLf & ex.StackTrace)
        End Try

Jun 26, 2009 at 11:28 PM

i simply can not get it to work. I can however continu my work with exposing the shadow remotely.

 

oVSS.ExposeSnapshot(oProps.SnapshotId, "\", Alphaleonis.Win32.Vss.VssVolumeSnapshotAttributes.ExposedRemotely, "ExposedShadow")

Coordinator
Aug 23, 2009 at 7:18 AM

On what platform (windows version) are you running this code?

 

Nov 26, 2009 at 8:28 PM

The second parameter of ExposeSnapshot must be null for ExposedLocally (according to docs) and the last parameter should be a drive or mount point (i.e. "Y:\")

The context should be AppRollback.

At least this worked fine for me.

Mar 5, 2010 at 11:06 AM

frankly, this is poorly documented (great library though)

here's a full example that works, with hardcoded C: (source of shadow) and M: (target of mount) volumes

IVssImplementation oVSSImpl = VssUtils.LoadImplementation();
            using (IVssBackupComponents oVSS = oVSSImpl.CreateVssBackupComponents())
            {
                oVSS.InitializeForBackup(null);
                oVSS.SetContext(Alphaleonis.Win32.Vss.VssVolumeSnapshotAttributes.Persistent | VssVolumeSnapshotAttributes.NoAutoRelease);
                oVSS.SetBackupState(false, true, VssBackupType.Full, false);

                using (IVssAsync async = oVSS.GatherWriterMetadata())
                {
                    async.Wait();
                }

                Guid gSet = oVSS.StartSnapshotSet();

                Guid gSnapshot = oVSS.AddToSnapshotSet("C:\\", Guid.Empty);

                using (IVssAsync async = oVSS.PrepareForBackup())
                {
                    async.Wait();
                }

                using (IVssAsync async = oVSS.DoSnapshotSet())
                {
                    async.Wait();
                }

                VssSnapshotProperties oProps = oVSS.GetSnapshotProperties(gSnapshot);
                string drive = oVSS.ExposeSnapshot(gSnapshot, null, VssVolumeSnapshotAttributes.ExposedLocally, "M:");
            }

so you should combine the two types (Persistent and NoAutoRelease) in your context to make it persistent (and thus mountable)

------------------------
explanation: 

I found this while testing the shadow & mount operation with vshadow.exe, the utility included in the latest MS VSS SDK 
to make a snapshot mountable, you have to create it with the "-p" (persistent) option 

the utility is provided with its C++ source (thank you MS for going open source ;-); if you look in the vshadow.cpp, you'll find

if (m_bPersistent)
    {
        if (m_bWithWriters) 
            dwContext |= VSS_CTX_APP_ROLLBACK;
        else
            dwContext |= VSS_CTX_NAS_ROLLBACK;
    }

with other words "app_rollback" is indeed the contextvalue to use

to find the value matching of this in the AlphaLeonis library, check the C++ enums

http://msdn.microsoft.com/en-us/library/aa385009(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa385012(VS.85).aspx 

 

  VSS_CTX_APP_ROLLBACK                = ( VSS_VOLSNAP_ATTR_PERSISTENT | VSS_VOLSNAP_ATTR_NO_AUTO_RELEASE ),

now these two have two matching values in the library

 

[Flags]
    public enum VssVolumeSnapshotAttributes
    {
        Persistent = 1,
        NoAutoRecovery = 2,
        ClientAccessible = 4,
        NoAutoRelease = 8,
        NoWriters = 16,
        Transportable = 32,
        NotSurfaced = 64,
        NotTransacted = 128,
        HardwareAssisted = 65536,
        Differential = 131072,
        Plex = 262144,
        Imported = 524288,
        ExposedLocally = 1048576,
        ExposedRemotely = 2097152,
        AutoRecover = 4194304,
        RollbackRecovery = 8388608,
        DelayedPostSnapshot = 16777216,
        TxFRecovery = 33554432,
    }

 

[Flags]
    public enum VssVolumeSnapshotAttributes
    {
        Persistent = 1,
        ...
        NoAutoRelease = 8,
        ...
    }

so you have to combine both with a bitwise "or" (the "|") to have the value matching the "-p" option of the utility

 

 

Mar 20, 2010 at 10:03 AM

also, if you want to remove the exposed snapshot, you have to set  the same context

 

IVssImplementation oVSSImpl = VssUtils.LoadImplementation();
	
              using (IVssBackupComponents oVSS = oVSSImpl.CreateVssBackupComponents())
	
              {
	
                  oVSS.InitializeForBackup(null);
	
                  oVSS.SetContext(Alphaleonis.Win32.Vss.VssVolumeSnapshotAttributes.Persistent | VssVolumeSnapshotAttributes.NoAutoRelease);
	
                  oVSS.DeleteSnapshot(snapshotGuid, true);
	
              }

 

 

May 6, 2010 at 11:00 AM

Hi,

what I did was using the "DefineDOSDevice" function as pInvoke:

 

        [DllImport("kernel32.dll")]
        internal static extern bool DefineDosDevice(uint dwFlags, string lpDeviceName,
        string lpTargetPath);

            string snap_path = vss.GetSnapshotPath(strLocalPath);

            VolumeFunctions.DefineDosDevice(0, @"Z:", snap_path);

It works with Windows XP