КаталогИндекс раздела
НазадОглавлениеВперед


Лабораторная работа N11
ДРАЙВЕРЫ DOS

1. Цель работы

Просмотреть список драйверов, которые в данный момент загружены в конкретной ПЭВМ.

2. Темы для предварительной проработки

3. Постановка задачи

Определить драйверы, резидентные в памяти компьютера на своем рабочем месте.

4. Порядок выполнения работы

Порядок выполнения работы и содержание отчета определены в общих указаниях.

5. Пример решения задачи

5.1. Разработка алгоритма решения

5.1.1. Структура программы

Программа состоит из основной программы main() и девяти вспомогательных функций.

5.1.2. Описание переменных

Переменные глобальные для всей программы:

В программе описана следующая структура заголовка драйвера:

  struct DR_HEAD {
      struct dr_head *next;     /* адрес следующего */
      word attr;                /* атрибуты */
      word strat_off, intr_off; /* смещения секций */
      char name[8];             /* имя */
  };

5.1.3. Описание алгоритма программы

Основная программа main() осуществляет просмотор списка драйверов и выводит на экран информацию о них при помощи вспомогательных функций.

Функция clrbuf(void) читает символы из буфера клавиатуры, пока он не опустеет.

Функция MemW(x,y,xr,yr) использует для обращения к видеопамяти функции GetSym, GetAtr. x, y - координаты левого верхнего угла прямоугольной области экрана. 8xr, yr - размеры области по горизонтали и вертикали соответственно.

Функция RmmW(x,y,xr,yr) использует для обращения к видеопамяти функции PutSym, PutAtr. x, y - координаты левого верхнего угла прямоугольной области экрана. xr, yr - размеры области по горизонтали и вертикали соответственно.

Функция ClrW(x1,y1,x2,y2,s,a) - использует для обращения к видеопамяти функции PutSym, PutAtr. x1, y1, x2, y2 - координаты прямоугольной области. s, a - символ и атрибут соответственно для заполнения области экрана.

Функция FlDrv(void) рассматривает побитно байт атрибута драйвера и может выдавать информацию в соответствии со значением атрибута.

Слово атрибутов драйвера в старшем разряде содержит признак символьного (1) или блочного (0) устройства. Интерпретация остальных разрядов слова атрибутов существенно разная для символьных и блочных устройств. Для символьных устройств слово атрибутов имеет формат:

         1 e b 0 p 0 0 0  0 l 0 0 c n o i,


а для блочных устройств:
         0 e m 0 p 0 0 0  0 l 0 0 0 0 s 0,

где  i - драйвер консоли ввода;
 o - драйвер консоли вывода;
 n - драйвер нулевого (пустого) устройства;
 c - драйвер часов;
 l - драйвер поддерживает функции, введенные в DOS 3.2;
 p - драйвер выполняет операции Open/Close;
 b - драйвер неIBM-овского блочного устройства;
 e - драйвер поддерживает функции IOCTL;
 s - драйвер поддерживает 32-битную адресацию сектора;
 m - драйвер определяет тип диска проверкой 1-го байта FAT.

По правилам DOS кодовая часть драйвера состоит из двух секций, называемых секцией стратегии и секцией обработки прерываний. Поля strat_off и intr_off заголовка содержат смещения этих секций от начала драйвера. Поле name для символьного устройства содержит имя устройства (возможно, дополненное пробелами), а для блочного - первый байт этого поля содержит количество устройств, поддерживаемых драйвером.

При помощи поля next, заполняемого системой при загрузке драйвера, все драйверы (системные и устанавливаемые) связываются в список. Начало этого списка - заголовок драйвера NUL в CVT. Значение FFFFh в части смещения поля next является признаком конца списка (такой же признак конца используется и в списках, образуемых другими управляющими блоками). Главная программа примера отслеживает этот список.

5.2. Текст программы

/*----------------Лабораторная работа N11-----------------*/
/*--------------"Просмотр списка драйверов."--------------*/
#include <dos.h>
#include <conio.h>
/*-----------------------Константы----------------------- */
#define byte unsigned char
#define word unsigned int
#define ATR(x,z) if(drv->attr&x){cprintf("     %s\n\r",z);y++;}
#define DA(x,y) (struct DR_HEAD *)MK_FP(x,y);
#define VSEG 0xb800       /* Сегментный адрес видеопамяти */
#define byte unsigned char
#define word unsigned int
#define Enter 13
#define rx 50
#define ry 13

int xk,yk;
word cc;
byte bm[rx][ry][2];
8struct DR_HEAD { /* заголовок драйвера */
   struct DR_HEAD *next;
   word attr, strat_addr, intr_addr;
   char name[8];
   } *drv;  /* адрес текущего драйвера */
struct DR_HEAD *clock, *con;  /* Адреса CLOCK$ и CON */
union REGS rr;
struct SREGS sr;
int i, y, y1;

/*---------------------------------------------------*/
void clrbuf(void)
{
 while(kbhit()) getch();
}
/*--------------Чтение символа из видеопамяти-------------*/
byte GetSym(x1,y1)
int x1,y1;
{
 return(peekb(VSEG,y1*160+x1*2));
}
/*-------------Чтение атрибута из видеопамяти-------------*/
byte GetAtr(x1,y1)
int x1,y1;
{
 return(peekb(VSEG,y1*160+x1*2+1));
}
/*-------------Запись символа в видеопамять---------------*/
void PutSym(x1,y1,sym)
int x1,y1;
byte sym;
{
 pokeb(VSEG,y1*160+x1*2,sym);
}
/*-------------Запись атрибута в видеопамять--------------*/
void PutAtr(x1,y1,atr)
8int x1,y1;
byte atr;
{
 pokeb(VSEG,y1*160+x1*2+1,atr);
}
/*--------------------------------------------------------*/
void MemW(x,y,xr,yr)
int x,y,xr,yr;
{
 int i,j;
 for (j=y;j<(y+yr);j++)
  for (i=x;i<(x+xr);i++)
   {
    bm[i][j][0]=GetSym(i,j);
    bm[i][j][1]=GetAtr(i,j);
   }
}
/*--------------------------------------------------------*/
void RmmW(x,y,xr,yr)
int x,y,xr,yr;
{
 int i,j;
 for (j=y;j<(y+yr);j++)
  for (i=x;i<(x+xr);i++)
   {
    PutSym(i,j,bm[i][j][0]);
    PutAtr(i,j,bm[i][j][1]);
   }
}
/*--------------------------------------------------------*/
void ClrW(x1,y1,x2,y2,s,a)
int x1,y1,x2,y2;
byte s,a;
{
 int i,j;
 for (j=y1;j<y2;j++)
  for (i=x1;i<x2;i++)
   {
    if (s!=0) PutSym(i,j,s);
    PutAtr(i,j,a);
   }
}
/*--------------------------------------------------------*/
void FlDrv(void)
{
 int xm,ym;
 xm=wherex();
 ym=wherey();
 MemW(0,1,rx,ry);
 ClrW(1,2,rx,ry,0,7);
 ClrW(0,1,rx-2,ry-2,32,16);
 gotoxy(1,2);
 textattr(15+16*3);
 cprintf("***         Атрибуты драйвера %5u          ***",cc);
 gotoxy(1,3);
 textattr(15+16);
 if (drv==clock) cprintf("     активный CLOCK$");
 if (drv==con) cprintf("     активный CON");
 gotoxy(1,4);
 textattr(14+16);
 if (drv->attr&0x8000)
 {
  ATR(1,"консоль ввода")
  ATR(2,"консоль вывода")
  ATR(4,"нулевое устройство")
  ATR(8,"CLOCK$ (часы)")
  ATR(0x2000,"поддерживает OUB")
 }
 else
 {
  ATR(2,"32-байтный адрес сектора")
  ATR(0x2000,"читает media FAT")
 }
 ATR(0x40,"поддерживает функции DOS 3.2")
 ATR(0x800,"поддерживает Open/Close")
 ATR(0x4000,"поддерживает IOCTL")
 gotoxy(1,12);
 textattr(15+16*3+128);
 cprintf("***          Нажмите любую клавишу...        ***");
 if (getch()==0) getch();
 RmmW(0,1,rx,ry);
 gotoxy(xm,ym);

}
/*--------------------------------------------------------*/
main() {
  int c;
  /* получение адреса CVT */
  rr.h.ah=0x52; intdosx(&rr,&rr,&sr);
  /* адрес драйвера часов */
  clock=DA(peek(sr.es,rr.x.bx+10),peek(sr.es,rr.x.bx+8));
  /* адрес драйвера консоли */
  con=DA(peek(sr.es,rr.x.bx+14),peek(sr.es,rr.x.bx+12));
  /* адрес NUL-драйвера */
  textattr(10);
  clrscr();
  cprintf("---------------");
  cprintf("              Лабораторная работа N11             ");
  cprintf("---------------");
  cprintf("---------------");
  cprintf("             Просмотр списка драйверов.           ");
  cprintf("---------------");

  drv=DA(sr.es,rr.x.bx+34);
  textattr(7);
  gotoxy(8,3);
  cprintf("Нажимайте <SpaceBar> ,а для рассмотрения атрибутов",
           "драйвера <Enter>.");
  textattr(12);
  gotoxy(28,4);
  cc=1;
  cprintf("Список драйверов устройств :\n\r");
  while(FP_OFF(drv)!=0xffff) {
    textattr(15);
    cprintf("%5u",cc);
    textattr(14);
    cprintf("  Адрес - %Fp    ",drv);
    textattr(11);
    cprintf(" атрибуты - %04X   ",drv->attr);
    textattr(13);
    if (drv->attr&0x8000)
      for (i=0;i<8; cprintf("%c",drv->name[i++]));
    else cprintf("блочный - %d",drv->name[0]);
      cprintf("\n\r"); y=0;
    while ((c=getch())==Enter)FlDrv();
    if (c==0) getch();
    drv=drv->next; /* адрес след.драйвера */
    cc++;
  }
  textattr(12+128);
  cprintf("Конец списка.     Нажмите любую клавишу...\n");
  getch();
  textattr(7);
}

5.3. Результаты работы программы

В процессе работы программы на экран была выведена следующая информация о распределении памяти:

--------------------------------------------------------------------------------
---------------              Лабораторная работа N11             ---------------
---------------             Просмотр списка драйверов.           ---------------
       Нажимайте <SpaceBar> ,а для рассмотрения атрибутов драйвера <Enter>.
                           Список драйверов устройств :
    1  Адрес - 011C:0048     атрибуты - 8004   NUL
    2  Адрес - 02A6:0000     атрибуты - 8000   SETVERXX
    3  Адрес - 025D:0000     атрибуты - A000   XMSXXXX0
    4  Адрес - 0070:0023     атрибуты - 8013   CON
    5  Адрес - 0070:0035     атрибуты - 8000   AUX
    6  Адрес - 0070:0047     атрибуты - A0C0   PRN
    7  Адрес - 0070:0059     атрибуты - 8008   CLOCK$
    8  Адрес - 0070:006B     атрибуты - 08C2   блочный - 4
    9  Адрес - 0070:007B     атрибуты - 8000   COM1
   10  Адрес - 0070:008D     атрибуты - A0C0   LPT1
   11  Адрес - 0070:009F     атрибуты - A0C0   LPT2
   12  Адрес - 0070:00B8     атрибуты - A0C0   LPT3
   13  Адрес - 0070:00CA     атрибуты - 8000   COM2

   14  Адрес - 0070:00DC     атрибуты - 8000   COM3
   15  Адрес - 0070:00EE     атрибуты - 8000   COM4
Конец списка.     Нажмите любую клавишу...

--------------------------------------------------------------------------------

При нажатии клавиши Enter открывается окно в котором подробно расписываются атрибуты драйвера. Например, атрибуты драйвера 8: ------------------------------------------------ ------------------------------------------------ ----------- Атрибуты драйвера 8 ------------ ------------------------------------------------ ---- 32-байтный адрес сектора ------------------ ---- поддерживает функции DOS 3.2 -------------- ---- поддерживает Open/Close ------------------- ------------------------------------------------ ------------------------------------------------ ------------------------------------------------ ------------------------------------------------ ------------------------------------------------ --------- Нажмите любую клавишу... ----------- ------------------------------------------------


КаталогИндекс раздела
НазадОглавлениеВперед