MS-DOS для программиста© Александр Фролов, Григорий ФроловТом 18, М.: Диалог-МИФИ, 1995, 254 стр. 6.6. Драйвер системных часов CLOCK$Операционная система содержит в своем составе драйвер системных часов. Это драйвер символьного устройства, имя устройства - CLOCK$. Символ "$" используется для того, чтобы это имя не конфликтовало с именем файла clock. Дело в том, что пользователь может создать файл с именем clock, но с именем clock$ - едва ли (разве лишь он пожелает закодировать в этом имени фразу "время - деньги"). Характерный признак драйвера системных часов - бит 3 слова атрибутов устройства установлен в 1. Именно этот признак используется MS-DOS для обнаружения драйвера часов. Для опроса содержимого часов или для установки часов операционная система, соответственно, читает или записывает шесть байт информации следующего формата:
Приведем исходный текст программы gettime (листинг 6.1). Эта программа открывает устройство CLOCK$ , задает двоичный режим обмена данных и вводит 6 байт, имеющих только что описанную структуру. Определенные таким способом показания часов выводятся на экран. Листинг 6.1. Файл gettime\gettime.cpp #include <io.h> #include <stdio.h> #include <fcntl.h> #include <errno .h> #include <dos.h> union REGS inregs, outregs; struct SREGS segregs; int main(void) { int io_handle; struct { unsigned days; unsigned char min; unsigned char hours; unsigned char sec_per_100; unsigned char sec; } clock_buf; // Открываем устройство с именем CLOCK$ if((io_handle = open("CLOCK$ ", O_RDWR)) == - 1) { // Если открыть устройство не удалось, выводим // код ошибки printf("Open: ошибка %d", errno ); return errno ; } // Определяем конфигурацию устройства inregs.h.ah = 0x44; inregs.h.al = 0; inregs.x.bx = io_handle; intdos (&inregs, &outregs); if(outregs.x.cflag == 1) { // При возникновении ошибки выводим ее код printf("IOCTL : ошибка %x\n", &outregs.x.ax); return(-1); } // Устанавливаем бит 5 (переключаем драйвер // в двоичный режим обмена данными) inregs.x.dx = (outregs.x.dx | 0x0020) & 0x00ff; // Устанавливаем слово конфигурации устройства inregs.h.ah = 0x44; inregs.h.al = 1; inregs.x.bx = io_handle; intdos ( &inregs, &outregs ); if(outregs.x.cflag == 1) { // При возникновении ошибки выводим ее код printf("IOCTL : ошибка %x\n", &outregs.x.ax); return(-1); } // Выводим слово конфигурации устройства printf("\nКонфигурация устройства: %04X\n", outregs.x.dx); // Читаем 6 байт из устройства в буфер buf // Обмен выполняется в двоичном режиме if(read(io_handle, &clock_buf, 6) == -1) { // Если при чтении произошла ошибка, // выводим ее код printf("Read: ошибка %d",errno ); return errno ; } printf("\nПолучено от драйвера часов CLOCK$ :" "\n" "\nПрошло дней после 01.01.80: %d" "\nМинуты: %d" "\nЧасы: %d" "\nСекунды: %d" "\nСотые доли секунды: %d" "\n", clock_buf.days, clock_buf.min, clock_buf.hours, clock_buf.sec, clock_buf.sec_per_100); // Закрываем устройство close(io_handle); return(0); } |