CreateFile в Kernel32.dll возвращает неверный дескриптор

Я пытаюсь создать безопасный дескриптор файла для "C:", используя метод CreateFile kernel32.dll, который всегда возвращает мне неправильный дескриптор.

Любая помощь о том, что я делаю не так здесь?"C:

CreateFile(
    lpFileName: "C:",
    dwDesiredAccess: FileAccess.ReadWrite,
    dwShareMode: FileShare.ReadWrite,
    lpSecurityAttributes: IntPtr.Zero,
    dwCreationDisposition: FileMode.OpenOrCreate,
    dwFlagsAndAttributes: FileAttributes.Normal,
    hTemplateFile: IntPtr.Zero);

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern SafeFileHandle CreateFile(
    string lpFileName,
    [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
    [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
    IntPtr lpSecurityAttributes,
    [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition,
    [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes,
    IntPtr hTemplateFile);

2 ответа

Решение

Есть пара параметров, которые не совсем верны.

  1. Чтобы открыть том, перед буквой диска необходимо указать \\.\,
  2. Вы можете открыть только том с правами на чтение.

Попробуйте этот код:

SafeFileHandle handle = CreateFile(
    lpFileName: @"\\.\C:",
    dwDesiredAccess: FileAccess.Read,
    dwShareMode: FileShare.ReadWrite,
    lpSecurityAttributes: IntPtr.Zero,
    dwCreationDisposition: FileMode.OpenOrCreate,
    dwFlagsAndAttributes: FileAttributes.Normal,
    hTemplateFile: IntPtr.Zero );

Обратите внимание, что для открытия дескриптора тома с правами чтения вы должны работать от имени администратора, в противном случае вам будет отказано в доступе (код ошибки 5). Как указывает Nik Bougalis и документация CreateFile, если вы укажете dwDesiredAccess как 0 права администратора не требуются.

Если этот параметр равен нулю, приложение может запрашивать определенные метаданные, например атрибуты файла, каталога или устройства, не обращаясь к этому файлу или устройству, даже если в доступе GENERIC_READ было бы отказано.

Вот так я решил проблему

    private const int GENERIC_READ = unchecked((int)0x80000000);
    private const int FILE_SHARE_READ = 1;
    private const int FILE_SHARE_WRITE = 2;
    private const int OPEN_EXISTING = 3;
    private const int IOCTL_DISK_GET_DRIVE_LAYOUT_EX = unchecked((int)0x00070050);
    private const int ERROR_INSUFFICIENT_BUFFER = 122;
    NativeMethods.CreateFile("\\\\.\\PHYSICALDRIVE" + PhysicalDrive, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero))
Другие вопросы по тегам