Как сделать так, чтобы запоминающее устройство читало только Windows из прошивки - PullRequest
2 голосов
/ 19 марта 2020

Я работаю с прошивкой для оборудования с интерфейсом USB. Когда устройство подключено к USB-порту, оно перечисляет 2 класса: CD C & MS C.

Для части MS C устройство настраивается пользователем таким образом, что устройство может быть защищено от записи. Таким образом, пользователь может выбрать, будет ли устройство доступно только для чтения или имеет возможность чтения-записи.

Я использую предварительно написанную USB-библиотеку, которая может перечислять устройство с 2 интерфейсами. Часть, с которой я борюсь, это как я могу позволить своей прошивке работать так, как будто устройство доступно только для чтения.

Микроконтроллер относится к серии STM32L4. Большая часть кода генерируется из программного обеспечения STM32CubeMX.

После некоторого исследования я выяснил, что SCSI Write10 вместе с командами SCSI Request Sense может проверить, защищена ли MS C от записи. Текущая реализация выглядит следующим образом:

static int8_t SCSI_Write10 (USBD_HandleTypeDef  *pdev, uint8_t lun , uint8_t *params)
{
  USBD_CDC_MSC_HandleTypeDef  *hmsc = pdev->pClassData;
  uint32_t len;

  if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
  {
    /* case 8 : Hi <> Do */
    if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U)
    {
      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
      return -1;
    }

    /* Check whether Media is ready */
    if(((USBD_CDC_StorageItfTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )
    {
      SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
      return -1;
    }

    /* Check If media is write-protected */
    if(((USBD_CDC_StorageItfTypeDef *)pdev->pUserData)->IsWriteProtected(lun) !=0 )
    {
      SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
      return -1;
    }

    // Other code
}

Я отладил и проверил, что IsWriteProtected() правильно возвращает ненулевое значение, когда устройство настроено как защищенное от записи. SCSI_SenseCode() выдвигает код ошибки в круговом списке. Windows должен отправить команду Request Sense SCSI для получения кода ошибки, но я проверил с точкой останова, что Windows никогда не отправлял эту команду!

int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
{
  switch (cmd[0])
  {
  case SCSI_TEST_UNIT_READY:
    SCSI_TestUnitReady(pdev, lun, cmd);
    break;

  case SCSI_REQUEST_SENSE:
    SCSI_RequestSense (pdev, lun, cmd);       // <<-- This is never reached
    break;
  case SCSI_INQUIRY:
    SCSI_Inquiry(pdev, lun, cmd);
    break;
    ....

Если я настраиваю устройство в режиме записи - В порядке защиты перечисление дисков в P C занимает очень много времени, а File Explorer очень долго занят. После перечисления я могу открыть дисковод и, если я попытаюсь выполнить запись на диск, Windows сообщит, что произошел дисковый ввод-вывод, и запись не удалась. Я ожидал, что Windows сообщит мне, что диск доступен только для чтения.

Если я настрою устройство с разрешением записи, то перечисление диска займет обычное время, как если бы я подключил обычное перо диск.

  1. Почему Windows никогда не отправлял команду SCSI Request Sense?
  2. Почему перечисление диска занимает очень много времени, когда возвращается -1 из-за защиты от записи из команды Write10? Мне нужен диск для быстрого перечисления с защитой от записи или без нее.
...