0

I have to open the volume with CreateFile from PInvoke:

[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, FileShare dwShareMode, IntPtr securityAttrs, FileMode dwCreationDisposition, FileOptions dwFlagsAndAttributes, IntPtr hTemplateFile);

But when I use it:

var fileName = @"C:\Users\myuser\Desktop\file.txt"
var root = Path.GetPathRoot(fileName);
var volumePath = @"\\.\" + root.Substring(0, root.Length - 1);

var volume = CreateFile(volumePath, GENERIC_READ, FileShare.Read, IntPtr.Zero, FileMode.Open, FileOptions.None, IntPtr.Zero);
if (volume.IsInvalid)
    throw new Win32Exception(Marshal.GetLastWin32Error());

It prints:

Access is denied

However, if I open it with elevated privileges, it prints:

The process cannot access the file because it is being used by another process

I've been trying everything, even picking up code from a lot of places but I can't make it work.

  • 1
    Either that block of code is getting called twice and failing on the second call (which I doubt) or something else is accessing the file already without the share flag set. It is that simple. Wait until you get the error and breakpoint. Open Process Explorer and see who has open handles for the file. – Señor CMasMas May 06 '20 at 15:54
  • https://stackoverflow.com/a/20725652/17034 – Hans Passant May 06 '20 at 16:20
  • Nice! Thanks Mr Passant! – Señor CMasMas May 06 '20 at 17:32

1 Answers1

0

Using the PInvoke code taken from here:

var volume = CreateFile(volumePath, EFileAccess.GenericRead, EFileShare.Read|EFileShare.Write, IntPtr.Zero, ECreationDisposition.OpenExisting, 0, IntPtr.Zero);

I have managed to get it working.

Celal Ergün
  • 955
  • 2
  • 14
  • 30