Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

MS-DOS для программиста

© Александр Фролов, Григорий Фролов
Том 19, М.: Диалог-МИФИ, 1995, 253 стр.

[Назад] [Содеожание] [Дальше]

4.3. Примеры использования функций GENERIC IOCTL

В этом разделе мы приведем исходные тексты двух программ. Первая из них форматирует дорожку дискеты с помощью функции GENERIC IOCTL . Вторая демонстрирует способы чтения и записи секторов дискеты. Для этого она также пользуется функциями GENERIC IOCTL.

Программа FMTIOCTL

Приведем пример программы FMTIOCTL (листинг 4.1), иллюстрирующей применение функций общего управления GENERIC IOCTL . Эта программа выполняет стандартное форматирование двадцатой дорожки диска А:.


Листинг 4.1. Файл fmtioctl\fmtioctl.cpp


#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <errno.h>

typedef struct _EBPB_
{
  unsigned sectsize;
  char clustsize;
  unsigned ressecs;
  char fatcnt;
  unsigned rootsize;
  unsigned totsecs;
  char media;
  unsigned fatsize;
  unsigned seccnt;
  unsigned headcnt;
  unsigned hiddensec_low;
  unsigned hiddensec_hi;
  unsigned long drvsecs;
} EBPB;

typedef struct _TRK_LY_
{
  unsigned no;
  unsigned size;
} TRK_LY;

typedef struct _DPB_
{
  char spec;
  char devtype;
  unsigned devattr;
  unsigned numofcyl;
  char media_type;
  EBPB bpb;
  char reserved[6];
  unsigned trkcnt;
  TRK_LY trk[100];
} DPB;

typedef struct _DPB_FORMAT_
{
  char spec;
  unsigned head;
  unsigned track;
} DPB_FORMAT;

int main(void)
{
  union REGS reg;
  struct SREGS segreg;
  DPB far *dbp;
  DPB_FORMAT far *dbp_f;
  int sectors, i;

  printf("\nПрограмма уничтожит содержимое"
    "\n20-й дорожки диска А:."
    "\nЖелаете продолжить? (Y,N)\n");

  // Ожидаем ответ и анализируем его
  i = getch();
  if((i != 'y') && (i != 'Y'))
    return(-1);

  // Заказываем память для блока
  // параметров устройства
  dbp = (DPB far*)farmalloc(sizeof(DPB));

  // Заказываем память для блока параметров
  // устройства, который будет
  // использован для форматирования
  dbp_f = (DPB_FORMAT far*)
    farmalloc(sizeof(DPB_FORMAT));

  if(dbp == NULL || dbp_f == NULL)
  {
    printf("\nМало памяти");
    return(-1);
  }

  // Получаем текущие параметры диска А:
  dbp->spec = 0;

  // Вызываем подфункцию 0Dh для выполнения
  // операции чтения текущих параметров диска А:
  reg.x.ax = 0x440d;
  reg.h.bl = 1;
  reg.x.cx = 0x0860;
  reg.x.dx =  FP_OFF(dbp);
  segreg.ds = FP_SEG(dbp);
  intdosx(&reg, &reg, &segreg);

  // Проверяем результат выполнения операции
  if(reg.x.cflag != 0)
  {
    printf("\nОшибка: %d",reg.x.ax);
    return(-1);
  }

  // Заполняем блок парметров для форматирования.
  // Байт специальных функций содержит значение,
  // равное 5. Это означает, что:
  //    - используется текущий блок параметров BIOS  BPB ;
  //    - используются все поля в блоке парметров устройства;
  //    - все секторы на дорожке имеют одинаковый размер
  dbp->spec = 5;

  // Считываем из BPB  количество секторов на дорожке
  sectors = dbp->bpb.seccnt;

  // Подготавливаем таблицу, описывающую формат дорожки

  // Записываем количество секторов на дорожке
  dbp->trkcnt = sectors;

  // Для каждого сектора на дорожке в таблицу
  // записываем его номер и размер.
  // Заметьте, что записывается размер сектора
  // в байтах, а не код размера, как это делается
  // при форматировании с помощью
  // функции 05h прерывания INT 13h
  for(i = 0; i < sectors; i++)
  {
    dbp->trk[i].no   = i + 1;
    dbp->trk[i].size = 512;
  }

  // Устанавливаем новые параметры для диска А:
  reg.x.ax = 0x440d;
  reg.h.bl = 1;
  reg.x.cx = 0x0840;
  reg.x.dx =  FP_OFF(dbp);
  segreg.ds = FP_SEG(dbp);
  intdosx(&reg, &reg, &segreg);

  // Проверяем результат выполнения операции
  if(reg.x.cflag != 0)
  {
    printf("\nОшибка: %d",reg.x.ax);
    return(-1);
  }

  // Подготавливаем блок параметров устройства,
  // который будет использован при вызове
  // операции проверки возможности форматирования
  // дорожки.
  // В поле специальных функций записываем 1,
  // это означает, что будет выполняться проверка
  // возможности использования
  // указанного формата дорожки
  dbp_f->spec = 1;
  dbp_f->head = 0;
  dbp_f->track = 20;

  reg.x.ax = 0x440d;
  reg.h.bl = 1;
  reg.x.cx = 0x0842;
  reg.x.dx =  FP_OFF(dbp_f);
  segreg.ds = FP_SEG(dbp_f);
  intdosx(&reg, &reg, &segreg);

  // Проверяем результат выполнения операции
  if(reg.x.cflag != 0)
  {
    printf("\nОшибка: %d", reg.x.ax);
    return(-1);
  }

  // Если указанный формат дорожки поддерживается,
  // поле специальных функций будет содержать 0.
  // Проверяем это
  if(dbp_f->spec != 0)
  {
    printf("\nФормат дорожки не поддерживается");
    return(-1);
  }

  // Заполняем блок параметров для выполнения
  // операции форматирования
  dbp_f->spec = 0;
  dbp_f->head = 0;
  dbp_f->track = 20;

  // Форматируем дорожку с номером 20, головка 0
  reg.x.ax = 0x440d;
  reg.h.bl = 1;
  reg.x.cx = 0x0842;
  reg.x.dx =  FP_OFF(dbp_f);
  segreg.ds = FP_SEG(dbp_f);
  intdosx(&reg, &reg, &segreg);

  // Проверяем резултат выполнения операции
  if(reg.x.cflag != 0)
  {
    printf("\nОшибка: %d", reg.x.ax);
    return(-1);
  }

  // Освобождаем память
  farfree(dbp);
  farfree(dbp_f);

  return(0);
}

После запуска программа форматирования читает текущие параметры для диска А:, формирует структуру дорожки и устанавливает параметры для выполнения операции форматирования. Затем программа проверяет возможность использования указанной структуры дорожки и выполняет форматирование.

Программа CPYIOCTL

Теперь приведем программу CPYIOCTL (листинг 4.2), копирующую содержимое двух первых секторов нулевой дорожки (головка 0) в первые два сектора двадцатой дорожки.


Листинг 4.2. Файл cpyioctl\cpyioctl.cpp


#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <errno.h>

typedef struct _DPB_WR_
{
  char spec;
  unsigned head;
  unsigned track;
  unsigned sector;
  unsigned sectcnt;
  void _far *buffer;
} DPB_WR;

char buf[2000];

int main(void)
{
  union REGS reg;
  struct SREGS segreg;
  DPB_WR far *dbp_wr;
  int sectors, i;

  printf("\nПрограмма уничтожит содержимое"
    "\n20-й дорожки диска А:."
    "\nЖелаете продолжить? (Y,N)\n");

  // Ожидаем ответ и анализируем его
  i = getch();
  if((i != 'y') && (i != 'Y'))
    return(-1);

  // Заказываем память для блока параметров
  // устройства, который будет
  // использован для чтения и записи
  dbp_wr = (DPB_WR far*)farmalloc(sizeof(DPB_WR));

  if(dbp_wr == NULL)
  {
    printf("\nМало памяти");
    return(-1);
  }

  // Заполняем блок параметров для выполнения
  // операции чтения.
  // Мы будем читать первые два сектора
  // на нулевой дорожке, головка 0
  dbp_wr->spec = 0;
  dbp_wr->head = 0;
  dbp_wr->track = 0;
  dbp_wr->sector = 0;
  dbp_wr->sectcnt = 2;
  dbp_wr->buffer = buf;

  // Выполняем операцию чтения дорожки
  reg.x.ax = 0x440d;
  reg.h.bl = 1;
  reg.x.cx = 0x0861;
  reg.x.dx =  FP_OFF(dbp_wr);
  segreg.ds = FP_SEG(dbp_wr);
  intdosx(&reg, &reg, &segreg);

  // Проверяем результат выполнения операции
  if(reg.x.cflag != 0)
  {
    printf("\nОшибка: %d", reg.x.ax);
    return(-1);
  }

  // Заполняем блок параметров для выполнения
  // операции записи.
  // Только что прочитанные два сектора нулевой
  // дорожки будут записаны на 20-ю дорожку
  dbp_wr->spec = 0;
  dbp_wr->head = 0;
  dbp_wr->track = 20;
  dbp_wr->sector = 0;
  dbp_wr->sectcnt = 2;
  dbp_wr->buffer = buf;

  // Выполняем операцию записи
  reg.x.ax = 0x440d;
  reg.h.bl = 1;
  reg.x.cx = 0x0841;
  reg.x.dx =  FP_OFF(dbp_wr);
  segreg.ds = FP_SEG(dbp_wr);
  intdosx(&reg, &reg, &segreg);

  // Проверяем результат выполнения операции
  if(reg.x.cflag != 0)
  {
    printf("\nОшибка: %d", reg.x.ax);
    return(-1);
  }

  // Освобождаем память
  farfree(dbp_wr);

  return(0);
}

Программа пользуется текущими параметрами диска А:, поэтому операции чтения текущих параметров и записи новых параметров не используются.

Обратите внимание на то, что эта и предыдущая программа разрушают содержимое двадцатой дорожки, поэтому для экспериментов с этими программами надо подготовить чистую отформатированную дискету.

[Назад] [Содеожание] [Дальше]