logo
несколько программ / bsp33

Программа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

}

}