alphaleonis / AlphaFS

AlphaFS is a .NET library providing more complete Win32 file system functionality to the .NET platform than the standard System.IO classes.
http://alphafs.alphaleonis.com/
MIT License
562 stars 99 forks source link

Methods Directory/File.Copy throw DeviceNotReadyException when using GLOBALROOT source path. #456

Closed VladimirK69 closed 6 years ago

VladimirK69 commented 6 years ago

I'm trying to copy files from SQL Server data folder into another folder where I can work with them by using Shadowcopy (AlphaVSS). I made simple project by example from VSS ` string source_file = @"c:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014\MSSQL\ALLTYPES_log.ldf"; string backup_root = @"D:\Backups"; string backup_path = Path.Combine(backup_root, Path.GetFileName(source_file));

  // Initialize the shadow copy subsystem.
  using (VssBackup vss = new VssBackup())
  {
     vss.Setup(Path.GetPathRoot(source_file));
     string snap_path = vss.GetSnapshotPath(source_file);

     // Here we use the AlphaFS library to make the copy.
     Alphaleonis.Win32.Filesystem.File.Copy(snap_path, backup_path);
  }

First error was with '?' in snap_path "\\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy9\\Program Files\\Microsoft SQL Server\\MSSQL12.MSSQL2014\\MSSQL\\ALLTYPES_log.ldf", but I disabled that in Path.Helpers.cs with switch (num) { case 34: // " (quote) case 60: // < (less than) case 62: // > (greater than) case 124: // | (pipe) throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.Illegal_Characters_In_Path, (char) num), "path");

           default:
              // 32: space
              if (num >= 32) // && (!checkAdditional || num != WildcardQuestionChar && num != WildcardStarMatchAllChar))
                 continue;

              goto case 34;
        }

` Now I have "Alphaleonis.Win32.Filesystem.DeviceNotReadyException: '(21) The device is not ready: [GLOBALROOT]'" in Alphaleonis.Win32.Filesystem.File.Copy(snap_path, backup_path) but it suppose to be fixed in 2.2.1. I downloaded today AlphaFS-develop, tried 2.2.2 but still have error. Am I doing something wrong or error in AlphaFS?

Yomodo commented 6 years ago

You're not doing anything wrong, it is a new bug related to GLOBALROOT.

VladimirK69 commented 6 years ago

You asked me to confirm "Could you verify that delayUntilReboot is false?" - it is false in File.Copy.cs 761. But I guess you already reproduced.

Yomodo commented 6 years ago

Yeah, sorry about that, post that message while debugging when I did not mean to. :) The exception also applies when using Directory.Copy, so a fix is on its way.

Yomodo commented 6 years ago

Could you try branch #456 so see if the issue is resolved?

VladimirK69 commented 6 years ago

It solved GLOBALROOT issue, but now I have "System.IO.FileNotFoundException: '\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014\MSSQL\ALLTYPES_log.ldf'" at Directory.ExistsDrive.cs line 94. And this is snap_path returned by string snap_path = vss.GetSnapshotPath(source_file); ""\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy4\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014\MSSQL\ALLTYPES_log.ldf"". How to check that VSS really created snapshot and it is where path points?

Yomodo commented 6 years ago

https://github.com/alphaleonis/AlphaFS/blob/9ea257d054d6d13aaf6f1801f6514a1e9700b3fe/AlphaFS.UnitTest/File%20Class/File.Copy/AlphaFS_File.Copy_ExistingFile_UsingGlobalRootAsSourcePath.cs#L65-L70

You should be able to use AlphaFS methods Directory/File.Exists to check if it exists.

VladimirK69 commented 6 years ago

I'm bit confused. Code at the start of topic from VSS 1.40 src\Samples\VssBackup, Snapshot.cs and VssBackup.cs used. Snapshot created before Alphaleonis.Win32.Filesystem.File.Copy(snap_path, backup_path); and I can see it with NirSoft ShadowCopyView https://www.nirsoft.net/utils/shadow_copy_view.html For example snap_path

"\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy6\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014\MSSQL\ALLTYPES_log.ldf"

and I can see

"\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy6"

in that tool, can copy file from snapshot

"c:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014\MSSQL\ALLTYPES_log.ldf" to "d:\Backups"

with that tool, but AlphaFS fails with "System.IO.FileNotFoundException:

'\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy6\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014\MSSQL\ALLTYPES_log.ldf'"

I'm not familiar with Shadowcopy service, but if I understand it right VSS creates snapshot "HarddiskVolumeShadowCopy6" and through that snapshot AlphaFS going to copy file? Is that correct? Is it AlphaFS fails or is there already suppose to be file "ALLTYPES_log.ldf" in "HarddiskVolumeShadowCopy6" before AlphaFS will be able to copy it?

Yomodo commented 6 years ago

Yes, AlphaFS expects the directory/file to exist in HarddiskVolumeShadowCopy6.

VladimirK69 commented 6 years ago

Last issue was on my side: "DATA" folder missing from source path. After changing to openFileDialog with "ValidateNames=false" to get file path everything works (I checked path side by side to figure).

Thanks for help and amazing work. It saved me from making the same through kernel mode drivers.

Yomodo commented 6 years ago

Glad to hear! Thanks for the bug.