Как прочитать необработанный диск без блокировки/размонтирования тома, используя Win32 API?

На этот вопрос StackOverflow есть ответ, требующий блокировки/отключения тома, но, похоже, это не обязательно. Когда я использую шестнадцатеричный редактор HxD (Tools > Open disk), чтобы открыть том (логические диски) или физический диск, я могу открыть C: и даже SSD, на котором он находится. Я могу без проблем продолжать использовать диск C, а HxD обновляет его содержимое.

Кроме того, когда я использую MSVC с помощью fopen("\\\\.\\D:", "rb") и fgetc(), я могу прочитать первый байт необработанного диска/тома D:. Это также происходит с MinGW, который, я думаю, связан с библиотекой MSVC.

Итак, как я могу это сделать с помощью Win32 API? Или MSVC делает зловещие вещи, которые обычно не выполняются Win32 API?

Попробуйте использовать DefineDosDevice. Он может сопоставить физическое устройство с логическим устройством. DosDevice — это символические ссылки в базе данных диспетчера объектов NT, указывающие на базовые устройства. Затем используйте createfile для доступа к диску.

Torrecto - MSFT 04.07.2024 10:43

@Torreto-MSFT DefineDosDevice здесь вообще не нужен

RbMm 04.07.2024 11:00

MSVC делает ))) msvc вообще ничего не делает. это забавно. это просто интегрированная оболочка для компиляции, компоновки и отладки.

RbMm 04.07.2024 11:02

могу ли я сделать это с помощью Win32 API? в чем проблема создать файл через CreateFileW или NtOpenFile и прочитать его?

RbMm 04.07.2024 11:04

Вы можете заглянуть в HxD (мой любимый инструмент в Windows) с помощью такого инструмента, как depends (dependentwalker.com) и посмотреть, какой API они импортируют. Утилита testrec довольно мощная, низкоуровневая и с открытым исходным кодом. Возможно, вы найдете в нем то, что ищете.

ixe013 04.07.2024 16:10

@RbMm, я попробовал CreateFile("\\\\.\\D:", ...) и ReadFile(), но он пожаловался: «Параметр недействителен». Я был действительно уверен, что с MinGW и MSVC все получится.

Schilive 05.07.2024 02:49

Как можно сказать, какой параметр неверен, если вы не показываете свой фактический код. И, конечно же, mingw или msvc здесь вообще не имеют никакого отношения.

RbMm 05.07.2024 06:08

@RbMm, я пробовал это. Вывод был: «Чтение: параметр неверен». Кроме того, я упомянул MinGW, потому что, когда я скомпилировал его и проверил выходной .exe (с помощью dumpbin), он использовал msvcrt.dll для таких функций, как fopen(). Но это не имеет отношения к вопросу.

Schilive 05.07.2024 06:52

конечно параметр неправильный, потому что вы используете FILE_FLAG_NO_BUFFERING. в этом случае размер и смещение данных должны быть кратными размеру сектора. и вы попробуйте прочитать 2 байта. и уже в 3 раз повторяю - mingw, msvc и т.д - здесь не связаны и не могут быть связаны

RbMm 05.07.2024 08:34

@RbMm, после того, как я заменил FILE_FLAG_NO_BUFFERING на 0, ошибка все равно возвращалась, но! Затем я изменил количество читаемых байтов на 512, и это сработало! Это немного странно. Большое спасибо за эту информацию! -- Ты какой-то волшебник! Есть ли у вас какая-либо документация или что-то в этом роде, чтобы я мог посмотреть дальше?

Schilive 05.07.2024 09:10

Для дисковых устройств всегда неявно устанавливается отсутствие буферизации. Таким образом, вам действительно всегда нужен несколько размеров и смещений секторов. Также требуется выравнивание буфера по устройству, но обычно это не более 4 байт.

RbMm 05.07.2024 10:00

@Schilive Вот документ, который вам нужен: Learn.microsoft.com/en-us/windows/win32/fileio/…

Torrecto - MSFT 05.07.2024 11:29

@RbMm, спасибо. Я думаю, вы могли бы ответить с помощью комментариев.

Schilive 05.07.2024 18:53

@Schilive Я могу создать сообщество для мистера Рбмм. Просто примите это, и это не добавит мне репутации.

Torrecto - MSFT 09.07.2024 03:31

@Torreto-MSFT, большое спасибо. Я немного отредактировал. Как вы думаете, это все еще хорошо?

Schilive 09.07.2024 21:09

@Schiliv Отлично.

Torrecto - MSFT 10.07.2024 03:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
16
98
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как сказал @RbMm, CreateFile("\\\\.\\D:", ...) может сделать так же, как fopen("\\\\.\\D:", "rb"). Это не имеет ничего общего с MinGW и MSVC.

При использовании флага FILE_FLAG_NO_BUFFERING, который является неявным для устройств, размер и смещение данных должны быть кратны размеру сектора. Например,

#include <windows.h>
#include <stdio.h>

#define SECTOR_SIZE 512

int main()
{
        HANDLE hFile;
        unsigned char buf[SECTOR_SIZE];
        DWORD rd;
        hFile = CreateFile(
                "\\\\.\\D:", 
                /* "GENERIC_WRITE" for writing access. */
                GENERIC_READ,
                /* Necessary to allow other programs to read and write to the
                 * device.
                 */
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                NULL
        );
        if (hFile == INVALID_HANDLE_VALUE) {
                fprintf(stderr, "Cuuld not open file: %lu\n", GetLastError());
                return 1;
        }

        if (ReadFile(hFile, buf, SECTOR_SIZE, &rd, NULL) == FALSE) {
                fprintf(stderr, "Could not read file: %lu\n", GetLastError());
                CloseHandle(hFile);
                return 1;
        }
        for (size_t i = 0; i < SECTOR_SIZE; i++)
                printf("%X ", buf[i]);

        CloseHandle(hFile);
        return 0;
}

Другие вопросы по теме

Похожие вопросы

Информация о растровом изображении регулярно возвращает серию одних и тех же неправильных значений, прежде чем возвращать правильные цвета пикселей
Запуск приложения с правами обычного пользователя из экземпляра с правами администратора
Как сохранить вывод сценария Python в действиях GitHub, запущенных в последней версии Windows?
Как перечислить потоки с помощью типов CreateToolhelp32Snapshot и Python?
Как связать приложения Rusqlite с пользовательскими сборками SQLite в Windows?
Какой API возвращает сообщение для NTSTATUS?
«Запуск с PowerShell» выдает ошибку политики выполнения, но запуск непосредственно в окне PowerShell не дает
Могу ли я держать ручку открытой в течение всего срока службы программы?
Регулярное выражение в findstr для поиска URL-адресов в текстовых файлах во всех подпапках
Проблема при добавлении зависимостей в pyinstaller с использованием поэзии для управления зависимостями