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 ответа
Есть пара параметров, которые не совсем верны.
- Чтобы открыть том, перед буквой диска необходимо указать
\\.\
, - Вы можете открыть только том с правами на чтение.
Попробуйте этот код:
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))