Аппаратное обеспечение персонального компьютера

       

Программа CDINFO


Программа CDINFO вызывает как функции расширения MSCDEX.EXE, так и драйвер устройства чтения CD-ROM, получая различную информацию как о расширении, так и о компакт-диске.

Вот пример листинга, полученного при работе программы CDINFO на виртуальной машине DOS в среде Microsoft Windows 95:

CDINFO, (c) A. Frolov, 1997

MSCDEX version: 2.95

Found 1 CD Unit, start unit: G

CD-ROM letters: G

Status of CD Drive G: 00000390

VolumeSize: 29460 blocks

Tracks: (1 - 1) 8252

track 1: location: 512, info: 41 * digital, copy prohibited *

Здесь в компьютере установлено только одно устройство чтения CD?ROM, в котором находился один цифровой компакт-диск.

Ниже мы представили листинг, полученный при аналогичных условиях на компьютере, оборудованном двумя устройствами чтения CD-ROM. В первое устройство (H:) был вставлен звуковой диск, а во второе (I:) - комбинированный диск с одной цифровой и тремя звуковыми дорожками:

CDINFO, (c) A. Frolov, 1997



MSCDEX version: 2.21

Found 2 CD Unit, start unit: H

CD-ROM letters: H I

Status of CD Drive H: 00000390

VolumeSize: 302375 blocks

Tracks: (1 - 15) 2866

track 1: location: 512, info: 01 * audio, copy prohibited *

track 2: location: 79922, info: 01 * audio, copy prohibited *

track 3: location: 466492, info: 01 * audio, copy prohibited *

track 4: location: 788490, info: 01 * audio, copy prohibited *

track 5: location: 1120281, info: 01 * audio, copy prohibited *

track 6: location: 1453334, info: 01 * audio, copy prohibited *

track 7: location: 1778979, info: 01 * audio, copy prohibited *

track 8: location: 2042649, info: 01 * audio, copy prohibited *

track 9: location: 2363412, info: 01 * audio, copy prohibited *

track 10: location: 2565639, info: 01 * audio, copy prohibited *

track 11: location: 2823479, info: 01 * audio, copy prohibited *

track 12: location: 3094814, info: 01 * audio, copy prohibited *

track 13: location: 3419404, info: 01 * audio, copy prohibited *

track 14: location: 3740478, info: 01 * audio, copy prohibited *


track 15: location: 4130306, info: 01 * audio, copy prohibited *

Status of CD Drive I: 00000390

VolumeSize: 278505 blocks

Tracks: (1 - 4) 13598

track 1: location: 512, info: 41 * digital, copy prohibited *

track 2: location: 3282733, info: 01 * audio, copy prohibited *

track 3: location: 3608079, info: 01 * audio, copy prohibited *

track 4: location: 3801921, info: 01 * audio, copy prohibited *

Заметим, что в среде виртуальной машины операционной системы Microsoft Windows NT эта программа показывает неверные результаты. Скорее всего это происходит из-за неправильной работы эмулятора расширения MSCDEX.

Исходный текст программы CDINFO вы найдете в листинге 9.1.

Листинг 9.1. Файл cdinfo\cdinfo.с

// =====================================================

// Прсмотр различной информации об устройствах

// чтения CD-ROM и компакт-дисках

// с помощью интерфейса MSCDEX и обращением к драйверу

// устройства чтения CD-ROM

//

// (C) Фролов А.В, 1997

//

// E-mail: frolov@glas.apc.org

// WWW:    http://www.glasnet.ru/~frolov

//            или

//         http://www.dials.ccas.ru/frolov

// =====================================================

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <dos.h>

#include <memory.h>

 

typedef unsigned char BYTE;

typedef unsigned int  WORD;

typedef unsigned long DWORD;

// Необходимо для обеспечения выравнивания

// полей структур на границу байта

#pragma pack(1)

// Заголовок запроса для обращения к драйверу

typedef struct _ReqHdr

{

  BYTE bSize;

  BYTE bSubUnit;

  BYTE bCmd;

  WORD wStatus;

  BYTE bReserved[8];   

} ReqHdr;

 

// Запрос IOCTL Input

typedef struct _IOCTL_Input

{            

  ReqHdr rh;

  BYTE   bMediaDescriptor;

  DWORD  lpTransferAddress;

  WORD   wDataSize;

  WORD   wStartSector;

  DWORD  lpVolID;

} IOCTL_Input;      

// Запрос на получение информации о компакт-диске

typedef struct _DiskInfo

{

  BYTE bControl;



  BYTE bLowest;

  BYTE bHighest;

  DWORD dwTotal;

} DiskInfo;

// Запрос на получение информации

// о дорожке компакт-диска

typedef struct _TrackInfo

{

  BYTE  bControl;

  BYTE  bTrack;

  DWORD dwLoc;

  BYTE  bInfo;

} TrackInfo;

// Запрос для определения текущего состояния

// устройства чтения CD-ROM

typedef struct _DeviceStatus

{

  BYTE bControl;

  DWORD dwParam;

} DeviceStatus;

// Запрос для определения общего количества

// секторов на компакт-диске

typedef struct _VolumeSize

{

  BYTE bControl;

  DWORD dwVolumeSize;

} VolumeSize;

#pragma pack()

// Прототипы функций

void GetCDLetters(BYTE *bLetters);

void CallCDDriver(void *rh, int nCDUnit);

int GetDiskInfo(int nCDUnit);

int GetDeviceStatus(int nCDUnit);

int GetVolumeSize(int nCDUnit);

int GetTrackInfo(int iTrack, int nCDUnit);

void delay(int ms);

// Регистры для вызова функции int86

union REGS rg;                     

// Количество установленных устройств чтения CD-ROM

int nCDUnits;

// Номер первого устройства чтения CD-ROM

int nCDStartUnit;

// Слово состояния после вызова драйвера CD-ROM

int iStatus;

// Информация о компакт-диске

DiskInfo     di;            

// Состояние устройства чтения CD-ROM

DeviceStatus ds;                    

// Объем компакт-диска

VolumeSize   vs;     

// Информация о дорожке

TrackInfo    ti;

BYTE bLetters[26];

// ---------------------------------------------------

// main

// Точка входа в программу

// ---------------------------------------------------

int main()

{

  int iRetry;

  int i, j;

 

  printf("CDINFO, (c) A. Frolov, 1997\n\n");

 

  // Проверяем, установлена ли программа MSCDEX

  rg.x.ax = 0x1500;

  rg.x.bx = 0;

  int86(0x2f, &rg, &rg);

  if(rg.x.bx == 0)

  {

    printf("MSCDEX is not installed\n");

    return -1;

  }

 

  else       

  {

    // Сохраняем общее количество устройств чтения CD-ROM



    nCDUnits = rg.x.bx;

   

    // Сохраняем номер первого такого устройства

    nCDStartUnit = rg.x.cx;

    // Определяем и отображаем вресию MSCDEX

    rg.x.ax = 0x150c;

    int86(0x2f, &rg, &rg);

    printf("MSCDEX version: %d.%d\n", rg.h.bh, rg.h.bl);

    // Отображаем количество найденных устройств чтения

    // CD-ROM и номер первого устройства

    printf("Found % d CD Unit, start unit: %c\n",

      nCDUnits, nCDStartUnit + 'A');

  }

  // Получаем массив номеров устройств чтения CD-ROM

  GetCDLetters(bLetters);

 

  // Отображаем обозначения всех устройств CD-ROM

  printf("CD-ROM letters: ");

  for(i = 0; i < nCDUnits; i++)

  {

    printf("%c ", bLetters[i] + 'A'); 

  }

  printf("\n");

  // Цикл по всем устройствам чтения CD-ROM

  for(i = 0; i < nCDUnits; i++)

  {

    // Определяем и отображаем состояние устройства

    iStatus = GetDeviceStatus(bLetters[i]);

    if(iStatus != 0x0100)

    {

      printf("GetDeviceStatus status: %04.4X\n", iStatus);

      printf("GetDeviceStatus failed\n");

      exit(1);              

    }

    printf("\nStatus of CD Drive %c: %08.8X\n",

      bLetters[i] + 'A', ds.dwParam);

    // Определяем и отображаем объем устройства

    iStatus = GetVolumeSize(bLetters[i]);

    if(iStatus != 0x0100)

    {

      printf("GetVolumeSize status: %04.4X\n", iStatus);

      printf("GetVolumeSize failed\n");

    }

    else

      printf("VolumeSize: %ld blocks\n", vs.dwVolumeSize);

    // Определяем и отображаем информацию о

    // компакт-диске

    iStatus = GetDiskInfo(bLetters[i]);

   

    // Делаем три попытки получения информации

    iRetry = 0;

    while(iStatus != 0x0100)

    {

      printf("GetDiskInfo status: %04.4X\n", iStatus);

   

      // Задержка длительностью 1 с

      delay(1000);

   

      iRetry++;



   

      if(iRetry == 3)

      {

        printf("GetDiskInfo failed\n");

        break;

      }

      iStatus = GetDiskInfo(bLetters[i]);

    }

 

    // Если удалось получить информацию о компакт-диске,

    // исследуем его дорожки

    if(iRetry != 3)

    {

      // Выводим номера дорожек

      printf("Tracks: (%d - %d) %d\n",

        di.bLowest, di.bHighest, di.dwTotal);

      // Цикл по всем дорожкам диска

      for(j = di.bLowest; j <= di.bHighest; j++)

      {

        // Получаем информацию о дорожке и отображаем ее

        GetTrackInfo(j, bLetters[i]);

        printf("track %d: location: %ld, info: %02.2X",

          j, ti.dwLoc, ti.bInfo);

     

        // Определяем тип дорожки - звуковая дорожка

        // или дорожка с данными

        if(ti.bInfo & 0x40)

          printf(" * digital");

        else

          printf(" * audio");

        // Определяем, разрашено ли копирование дорожки

        if(ti.bInfo & 0x20)

          printf(", copy permitted *\n");

        else

          printf(", copy prohibited *\n");

      }

    } 

  }

  return 0;

}

// ---------------------------------------------------

// GetDiskInfo

// Получение информации о компакт-диске

// ---------------------------------------------------

int GetDiskInfo(int nCDUnit)

{

  // Заголовок команды IOCTL Input

  IOCTL_Input cmd;

 

  // Очищаем заголовок

  memset(&cmd, 0, sizeof(IOCTL_Input ));

 

  // Заполняем заголовок

  cmd.rh.bSize    = 26;

  cmd.rh.bSubUnit = 0;

  cmd.rh.bCmd     = 3;

 

  cmd.bMediaDescriptor  = 0;

  cmd.lpTransferAddress = (DWORD)(void far *)&di;

  cmd.wDataSize         = 7;

  cmd.wStartSector      = 0;

  cmd.lpVolID           = (DWORD)(void far *)NULL;

 

  di.bControl = 10;

 

  // Вызываем драйвер

  CallCDDriver(&cmd, nCDUnit);

 

  return cmd.rh.wStatus;



// ---------------------------------------------------



// GetTrackInfo

// Получение информации о дорожке компакт-диска

// ---------------------------------------------------

int GetTrackInfo(int iTrack, int nCDUnit)

{

  IOCTL_Input cmd;

 

  memset(&cmd, 0, sizeof(IOCTL_Input ));

 

  cmd.rh.bSize    = 26;

  cmd.rh.bSubUnit = 0;

  cmd.rh.bCmd     = 3;

 

  cmd.bMediaDescriptor  = 0;

  cmd.lpTransferAddress = (DWORD)(void far *)&ti;

  cmd.wDataSize         = 7;

  cmd.wStartSector      = 0;

  cmd.lpVolID           = (DWORD)(void far *)NULL;

 

  ti.bControl = 11;

  ti.bTrack = iTrack;

 

  CallCDDriver(&cmd, nCDUnit);

 

  return cmd.rh.wStatus;



// ---------------------------------------------------

// GetDeviceStatus

// Определение состояния устройства чтения CD-ROM

// ---------------------------------------------------

int GetDeviceStatus(int nCDUnit)

{

  IOCTL_Input cmd;

 

  memset(&cmd, 0, sizeof(IOCTL_Input ));

 

  cmd.rh.bSize    = 26;

  cmd.rh.bSubUnit = 0;

  cmd.rh.bCmd     = 3;

 

  cmd.bMediaDescriptor  = 0;

  cmd.lpTransferAddress = (DWORD)(void far *)&ds;

  cmd.wDataSize         = 5;

  cmd.wStartSector      = 0;

  cmd.lpVolID           = (DWORD)(void far *)NULL;

 

  ds.bControl = 6;

 

  CallCDDriver(&cmd, nCDUnit);

  return cmd.rh.wStatus;



// ---------------------------------------------------

// GetVolumeSize

// Определение объема компакт-диска

// ---------------------------------------------------

int GetVolumeSize(int nCDUnit)

{

  IOCTL_Input cmd;

 

  memset(&cmd, 0, sizeof(IOCTL_Input ));

 

  cmd.rh.bSize    = 26;

  cmd.rh.bSubUnit = 0;

  cmd.rh.bCmd     = 3;

 

  cmd.bMediaDescriptor  = 0;

  cmd.lpTransferAddress = (DWORD)(void far *)&vs;

  cmd.wDataSize         = 5;

  cmd.wStartSector      = 0;

  cmd.lpVolID           = (DWORD)(void far *)NULL;

 

  vs.bControl = 8;

 

  CallCDDriver(&cmd, nCDUnit);

  return cmd.rh.wStatus;



// ---------------------------------------------------



// CallCDDriver

// Вызов драйвера компакт-диска

// ---------------------------------------------------

void CallCDDriver(void *rh, int nCDUnit)

{

  static union REGS rg;

  static struct SREGS srg;

 

  segread(&srg);

  rg.x.ax = 0x1510;

  rg.x.cx = nCDUnit;

  rg.x.bx = FP_OFF(rh); 

 

  int86x(0x2f, &rg, &rg, &srg);

}

// ---------------------------------------------------

// GetCDLetters

// Заполнение массива номерами установленных

// в системе устройств чтения компакт-диска

// ---------------------------------------------------

void GetCDLetters(BYTE *bLetters)

{

  static union REGS rg;

  static struct SREGS srg;

 

  segread(&srg);

  rg.x.ax = 0x150d;

  rg.x.bx = FP_OFF(bLetters); 

 

  int86x(0x2f, &rg, &rg, &srg);

}

// ---------------------------------------------------

// delay

// Формирование задержки по таймеру

// ---------------------------------------------------

void delay(int ms)

{

  int ticks;   

 

  ticks = ms / 55;

  _asm

  {

    push si

    mov  si, ticks

    mov  ah, 0

    int  1ah

    mov  bx, dx

    add  bx, si

delay_loop:

    int  1ah

    cmp  dx, bx

    jne  delay_loop

    pop  si

  }

}


Содержание раздела