CreateFile: прямая операция записи на сырой диск "Доступ запрещен" - Vista, Win7 - PullRequest
15 голосов
/ 01 января 2012

Соответствующий документ Microsoft: Блокирование операций прямой записи на тома и диски CreateFile, замечания по физическим дискам и томам

Исполняемый файл написан на C ++ и вызывает CreateFile(), чтобы открыть карту SD, на которой нет файловой системы .CreateFile() и последовательные ReadFile() вызовы успешны для GENERIC_READ без прав администратора.

CreateFile не удается для GENERIC_WRITE даже с привилегиями администратора.В проводнике я установил Запуск от имени администратора в Свойства> Совместимость> Уровень привилегий.Я также попытался запустить исполняемый файл из cmd администратора (началось с Ctrl + Shift + Enter, «Administrator:» в заголовке окна, должным образом повышен).Тем не менее, я получаю ERROR_ACCESS_DENIED (0x5).

Должен ли я передать что-то еще CreateFile? Понятия не имею, что такое атрибуты безопасности, я просто передаю NULL, соответствующий код здесь в строке 92 и здесь в строке 48.

Или есть что-то еще, что должно быть настроено для запуска процесса с правами администратора?Связанные вопросы:

Могу ли я получить доступ на запись в секторы сырых дисков под Vista и Windows 7 в режиме пользователя? Доступ к необработанным разделам в Windows Vista Как получить прямой доступ к необработанным данным HD в C? Есть ли чистый способ получить эксклюзивный доступ к физическому разделу под Windows?

Ответы [ 4 ]

15 голосов
/ 10 января 2012

Хотя ответ @MSalters имеет смысл, это не то, как работает мой код.На самом деле это настолько нелогично, что я потратил несколько дней, чтобы убедиться, что код на самом деле работает.

Эти фрагменты кода находятся в проверенном программном продукте массового рынка.Когда ему нужно изменить структуру на диске, он отключает том win32, чтобы он мог изменять структуры файловой системы NTFS или FAT.Интересно, что дескриптор доступа к тому доступен только для чтения:

    char    fn [30];
    snprintf (fn, sizeof fn, "\\\\.\\%s:", vol -> GetVolName ());

    vol_handle = CreateFile (fn, GENERIC_READ,
                            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS,
                            NULL);

    if (vol_handle == INVALID_HANDLE_VALUE)
    {
          // show error message and exit
    }

Если не удается получить доступ на запись к тому или разделу, этот код принудительно отключается, если пользователь разрешает такое после строгого предупреждения:

if (!DeviceIoControl (vol_handle, FSCTL_DISMOUNT_VOLUME,
                                            NULL, 0, NULL, 0, &status, NULL))
{
    DWORD err = GetLastError ();
    errormsg ("Error %d attempting to dismount volume: %s",
                                                        err, w32errtxt (err));
}

// lock volume
if (!DeviceIoControl (vol_handle, FSCTL_LOCK_VOLUME,
                                            NULL, 0, NULL, 0, &status, NULL))
{
     // error handling; not sure if retrying is useful
}

Запись тогда довольно проста, за исключением позиционирования указателя файла по 512-байтному сектору:

    long    hipart = sect >> (32-9);
    long    lopart = sect << 9;
    long    err;

    SetLastError (0);       // needed before SetFilePointer post err detection
    lopart = SetFilePointer (vol_handle, lopart, &hipart, FILE_BEGIN);

    if (lopart == -1  &&  NO_ERROR != (err = GetLastError ()))
    {
            errormsg ("HWWrite: error %d seeking drive %x sector %ld:  %s",
                            err, drive, sect, w32errtxt (err));
            return false;
    }

    DWORD   n;

    if (!WriteFile (vol_handle, buf, num_sects*512, &n, NULL))
    {
            err = GetLastError ();
            errormsg ("WriteFile: error %d writing drive %x sectors %lu..%lu:  %s",
                            err, drv, sect, sect + num_sects - 1,
                            w32errtxt (err));
            return false;
    }
13 голосов
/ 05 января 2012

Редко хотеть только GENERIC_WRITE.Скорее всего, вы хотите GENERIC_READ|GENERIC_WRITE.

1 голос
/ 02 января 2012

В документации MSDN есть примечание в документации CreateFile:

Прямой доступ к диску или тому ограничен. Дополнительные сведения см. В разделе «Изменения в файловой системе и в стеке хранения для ограничения прямого доступа к диску и прямого доступа к томам в Windows Vista и Windows Server 2008» в базе знаний справки и поддержки по адресу http://support.microsoft.com/kb/942448. * 1005. *

Это относится к Vista / 2008, но может быть применимо и к Win7.

0 голосов
/ 04 января 2012

У меня была похожая проблема при переносе кода с x86 на x64.Вы упоминаете, что передаете null для вашего параметра SECURITY_ATTRIBUTES;Я получал ошибки отказа в доступе сам, используя этот подход, пока я фактически не начал создавать / передавать этот параметр.

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