Управление лотком CD-ROM на Ассемблере
Открывать и закрывать лоток CD-ROM можно программными способами. Это может оказаться полезным в случаях, когда системный блок стоит в труднодоступном месте или по каким-либо иным причинам нет возможности управлять им при помощи механической кнопки. Также я читал истории, когда на лоток CD-ROM возлагались полезные функции, например, при выдвижении он замыкал контакты питания и отправлял сервер в перезагрузку, а администратор таким образом удаленно управлял им. Так что программное управление лотком CD-ROM имеет место быть, и наша задача научиться его делать. Чаще всего в разных интернетах описывается способ управления при помощи MCI (Media Control Interface). Кстати, именно этот способ приводится в качестве одного из примеров программ в пакете FASM.Code (Assembler) : Убрать нумерацию
- ...
- ; Открыть лоток CD-ROM
- invoke mciSendString,cmd_open,0,0,0
- invoke mciSendString,cmd_eject,0,0,0
- invoke mciSendString,cmd_close,0,0,0
- ...
- ; Закрыть лоток CD-ROM
- invoke mciSendString,cmd_open,0,0,0
- invoke mciSendString,cmd_load,0,0,0
- invoke mciSendString,cmd_close,0,0,0
- ...
- cmd_open db 'open cdaudio',0
- cmd_eject db 'set cdaudio door open',0
- cmd_load db 'set cdaudio door closed',0
- cmd_close db 'close cdaudio',0
Второй способ заключается в прямом обращении к драйверу дискового устройства с помощью функции управления вводом/выводом, которая называется DeviceIoControl. Эта функция официально документирована и присутствует на всех системах, начиная с Win9X. В контексте нашей задачи она используется следующим образом:
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- path db '\\.\E:',0 ; Полное имя CD-ROM
- tmp dd ? ; Временная переменная для DeviceIoControl
- ; Константы в FASM не определены, делаем это сами
- IOCTL_DISK_EJECT_MEDIA = 74808h
- IOCTL_DISK_LOAD_MEDIA = 7480Ch
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ; Открыть лоток CD-ROM
- invoke CreateFile,path,GENERIC_READ,FILE_SHARE_READ,\
- NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
- mov ebx,eax
- invoke DeviceIoControl,ebx,IOCTL_DISK_EJECT_MEDIA,NULL,\
- NULL,NULL,NULL,tmp,NULL
- invoke CloseHandle,ebx
- ...
- ; Закрыть лоток CD-ROM
- invoke CreateFile,path,GENERIC_READ,FILE_SHARE_READ,\
- NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
- mov ebx,eax
- invoke DeviceIoControl,ebx,IOCTL_DISK_LOAD_MEDIA,NULL,\
- NULL,NULL,NULL,tmp,NULL
- invoke CloseHandle,ebx
- ...
'A:\', 0, 'C:\', 0, 'D:\', 0, 'E:\', 0, 'F:\', 0, 'G:\', 0, 0
Буквы дисков разделены символом с кодом 00h, строка оканчивается двойным нулем. Чтобы узнать, является ли выбранный диск приводом CD-ROM, проще всего использовать функцию GetDriveType, она должна вернуть значение DRIVE_CDROM. Вот теперь у нас есть все необходимые инструменты для управления лотком CD-ROM, можете начинать применять их на практике.
В приложении две программы с исходниками, применяющие оба описанных в статье способа управления. Первая использует Media Control Interface для открытия лотка CD-ROM, затем через 5 секунд закрывает его обратно. Вторая использует функцию DeviceIoControl и открывает лотки всех доступных CD-ROM, затем также через 5 секунд закрывает их обратно.
Просмотров: 10161 | Комментариев: 6
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
laser
(11.10.2011 в 00:31):
спасибо,а как включить лазерный диод
ManHunter
(05.02.2011 в 17:14):
Это никак не сделать. В таких открывалках-закрывалках принимается некое начальное значение, например "закрыто", а потом при нажатии значение инвертируется, и, соответственно, диск или извлекается, или загружается. Плюс отлов сообщений WM_DEVICECHANGE, плюс проверка наличия диска в дисководе. По совокупности этих данных можно _примерно_ определить состояние CD-ROM.
Jura
(05.02.2011 в 13:58):
А вот в Nero DriveSpeed есть кнопка, которая открывает лоток дисковода, если он закрыт и закрывает его, если открыт. Как реализовать такое? Как проверить состояние лотка?
ManHunter
(05.02.2011 в 12:11):
Nero Burning ROM именно так и делает.
64-ядерный процессор
(05.02.2011 в 12:05):
Это очень актуально в случае, если пишешь прогирамму для записи дисков. Типа если нет диска в приводе, то она автоматически откроет дисковод. Спасибо за статью =))
ezfalc0n
(05.02.2011 в 02:37):
да, да mciSendString - нарыл ее вызов лет 10 назад в бинарнике игры Плачущий Меч, когда отучивал от СиДи
Спасибо - столько вспомнилось!
эх студенчество
написано все вкусно, полезно и без химии ))
Спасибо - столько вспомнилось!
эх студенчество
написано все вкусно, полезно и без химии ))
Добавить комментарий
Заполните форму для добавления комментария