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

Открывать и закрывать лоток CD-ROM можно программными способами. Это может оказаться полезным в случаях, когда системный блок стоит в труднодоступном месте или по каким-либо иным причинам нет возможности управлять им при помощи механической кнопки. Также я читал истории, когда на лоток CD-ROM возлагались полезные функции, например, при выдвижении он замыкал контакты питания и отправлял сервер в перезагрузку, а администратор таким образом удаленно управлял им. Так что программное управление лотком CD-ROM имеет место быть, и наша задача научиться его делать. Чаще всего в разных интернетах описывается способ управления при помощи MCI (Media Control Interface). Кстати, именно этот способ приводится в качестве одного из примеров программ в пакете FASM.
        ...
        ; Открыть лоток 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

У данного метода есть недостатки. Главный заключается в том, что при наличии в системе нескольких приводов CD-ROM нет возможности указать, лоток которого из них необходимо выдвигать, всегда открывается первый по счету. Второй существенный недостаток - некоторые антивирусы считают наличие таких функций в программах потенциально опасными. Видимо из-за того, что иногда несанкционированное открытие лотка CD-ROM используется в различных программах-шутках для окошмаривания доверчивых пользователей.

Второй способ заключается в прямом обращении к драйверу дискового устройства с помощью функции управления вводом/выводом, которая называется DeviceIoControl. Эта функция официально документирована и присутствует на всех системах, начиная с Win9X. В контексте нашей задачи она используется следующим образом:
; Сегмент данных
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
        ...

Константы 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 секунд закрывает их обратно.
Теги:
CD-ROM
Добавлено: 10 Апреля 2018 20:35:16 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...