Аппаратное обеспечение персонального компьютера© Александр Фролов, Григорий ФроловТом 33, М.: Диалог-МИФИ, 1997, 304 стр. Команды драйвера CD-ROMВ этом разделе мы расскажем о командах драйвера CD-ROM. Заметим, что в рамках одной команды может выполняться несколько функций. Код функции при этом записывается в расширение загловка запроса. ИнициализацияКоманда инициализации вызывается из MS-DOS только один раз. Ниже мы привели формат заголовка запроса для этой команды: // --------------- // Код команды 0 // --------------- #pragma pack(1) typedef struct _Init { ReqHdr rh; BYTE bNumberOfUnits; DWORD lpEndAddress; DWORD lpAddressOfBPB; BYTE bNumberOfBlockDevice; } Init; После выполнения команды поля структуры заполняются драйвером следующим образом:
Чтение IOCTL InputПри помощи команды IOCTL Input программа может получить от драйвера самую разную информацию, начиная от адреса заголовка драйвера и заканчивая информацией о дорожках диска. Формат заголовка запроса: // --------------- // Код команды 3 // --------------- #pragma pack(1) typedef struct _IOCTL_Input { ReqHdr rh; BYTE bMediaDescriptor; DWORD lpTransferAddress; WORD wDataSize; WORD wStartSector; DWORD lpVolID; } IOCTL_Input; Заполнение полей заголовка запроса:
Команда IOCTL Input может выполнять много функций. Перед вызовом драйвера вы должны подготовить заголовок функции, указав в одном из его полей код выполняемой функции. Адрес и размер этой структуры необходимо записать в поля lpTransferAddress и wDataSize, соответственно. Рассмотрим форматы заголовков различных функций, выполняемых в рамках команды IOCTL Input. Определение адреса заголовка драйвера CD-ROM// --------------- // Код функции 0 // --------------- #pragma pack(1) typedef struct _RAddr { BYTE bFunctionCode; DWORD lpDeviceHeader; } RAddr;
Зная адрес заголовка драйвера, вы можете определить имя драйвера и его атрибуты. Подробности об атрибутах драйверов вы найдете в 18 томе «Библиотеки системного програмиста». Определение положения головки// --------------- // Код функции 1 // --------------- #pragma pack(1) typedef struct _HeadLocation { BYTE bFunctionCode; BYTE bAddressMode; DWORD lpHeadLocation; } HeadLocation;
Здесь необходимо сделать замечание относительно режимов адресации. По умолчанию устройство чтения CD-ROM находится в режиме адресации HSG, описанный в стандарте High Sierra. При этом в качестве адреса указывается логический номер блока. Другой режим адресации описан в стандарте Redbook. В нем адрес представляет собой набор из трех значений: минуты (MIN), секунды (SEC), фреймы (FRAME). Каждое значение занимает один байт, причем в младшем байте хранится значение FRAME, в следующем байте - значение SEC, и в последнем, третьем байте, - значение MIN. С помощью следующей формулы вы можете преобразовать адрес из формата Redbook в формат HSG: SECTOR = MIN * 60 * 75 + SEC * 75 + FRAME - 150 Получение информации о звуковых каналах// --------------- // Код функции 4 // --------------- #pragma pack(1) typedef struct _ChanInfo { BYTE bFunctionCode; BYTE bInpChannel0; BYTE bVolControl0; BYTE bInpChannel1; BYTE bVolControl1; BYTE bInpChannel2; BYTE bVolControl2; BYTE bInpChannel3; BYTE bVolControl3; } ChanInfo;
Чтение данных из устройства// --------------- // Код функции 5 // --------------- #pragma pack(1) typedef struct _DriveBytes { BYTE bFunctionCode; BYTE bNumBytes; BYTE bReadBuff[128]; } DriveBytes;
Определение состояния устройства// --------------- // Код функции 6 // --------------- #pragma pack(1) typedef struct _DeviceStatus { BYTE bFunctionCode; DWORD dwDeviceParameters; } DeviceStatus;
Описания отдельных бит слова состояния приведено ниже:
Немного о режимах Cooked и Raw. По умолчанию устройство чтения CD-ROM работает в режиме Cooked. Этот режим предполагает аппаратную обработку циклической контрольной суммы. Размер блока данных равен 2048 байт. В режиме Raw драйвер возвращает 2352 байта данных, в которые входят заголовок блока данных и контрольная сумма. Определение размера сектора// --------------- // Код функции 7 // --------------- #pragma pack(1) typedef struct _SectorSize { BYTE bFunctionCode; BYTE bReadMode; DWORD dwSectorSize; } SectorSize;
Определение размера тома// --------------- // Код функции 8 // --------------- #pragma pack(1) typedef struct _VolumeSize { BYTE bFunctionCode; DWORD dwVolumeSize; } VolumeSize;
Функция возвращает адрес дорожки Lead-out, преобразованное в численное значение по следующей формуле: frame + (sec * 75) + (min * 60 * 75) Это значение является адресом первого сектора, который располагается за самым последним адресуемым сектором диска. Проверка замены носителя данных// --------------- // Код функции 9 // --------------- #pragma pack(1) typedef struct _MediaChange { BYTE bFunctionCode; BYTE bMedia; } MediaChange;
Получение информации о компакт-диске// --------------- // Код функции 10 // --------------- #pragma pack(1) typedef struct _DiskInfo { BYTE bFunctionCode; BYTE bLowest; BYTE bHighest; DWORD dwTotal; } DiskInfo;
Получение информации о дорожке компакт-диска// --------------- // Код функции 11 // --------------- #pragma pack(1) typedef struct _TrackInfo { BYTE bFunctionCode; BYTE bTrack; DWORD dwLoc; BYTE bInfo; } TrackInfo;
Старшая тетрада формата дорожки имеет следующий формат:
Состояние бита, отмеченного символом *, значения не имеет. Младшая тетрада формата дорожки содержит тип режима ADR, описанного в Redbook. Получение информации о канале Q// --------------- // Код функции 12 // --------------- #pragma pack(1) typedef struct _QInfo { BYTE bFunctionCode; BYTE bCtrlAndARD; BYTE bTrackNumb; BYTE bIndex; BYTE bMin; BYTE bSec; BYTE bFrame; BYTE bRunningTime; BYTE bAminOrPmin; BYTE bAsecOrPsec; BYTE bAframeOrPframe; } QInfo;
Получение информации о подканале// --------------- // Код функции 13 // --------------- #pragma pack(1) typedef struct _QInfo { BYTE bFunctionCode; DWORD dwStartSector; DWORD dwTransferAddress; DWORD dwNumberOfSectors; } QInfo;
Получение штрих-кода изготовителя компакт-диска// --------------- // Код функции 14 // --------------- #pragma pack(1) typedef struct _UPCCode { BYTE bFunctionCode; BYTE bCtrlAndARD; BYTE bUPCCode[7]; BYTE bZero; BYTE bAFrame; } UPCCode;
Сброс входных буферовКоманда освобождает все входные буферы и отменяет все запущенные команды. Формат заголовка запроса: // --------------- // Код команды 7 // --------------- #pragma pack(1) typedef struct _Flush { ReqHdr rh; } Flush; Заполнение полей заголовка запроса:
Запись IOCTL OutputПри помощи команды IOCTL Output программа может заставить драйвер выполнять различные операции, такие как управление механизмом извлечения компакт-диска. Формат заголовка запроса: // --------------- // Код команды 12 // --------------- #pragma pack(1) typedef struct _IOCTL_Output { ReqHdr rh; BYTE bMediaDescriptor; DWORD lpTransferAddress; WORD wDataSize; WORD wStartSector; DWORD lpVolID; } IOCTL_Output; Заполнение полей заголовка запроса:
Рассмотрим форматы заголовков различных функций, выполняемых в рамках команды IOCTL Output. Извлечение компакт-диска// --------------- // Код функции 0 // --------------- #pragma pack(1) typedef struct _EjectDisk { BYTE bFunctionCode; } EjectDisk;
Блокирование и разблокирование компакт-диска в устройстве// --------------- // Код функции 1 // --------------- #pragma pack(1) typedef struct _LockDisk { BYTE bFunctionCode; BYTE bLock; } LockDisk;
Сброс устройства чтения CD-ROM// --------------- // Код функции 2 // --------------- #pragma pack(1) typedef struct _ResetDrive { BYTE bFunctionCode; } ResetDrive;
Управление звуковыми каналами// --------------- // Код функции 3 // --------------- #pragma pack(1) typedef struct _ChanControl { BYTE bFunctionCode; BYTE bInpChannel0; BYTE bVolControl0; BYTE bInpChannel1; BYTE bVolControl1; BYTE bInpChannel2; BYTE bVolControl2; BYTE bInpChannel3; BYTE bVolControl3; } ChanControl;
Запись в устройство управляющей строки// --------------- // Код функции 4 // --------------- #pragma pack(1) typedef struct _DriveControlBytes { BYTE bFunctionCode; BYTE bWriteBuff[...]; // размер зависит от устройства } DriveControlBytes;
Закрывание приемного устройства для компакт-диска// --------------- // Код функции 5 // --------------- #pragma pack(1) typedef struct _CloseTray { BYTE bFunctionCode; } CloseTray;
Открывание устройстваКоманда открывает устройство чтения CD-ROM, сообщая драйверу о том, что данное устройство будет использовано еще одной программой. Формат заголовка запроса: // --------------- // Код команды 13 // --------------- #pragma pack(1) typedef struct _RsumePlay { ReqHdr rh; } RsumePlay; Заполнение полей заголовка запроса:
Закрывание устройстваКоманда закрывает устройство чтения CD-ROM, открытое предыдущей командой. Формат заголовка запроса: // --------------- // Код команды 14 // --------------- #pragma pack(1) typedef struct _RsumePlay { ReqHdr rh; } RsumePlay; Заполнение полей заголовка запроса:
Чтение длинноеПри помощи команды длинного чтения программа может прочитать полное содержимое сектора компакт-диска, включая служебные области сектора. Формат заголовка запроса: // --------------- // Код команды 128 // --------------- #pragma pack(1) typedef struct _ReadLong { ReqHdr rh; BYTE bAddressMode; DWORD lpTransferAddress; WORD wDataSize; WORD wStartSector; BYTE bDataReadMode; BYTE bInterleaveSise; BYTE bInterleaveSkip; } ReadLong; Заполнение полей заголовка запроса:
Чтение длинное с предварительной выборкойФункция аналогична предыдущей, но сразу после вызова она немедленно возвращает управление. Драйвер выполняет подготовительные действия для операции чтения, такие, например, как позиционирование головки, однако операция чтения не выполняется. Формат заголовка запроса: // --------------- // Код команды 130 // --------------- #pragma pack(1) typedef struct _ReadLongPrefetch { ReqHdr rh; BYTE bAddressMode; DWORD lpTransferAddress; WORD wDataSize; WORD wStartSector; BYTE bDataReadMode; BYTE bInterleaveSise; BYTE bInterleaveSkip; } ReadLongPrefetch; Заполнение полей заголовка запроса такое же, как и для предыдущей функции. ПоискКоманда выполняет позиционирование головки. Она возвращает управление немедленно, не дожидаясь завершения процесса позиционирования. Формат заголовка запроса: // --------------- // Код команды 131 // --------------- #pragma pack(1) typedef struct _Seek { ReqHdr rh; BYTE bAddressMode; DWORD lpTransferAddress; WORD wDataSize; WORD wStartSector; } Seek; Заполнение полей заголовка запроса:
Проигрывание звуковой дорожкиКоманда запускает проигрывание звуковой дорожки начиная с указанного сектора. Формат заголовка запроса: // --------------- // Код команды 132 // --------------- #pragma pack(1) typedef struct _Play { ReqHdr rh; BYTE bAddressMode; WORD wStartSector; WORD wNumberOfSectors; } Play; Заполнение полей заголовка запроса:
Остановка проигрывания звуковой дорожкиКоманда останавливает проигрывание звуковой дорожки. Формат заголовка запроса: // --------------- // Код команды 133 // --------------- #pragma pack(1) typedef struct _StopPlay { ReqHdr rh; } StopPlay; Заполнение полей заголовка запроса:
Возобновление проигрывания звуковой дорожкиКоманда останавливает проигрывание звуковой дорожки. Формат заголовка запроса: // --------------- // Код команды 136 // --------------- #pragma pack(1) typedef struct _RsumePlay { ReqHdr rh; } RsumePlay; Заполнение полей заголовка запроса:
|