На этот вопрос StackOverflow есть ответ, требующий блокировки/отключения тома, но, похоже, это не обязательно. Когда я использую шестнадцатеричный редактор HxD (Tools
> Open disk
), чтобы открыть том (логические диски) или физический диск, я могу открыть C:
и даже SSD, на котором он находится. Я могу без проблем продолжать использовать диск C, а HxD обновляет его содержимое.
Кроме того, когда я использую MSVC с помощью fopen("\\\\.\\D:", "rb")
и fgetc()
, я могу прочитать первый байт необработанного диска/тома D:
. Это также происходит с MinGW, который, я думаю, связан с библиотекой MSVC.
Итак, как я могу это сделать с помощью Win32 API? Или MSVC делает зловещие вещи, которые обычно не выполняются Win32 API?
@Torreto-MSFT DefineDosDevice
здесь вообще не нужен
MSVC делает ))) msvc вообще ничего не делает. это забавно. это просто интегрированная оболочка для компиляции, компоновки и отладки.
могу ли я сделать это с помощью Win32 API? в чем проблема создать файл через CreateFileW
или NtOpenFile
и прочитать его?
Вы можете заглянуть в HxD (мой любимый инструмент в Windows) с помощью такого инструмента, как depends
(dependentwalker.com) и посмотреть, какой API они импортируют. Утилита testrec довольно мощная, низкоуровневая и с открытым исходным кодом. Возможно, вы найдете в нем то, что ищете.
@RbMm, я попробовал CreateFile("\\\\.\\D:", ...)
и ReadFile()
, но он пожаловался: «Параметр недействителен». Я был действительно уверен, что с MinGW и MSVC все получится.
Как можно сказать, какой параметр неверен, если вы не показываете свой фактический код. И, конечно же, mingw или msvc здесь вообще не имеют никакого отношения.
@RbMm, я пробовал это. Вывод был: «Чтение: параметр неверен». Кроме того, я упомянул MinGW, потому что, когда я скомпилировал его и проверил выходной .exe (с помощью dumpbin
), он использовал msvcrt.dll
для таких функций, как fopen()
. Но это не имеет отношения к вопросу.
конечно параметр неправильный, потому что вы используете FILE_FLAG_NO_BUFFERING
. в этом случае размер и смещение данных должны быть кратными размеру сектора. и вы попробуйте прочитать 2 байта. и уже в 3 раз повторяю - mingw, msvc и т.д - здесь не связаны и не могут быть связаны
@RbMm, после того, как я заменил FILE_FLAG_NO_BUFFERING
на 0
, ошибка все равно возвращалась, но! Затем я изменил количество читаемых байтов на 512
, и это сработало! Это немного странно. Большое спасибо за эту информацию! -- Ты какой-то волшебник! Есть ли у вас какая-либо документация или что-то в этом роде, чтобы я мог посмотреть дальше?
Для дисковых устройств всегда неявно устанавливается отсутствие буферизации. Таким образом, вам действительно всегда нужен несколько размеров и смещений секторов. Также требуется выравнивание буфера по устройству, но обычно это не более 4 байт.
@Schilive Вот документ, который вам нужен: Learn.microsoft.com/en-us/windows/win32/fileio/…
@RbMm, спасибо. Я думаю, вы могли бы ответить с помощью комментариев.
@Schilive Я могу создать сообщество для мистера Рбмм. Просто примите это, и это не добавит мне репутации.
@Torreto-MSFT, большое спасибо. Я немного отредактировал. Как вы думаете, это все еще хорошо?
@Schiliv Отлично.
Как сказал @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;
}
Попробуйте использовать
DefineDosDevice
. Он может сопоставить физическое устройство с логическим устройством. DosDevice — это символические ссылки в базе данных диспетчера объектов NT, указывающие на базовые устройства. Затем используйте createfile для доступа к диску.