Как я могу читать и записывать необработанные данные на USB-накопитель, используя C в Windows

Поэтому я создал свою собственную схему шифрования и придумал, что у меня может быть USB-накопитель с необработанными данными (вообще без файловой системы), который я могу использовать в качестве «ключа» в моей схеме шифрования.

Мне нужен способ чтения и записи данных прямо на USB, я пробовал использовать libusb, но не смог понять (слишком низкоуровневый для меня).

Я также видел, что есть способ открыть дескриптор USB-накопителя с помощью функции CreateFile в Windows, но я не смог определить необходимые параметры и получил ERROR_INVALID_PARAMETER при попытке чтения.

Я понимаю, что ОС будет думать, что диск / его файловая система повреждены (поскольку у нее ее не будет), но это не имеет значения, мне просто нужен способ хранения необработанных данных.

Любая помощь приветствуется, спасибо!

пожалуйста, покажите свой код, где вы пытаетесь открыть том.

vlad_tepesch 11.06.2019 17:11
Стоит ли изучать 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
1
1 257
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Проблема с вашим подходом в том, что Windows всегда спрашивает, следует ли отформатировать диск. И очень может быть, что в тот или иной день на вопрос ответят неправильно ;)

Однако вы можете открыть том, если знаете правильное имя, которое Windows использует для него внутри. Вы можете получить Sysinternals WinObj, который может показать вам все имена. Для дисков Windows также создает символические ссылки, такие как \\.\C:, чтобы получить к ним доступ через букву диска. Убедитесь, что в вашем коде правильно экранированы обратные косые черты (обычно "\\\\.\\C:") и что после двоеточия нет завершающей косой черты.

Но мне нравится указывать вам на документацию CreateFile, особенно на раздел примечаний (https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-createfilea#remarks):

Возможно, вы упустили один из следующих пунктов:

The following requirements must be met for such a call to succeed:

  • The caller must have administrative privileges. For more information, see Running with Special Privileges.
  • The dwCreationDisposition parameter must have the OPEN_EXISTING flag.
  • When opening a volume or floppy disk, the dwShareMode parameter must have the FILE_SHARE_WRITE flag.

Как указал Эриксун: для диска, который сам сообщается как съемный, права администратора не требуются.

Пример открытия USB-накопителя с буквой «D»;

HANDLE h = CreateFile("\\\\.\\D:", (GENERIC_READ | GENERIC_WRITE), FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

if (h != INVALID_HANDLE_VALUE) {
  unsigned char buffer[512];
  DWORD readBytes = 0;
  ReadFile(h, buffer, sizeof(buffer), &readBytes, NULL);
  /* .. */
  CloseHandle(h);
}

Также обратите внимание, что согласно цитатам в https://stackoverflow.com/a/31712818/2331592 блоки данных для чтения/записи должны быть выровнены по секторам.
Поэтому, чтобы быть в безопасности, сначала определите размер сектора (например, с помощью GetDiskFreeSpace)

В этом случае область действия ограничена съемным диском. По умолчанию, начиная с Vista, локальные интерактивные пользователи (т. е. пользовательские токены, содержащие SID S-1-5-4) имеют доступ для чтения и записи к съемным устройствам хранения (см. ACL и стек устройств). Это можно заблокировать с помощью групповой политики «Доступ к съемным носителям». Обратите внимание, что запрет на чтение, запись или выполнение для интерактивных пользователей будет распространяться и на интерактивных администраторов. Только неинтерактивные пользователи (например, сервисы) не будут затронуты.

Eryk Sun 11.06.2019 17:35

Кроме того, мы можем получить доступ к тому через классическую точку монтирования с буквой диска, например. "//./Э:". Нам не нужно использовать имя внутреннего тома. Тому будет присвоена буква диска, даже если он не имеет распознанной файловой системы. Графический интерфейс также может автоматизировать список с помощью FindFirstVolumeW и т. д. Без распознанной файловой системы том монтируется «файловой системой» RAW, которая просто обеспечивает низкоуровневый доступ для чтения и записи, фактически просто перенаправляя эти запросы на базовое дисковое устройство.

Eryk Sun 11.06.2019 17:39

@eryksun спасибо, я учел ваши замечания и изменил свой ответ

vlad_tepesch 12.06.2019 09:52

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

user7263832 13.06.2019 15:41

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