⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdrom.cpp

📁 CD工具
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*C4*/
//****************************************************************
//	Author:	Jethro Wright, III 			TS :  1/20/1994 19:39
//	Date:	01/01/1994
//
//			cdrom.cpp :  cd-rom audio interface class for dos
//			and windows (as a dll) via mscdex....
//
//	History:
//		01/01/1994  jw3	 also sprach zarathustra....
//****************************************************************/


				//
				//	the principal purpose of this simple c++ utility
				//	framework is to provide the basis for a simple
				//	audio cd util under dos as well as supplement the
				//	multimedia cd audio facils under windows.  as of
				//	this writing, msoft hasn't provided a means of
				//	id'ing audio cds for windows.
				//	unfortunately, audio cd manufacuturers don't
				//	always include a upc on audio cds, which would
				//	provide an irrefutable and universal means of
				//	identifying cds.  therefore, this project has
				//	been undertaken w/ the hope that it'll be
				//	possible to use basic mscdex services to address
				//	this oversight. (famous last words....)  if
				//	nothing else, like myself, you'll learn about
				//	the basics of audio cd pgmg by digging into this
				//	code, as i knew nothing about it prior to this
				//	effort.
				//
				//	the code started life from an incomplete C pgm
				//	discovered in the bbs ether, by an anonymous
				//	author.  i've attempted to document some of the
				//	less obvious details of mscdex audio cd pgmg
				//	and complete the work, by providing a neat little
				//	shell pgm, which demonstrates the use of the classes.
				//	the pgm and classes are hereby committed to the
				//	public domain and you are free to use them, in
				//	whatever way you see fit.
				//
				//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				//
				//	IF YOU DO USE THIS CODE IN ANY PROJECT, YOU'RE
				//	COMPLETELY RESPONSIBLE FOR ALL DAMAGES INCURRED BY
				//	ITS USE.  IN OTHER WORDS, WHETHER MODIFIED OR NOT,
				//	I ACCEPT NO RESPONSIBILITY FOR ANY USE OF THE CODE
				//	OR THE PROGRAM PROVIDED WITH THIS KIT.
				//
				//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				//
				//	perhaps you may want to clean the code up a bit.
				//	personally, i've gotten tired of playing w/ it
				//	(under dos), but it's pretty modular as c++ class
				//	libs go, however there is room for improvement.
				//
				//	essentially, one simply instantiates a CDRom object
				//	it's off to the races, sending commands to the
				//	object and watching the results.  main.cpp illustrates
				//	a simple pgm that uses most, if not all, of the
				//	functionality of the class lib.  prior to instantiating
				//	the CDRom object, one must call CDRom::InitClass() to
				//	initialize the lib -> mscdex interface.  this fn
				//	returns the nbr of drives mscdex knows about.  had
				//	i been a little more fastidious, i might have added
				//	a fn to present a list of drives from which one 
				//	could choose a particular cdrom drive, if more than
				//	one unit were attached to a system.  since i don't
				//	have a means of testing this facil, it wasn't
				//	included, altho it would be very simple to write.
				//	who knows, as i'm writing this prior to setting up
				//	the final archive, such a routine *might* even make it
				//	into the kit....
				//
				//	also to be found in this kit is the mscdex 2.20
				//	spec.  this was the spec that was the basis of the
				//	work provided.  among other things, it has an rtf
				//	(microsoft word) version of the spec, which will
				//	make it possible to generate a pretty-printed
				//	copy of the document.
				//
				//	the principal CDRom mbr fns are generally very simple
				//	and could have been written as inline fns, but i
				//	wasn't sure how complex i'd want to make to the command
				//	dispatching when i started coding them.  again, for
				//	those who're a bit more anal retentive than myself,
				//	the src code is available for add'l modification.
				//
				//	commands are dispatched to the cdrom driver via
				//	an ioctl object.  the public mbr fns it supports
				//	are all related to cd audio operations. an ioctl
				//	object only needs to know which unit (to be precise,
				//	the sub-unit nbr) and the addresses of the cdrom
				//	driver's strategy and interrupt functions.  most
				//	of these operations could've been inlined, but
				//	besides my lack of enthusiasm to labor on this too
				//	much more, i also don't want to see the executable
				//	size grow anymore.  the exe is currently 33 kb, of
				//	which 90+ % is the library itself.  inlining more
				//	of the code wouldn't have helped the size situation
				//	and couldn't have done much (if anything) to improve
				//	performance.
				//
				//	things to look out for:  audio cd track timing isn't
				//	as perfect as one might expect.  that is, i've
				//	noted minor discrepencies bet what's written on
				//	cd liner and what's actually on the disc.  nothing
				//	more than two or three seconds per track and, in my
				//	opinion, not worth the bother of splitting hairs
				//	for code that *might* make things absolutely perfect.
				//	-  *no* error handling code.  since the consumer (the
				//	user of the classes) can interrogate any meaningful
				//	status information before initiating any cmd and
				//	bec the cmds are *so* straight-fwd, it was decided to
				//	leave out a safety net.  as noted elsewhere, it might
				//	not be a good idea to interrogate the toc while a play
				//	operation is underway, as this might interrupt the
				//	audio pgm, depending on the cd driver sware.  my
				//	limited testing hasn't encountered this prob, but a
				//	full-blown cd audio player app should have the option to
				//	deal w/ this contingency.  btw, any CDRom play fn will
				//	stop the current audio pgm, in order to start a new pgm.
				//	but this was dictated by the cdrom sub-system used to
				//	develop this code (a sony cdu-31a, a sub-system to be
				//	avoided, if at all possible.)
				//


#include		<stdio.h>
#include		<stdlib.h>
#include		<string.h>
#include		<conio.h>
#include	 	<dos.h>

#include		"types.h"				// needed for our basic data types
#include		"device.h"				// device driver and device cmd stuff
#include		"ioctl.hpp"				// to communicate w/ the drivers
										//	themselves
#include		"cdrom.hpp"


static union REGS 	inRegs, outRegs ;	// == used by the DOS interface
static struct SREGS	segRegs ;			//	routines
static DeviceList	deviceTable[ 26 ] ;	// == up to 26 cdrom drives supported


			//	the obligatory dummy initializations that c++ demands for
			//	static (class) mbr varbls....

int				CDRom::version = 0,
				CDRom::firstLetter = 0,
				CDRom::nbrOfDrives = 0 ;


//********************************************************
//
//		CDRom::CDRom  :-
//
//		prior to using this cstor the consumer must use
//		the static (class) InitClass mbr fn to setup the
//		internal list of cdrom drives, which will also
//		return the nbr of available drives.  as w/ all
//		operations covered by this system, there is *no*
//		error checking for procedural foul-ups, so let the
//		consumer beware....
//
//********************************************************/

CDRom::CDRom( int cdDrv ) : 
	cmdInterface( cdDrv, ( int ) deviceTable[ cdDrv ].subUnit,
		   		MK_FP( FP_SEG( deviceTable[ cdDrv ].deviceAddress ),
					   deviceTable[ cdDrv ].deviceAddress->deviceStrat ),
		   		MK_FP( FP_SEG( deviceTable[ cdDrv ].deviceAddress ),
		   			   deviceTable[ cdDrv ].deviceAddress->deviceEntry ) )
{

	//	this shudn't be needed, but let's keep it around anyway....
	cdDriveNbr = cdDrv ;
	GetDeviceStatus() ;					// find out if anything is happening

}


//********************************************************
//
//		CDRom::~CDRom  :-
//
//		don't really need an explicit dstor for the
//		moment....
//
//********************************************************/

CDRom::~CDRom()
{
}


//********************************************************
//
//		CDRom::InitClass  :-
//
//		this static (class) mbr fn is to be called prior
//		to instancing the 1st CDRom obj, in order to extract
//		the cdrom device table from dos/mscdex.  returns
//		the nbr of drives or zero if mscdex isn't loaded.
//
//********************************************************/

int		CDRom::InitClass( void ) 
{

	//	get number of cdrom drive letters from mscdex, via the dos multiplex
	//	interrupt
	inRegs.x.ax = 0x1500 ;
	inRegs.x.bx = 0 ;					// will be unmodified if mscdex isn't
	int86( 0x2f, &inRegs, &outRegs ) ;	//   loaded
	if( outRegs.x.bx == 0 ) {
		return( 0 ) ;
	}
	
	CDRom::nbrOfDrives = outRegs.x.bx ;
	CDRom::firstLetter = outRegs.x.cx ;

	//	get cdrom drive device list
	inRegs.x.ax = 0x1501 ;
	inRegs.x.bx = FP_OFF( ( DeviceList far * ) &deviceTable ) ;
	segRegs.es = FP_SEG( ( DeviceList far * ) &deviceTable ) ;
	int86x( 0x2f, &inRegs, &outRegs, &segRegs ) ;

	//	finally, get the mscdex version code, but it only works for
	//	mscdex 2.00 and above....
	inRegs.x.ax = 0x150C ;
	inRegs.x.bx = 0 ;
	int86x( 0x2f, &inRegs, &outRegs, &segRegs ) ;
	CDRom::version = outRegs.x.bx ;

	//	returns the nbr of drives or zero if this failed for some bizzare
	//	reason, bec mscdex is in fact loaded and it wouldn't be around if
	//	the cdrom device driver didn't load and normally they don't seem
	//	to load if a working drive isn't detected....
	return( ! outRegs.x.cflag ? CDRom::nbrOfDrives : 0 ) ;

}


//********************************************************
//
//		CDRom::GetUPC  :-
//
//		get the upc code from the disk, if it exists.
//		the function returns non-zero if found or
//		zero if not found.  the consumer can subsequently
//		interrogate the driver for the precise failure (per
//		the mscdex spec by calling GetErrorCode() immediately
//		after calling GetUPC()....
//		we really have no way of knowing if all of this works
//		bec there are apparently so few disks that possess the
//		code....
//
//********************************************************/

int		CDRom::GetUPC( DWORD far * upcCode )
{

	int			i ;
	WORD		st ;
	DWORD		tmp = 0 ;
	UPCCommand	upc ;

	memset( &upc, 0, sizeof( UPCCommand ) ) ;
	lastStatus = cmdInterface.GetUPC( ( struct UPCCommand far * ) &upc ) ;

	//	mscdex sez that the cmd will retn an sect not fnd err if the operation
	//	is supported by the driver, but the upc was missing/not found or
	//	an unknwn cmd if not supported
	st = GetErrorCode() ;
	if ( st == ERROR_UNKWN_CMD || st == ERROR_SECT_NOT_FND )
		return( 0 ) ;

	//	assumes the upc is a bcd value, which isn't entirely clear from the
	//	mscdex spec....
	for ( i = 0 ; i <= 7 ; i++ ) {
		tmp *= 10L ;
		tmp = ( ( upc.upc[ i ] >> 4 ) * 10 ) + ( upc.upc[ i ] & 0x0f ) + tmp ;
	}

	//	if the control byte is 0 or if the upc itself is 0, then no UPC was
	//	found, so synthesize the sector not fnd error
	if ( upc.controlAddress == 0 || tmp == 0L ) {
		st = lastStatus & 0xff00 ;
		lastStatus = st | ERROR_SECT_NOT_FND ;
		return 0 ;
	}

	*upcCode = tmp ;
	return( 1 ) ;

}


//********************************************************
//
//		CDRom::GetDeviceStatus  :-
//
//		get the most up-to-date device status from the
//		cd and return it to the caller....
//
//********************************************************/

DWORD	CDRom::GetDeviceStatus( void )
{

	DWORD	cdStatus ;
	lastStatus = cmdInterface.GetDeviceStatus( ( DWORD far * ) &cdStatus ) ;
	return cdStatus ;

}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -