Blog. Just Blog

Управление лотком CD-ROM на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Открывать и закрывать лоток CD-ROM можно программными способами. Это может оказаться полезным в случаях, когда системный блок стоит в труднодоступном месте или по каким-либо иным причинам нет возможности управлять им при помощи механической кнопки. Также я читал истории, когда на лоток CD-ROM возлагались полезные функции, например, при выдвижении он замыкал контакты питания и отправлял сервер в перезагрузку, а администратор таким образом удаленно управлял им. Так что программное управление лотком CD-ROM имеет место быть, и наша задача научиться его делать. Чаще всего в разных интернетах описывается способ управления при помощи MCI (Media Control Interface). Кстати, именно этот способ приводится в качестве одного из примеров программ в пакете FASM.
  1.         ...
  2.         ; Открыть лоток CD-ROM
  3.         invoke  mciSendString,cmd_open,0,0,0
  4.         invoke  mciSendString,cmd_eject,0,0,0
  5.         invoke  mciSendString,cmd_close,0,0,0
  6.         ...
  7.         ; Закрыть лоток CD-ROM
  8.         invoke  mciSendString,cmd_open,0,0,0
  9.         invoke  mciSendString,cmd_load,0,0,0
  10.         invoke  mciSendString,cmd_close,0,0,0
  11.         ...
  12. cmd_open   db 'open cdaudio',0
  13. cmd_eject  db 'set cdaudio door open',0
  14. cmd_load   db 'set cdaudio door closed',0
  15. cmd_close  db 'close cdaudio',0
У данного метода есть недостатки. Главный заключается в том, что при наличии в системе нескольких приводов CD-ROM нет возможности указать, лоток которого из них необходимо выдвигать, всегда открывается первый по счету. Второй существенный недостаток - некоторые антивирусы считают наличие таких функций в программах потенциально опасными. Видимо из-за того, что иногда несанкционированное открытие лотка CD-ROM используется в различных программах-шутках для окошмаривания доверчивых пользователей.

Второй способ заключается в прямом обращении к драйверу дискового устройства с помощью функции управления вводом/выводом, которая называется DeviceIoControl. Эта функция официально документирована и присутствует на всех системах, начиная с Win9X. В контексте нашей задачи она используется следующим образом:
  1. ; Сегмент данных
  2. section '.data' data readable writeable  
  3. path    db '\\.\E:',0     ; Полное имя CD-ROM
  4. tmp     dd ?              ; Временная переменная для DeviceIoControl
  5.  
  6. ; Константы в FASM не определены, делаем это сами
  7. IOCTL_DISK_EJECT_MEDIA = 74808h
  8. IOCTL_DISK_LOAD_MEDIA  = 7480Ch
  9.  
  10. ; Сегмент кода
  11. section '.code' code readable executable
  12.         ...
  13.         ; Открыть лоток CD-ROM
  14.         invoke  CreateFile,path,GENERIC_READ,FILE_SHARE_READ,\
  15.                 NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
  16.         mov     ebx,eax
  17.         invoke  DeviceIoControl,ebx,IOCTL_DISK_EJECT_MEDIA,NULL,\
  18.                 NULL,NULL,NULL,tmp,NULL
  19.         invoke  CloseHandle,ebx
  20.         ...
  21.         ; Закрыть лоток CD-ROM
  22.         invoke  CreateFile,path,GENERIC_READ,FILE_SHARE_READ,\
  23.                 NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
  24.         mov     ebx,eax
  25.         invoke  DeviceIoControl,ebx,IOCTL_DISK_LOAD_MEDIA,NULL,\
  26.                 NULL,NULL,NULL,tmp,NULL
  27.         invoke  CloseHandle,ebx
  28.         ...
Константы IOCTL_DISK_EJECT_MEDIA и IOCTL_DISK_LOAD_MEDIA, используемые при вызове функции DeviceIoControl, в FASM изначально не определены, пришлось покопаться в сети и сделать это самостоятельно. Обратите внимание, что в этом случае можно выбирать какой дисковод открыть или закрыть, но путь к нему должен быть прописан в полном формате, например, "\\.\E:" Возможно, что еще потребуется получить список всех дисков, имеющихся в системе, это можно легко сделать при помощи функции GetLogicalDriveStrings, она возвращает список всех дисков в виде строки:

'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 секунд закрывает их обратно.

Примеры программ с исходными текстами (FASM)Примеры программ с исходными текстами (FASM)

CD-ROM.Control.Demo.zip (2,887 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 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 назад в бинарнике игры Плачущий Меч, когда отучивал от СиДи

Спасибо - столько вспомнилось!
эх студенчество

написано все вкусно, полезно и без химии ))

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0045 сек.) / Память: 4.5 Mb
Наверх