Не удается получить доступ к разделу NTFS через CreateFile - PullRequest
1 голос
/ 16 декабря 2010

Я пытаюсь добавить функцию сквозного USB-ключа к программному обеспечению, аналогичному по функциональности удаленному рабочему столу. У меня есть следующий код:

public void Open(string path)
{
    System.OperatingSystem ver = System.Environment.OSVersion;
    uint mode;
    uint attr;
    uint share;
    int junk = 0;
    bool success;
    string partitionFileName = @"\\.\" + path;
    uint drvtype;

    // Only determine drvtype if not already defined
    // Default drytype is DRIVE_UNKNOWN
    if (drvtype == Kernel32.DriveType.Unknown)
    {
        drvtype = Kernel32.GetDriveType(path); //0=unknown, 1 = no root drive, 2= removable, 3=fixed, 4=remote, 5=cdrom, 6=ramdisk
    }

    // Set the access modes depending on what we are opening
    if (drvtype == Kernel32.DriveType.CDROM)
    {
        // Depending on the OS version, the flags for opening the cdrom for ioctls are different
        if (ver.Version.Major == 4)    //4 == Windows NT
        {
            mode = Kernel32.GENERIC_READ;
            share = Kernel32.FILE_SHARE_READ;
            attr = Kernel32.FILE_ATTRIBUTE_NORMAL;
        }
        else
        {
            mode = Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE;
            share = Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE;
            attr = Kernel32.FILE_ATTRIBUTE_NORMAL;
        }
    }
    else
    {
        mode = Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE;
        share = Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE;   // exclusive access to device
        attr = Kernel32.FILE_ATTRIBUTE_NORMAL;
    }

    // Try to open the partition as read/write
    hFile = Kernel32.CreateFile(partitionFileName,
                      mode,
                      share,
                      IntPtr.Zero,
                      Kernel32.OPEN_EXISTING,
                      attr,
                      IntPtr.Zero);

    // Lock the volume
    Kernel32.DeviceIoControl(hFile, Kernel32.EIOControlCode.FsctlLockVolume, IntPtr.Zero, 0, IntPtr.Zero, 0, ref junk, IntPtr.Zero);

    // Dismount from the host OS to get around Vista's security
    Kernel32.DeviceIoControl(hFile, Kernel32.EIOControlCode.FsctlDismountVolume, IntPtr.Zero, 0, IntPtr.Zero, 0, ref junk, IntPtr.Zero);

    // Allow extended access to get at boot sectors
    Kernel32.DeviceIoControl(hFile, Kernel32.EIOControlCode.FsctlAllowExtendedDasdIo, IntPtr.Zero, 0, IntPtr.Zero, 0, ref junk, IntPtr.Zero);

    // If it's a USB disk, see if it is write-protected
    if (drvtype == Kernel32.DriveType.Removable)
    {
        // If it is write-protected, tell the user
        success = Kernel32.DeviceIoControl(hFile, Kernel32.EIOControlCode.DiskIsWritable, IntPtr.Zero, 0, IntPtr.Zero, 0, ref junk, IntPtr.Zero);
        if (success)
        {
            bWriteProtect = false;
        }
        else
        {
            if (Kernel32.GetLastError() == 19) //ERROR_WRITE_PROTECT
            {
                bWriteProtect = true;
                showStatus("Unable to open as read/write. File opened as read-only.");
            }
            else
            {
                bWriteProtect = false;
            }
        }
    }
}

Затем я читаю с диска с помощью ReadFile (). Он отлично работает для USB-ключа в формате FAT, я могу читать / писать и даже загружаться с него. Однако по некоторым причинам он не работает с ключами в формате NTFS. Вызов ReadFile () выдает ошибку 21, ERROR_NOT_READY, которую обнаружило некоторое копание, потому что том отключен. Я не могу оставить том подключенным, потому что я обращаюсь (и, возможно, пишу) к загрузочным секторам на диске, и, насколько я понимаю, Vista / 7 не позволит вам сделать это без предварительного отключения диска.

Существуют ли какие-либо другие вызовы DeviceIoControl, которые я должен делать для NTFS, которые мне не хватает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...