views:

299

answers:

3

I trying to open C: directly with FileStream without success:

new FileStream("C:", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

System.UnauthorizedAccessException was unhandled

Message="Access to the path 'C:\' is denied."

Source="mscorlib"

StackTrace:

  in  System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)

  in  System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)

  in  System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)

  in  System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)

  in  ReadingMftNewTest.Program.Main(String[] args) in D:\CS\2008\ReadingMftNewTest\ReadingMftNewTest\Program.cs:line 76

Note that i openning "C:" but the error says "C:\", where did this slash came from? :\

Is there any chance to open C: without using the CreateFile API?

I really don't want be depending on WIN32 API because this code should also run on Mono that dont support WIN32 API, but successfully openning devices with regular FileStream (Mono 1 Microsoft 0).

+1  A: 

When you reference a root drive without the \ in the name you are using what amounts to an alias in the file system. It maps to the last working directory used under that root drive. It's the equivalent of typing d: or c: into a cmd window. It moves you to the appropriate root drive under the last directory.

In this case the last path used on the c: drive was c:\. So when opening c: you end up opening c:\.

There is no way to avoid this "aliasing" using the FileStream API that I know of. All of the FileStream APIs will eventually map the path given with Path.NormalizePath before calling CreateFile. This is the function which does the mapping.

JaredPar
+1  A: 

Opening the drive requires the drive name, like "\\.\PhysicalDrive0". Finding the drive name requires QueryDosDevice(). The odds that Windows will allow this are fairly minimal.

Hans Passant
"\\.\PhysicalDrive0" will open the whole hard drive, while "\\.\C:" open specific partition.
DxCK
A: 

I finally found a way to do this:

new FileStream(@"C:\$Volume", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

This works only on NTFS volumes.

DxCK