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

📄 ioctl.cpp

📁 CD工具
💻 CPP
字号:
/*C4*/
//****************************************************************
//	Author:	Jethro Wright, III 			TS :  1/18/1994 12:06
//	Date:	01/01/1994
//
//			ioctl.cpp :  ioctl-oriented cmd interface to mscdex
//			primarily used to control audio cds
//
//	History:
//		01/01/1994  jw3	also sprach zarathustra....
//****************************************************************/


#include		<stdio.h>
#include		<stdlib.h>
#include		<dos.h>
#include		<memory.h>

#include		"types.h"
#include		"device.h"
#include		"ioctl.hpp"


			//	device driver/ioctl command codes

#define		IOCTL_READ		(3)
#define 	IOCTL_WRITE		(12)
#define		PLAY_AUDIO		(132)
#define		STOP_AUDIO		(133)
#define		RESUME_AUDIO	(136)


			//	ioctl_read sub-commands

enum {
	GET_DVC_STATUS = 6,
	GET_DISK_INFO = 10,
	GET_TRACK_INFO,
	GET_QCHNL_INFO,
	GET_SUBCNHL_DATA,
	GET_UPC = 14,
	GET_PLAY_STATUS,
} ;


			//	ioctl_write sub-commands

enum {
	EJECT_DISK,
	LOCK_DOOR,
	RESET_DISK,
	AUDIO_CONTROL,
	CLOSE_TRAY = 5
} ;


//********************************************************
//
//		IOCTL::IOCTL  :-
//
//		initialize the cmd interface for this cdrom, by
//		storing the device's unit and sub-unit nbr and
//		the device's strategy and interrupt fn ptrs, for
//		future reference.
//
//********************************************************/

IOCTL::IOCTL( int cdUnitNbr, int cdSubUnitNbr, VFP cdDevStrategyFn,
			  VFP cdDevIntrFn )
{

	memset( &theRequest, 0, sizeof( theRequest ) ) ;
	unitNbr = cdUnitNbr ; subUnitNbr = cdSubUnitNbr ;
	devStrategy = cdDevStrategyFn ; devInterrupt = cdDevIntrFn ;

}


//********************************************************
//
//		IOCTL::~IOCTL  :-
//
//		don't know that we'll need a dstor, but it's here
//		anyway....
//
//********************************************************/

IOCTL::~IOCTL()
{
}


//********************************************************
//
//		IOCTL::GetDeviceStatus  :-
//
//		get the most up-to-date status from the cdrom's
//		device driver....
//
//********************************************************/

WORD	IOCTL::GetDeviceStatus( DWORD far * cdStatus )
{

	DeviceStatusCmd	devStatus ;

	devStatus.command = GET_DVC_STATUS ;
	Setup( IOCTL_READ, ( VFP ) &devStatus, sizeof( DeviceStatusCmd ) ) ;
	DoCmd() ;							// perform, i say !

	//	return the desired data back to the caller....
	*cdStatus = devStatus.deviceStatus ;
	return theRequest.rqh.status ;

}


//********************************************************
//
//		IOCTL::LockDoor  :-
//
//		lock the drive door depending on the flag word
//		specified by the consumer....
//
//********************************************************/

WORD	IOCTL::LockDoor( Boolean fLock )
{

	DoorLockCmd	lockCmd ;

	lockCmd.command = LOCK_DOOR ;
	lockCmd.lockCode = fLock ;
	Setup( IOCTL_WRITE, ( VFP ) &lockCmd, sizeof( DoorLockCmd ) ) ;
	DoCmd() ;							// perform, i say !
	return theRequest.rqh.status ;

}


//********************************************************
//
//		IOCTL::CloseTray  :-
//
//		this is one of a series of functions that is
//		not always supported on all cdrom drives, but is
//		provided anyway and will close the motorized tray
//		of a cdrom drive, if drive is capable of doing so....
//
//********************************************************/

WORD	IOCTL::CloseTray( void )
{

	CloseTrayCmd	closeCmd ;

	closeCmd.command = CLOSE_TRAY ;
	Setup( IOCTL_WRITE, ( VFP ) &closeCmd, sizeof( CloseTrayCmd ) ) ;
	DoCmd() ;							// nike it !
	return theRequest.rqh.status ;

}


//********************************************************
//
//		IOCTL::EjectDisk  :-
//
//		eject the disk from the drive, if supported by the
//		device....
//
//********************************************************/

WORD	IOCTL::EjectDisk( void )
{

	EjectCommand	ejectCmd ;

	ejectCmd.command = EJECT_DISK ;
	Setup( IOCTL_WRITE, ( VFP ) &ejectCmd, sizeof( EjectCommand ) ) ;
	DoCmd() ;							// nike it !
	return theRequest.rqh.status ;

}


//********************************************************
//
//		IOCTL::ResetDisk  :-
//
//		reset the cdrom and (presumably) the device driver
//		as well....
//
//********************************************************/

WORD	IOCTL::ResetDisk( void )
{

	ResetCommand	resetCmd ;

	resetCmd.command = RESET_DISK ;
	Setup( IOCTL_WRITE, ( VFP ) &resetCmd, sizeof( ResetCommand ) ) ;
	DoCmd() ;
	return theRequest.rqh.status ;

}


//********************************************************
//
//		IOCTL::GetDiskInfo  :-
//
//		get the disk's pertinent info (starting & ending
//		track nbrs and the address of the lead-out track)
//
//********************************************************/

WORD	IOCTL::GetDiskInfo( struct DiskInfoCmd far * dskInfo )
{

	dskInfo->command = GET_DISK_INFO ;
	Setup( IOCTL_READ, ( VFP ) dskInfo, sizeof( DiskInfoCmd ) ) ;
	DoCmd() ;
	return theRequest.rqh.status ;

}


//********************************************************
//
//		IOCTL::GetTrackInfo  :-
//
//		get the information corresponding to a particular
//		track....
//
//********************************************************/

WORD	IOCTL::GetTrackInfo( struct TrackInfoCmd far * trackInfo )
{

	trackInfo->command = GET_TRACK_INFO ;
	Setup( IOCTL_READ, ( VFP ) trackInfo, sizeof( TrackInfoCmd ) ) ;
	DoCmd() ;
	return theRequest.rqh.status ;

}


//********************************************************
//
//		IOCTL::GetQInfo  :-
//
//		retrieve the current q-channel info for the disk
//		(track nbr, pos into the track and disk, etc)
//
//********************************************************/

WORD	IOCTL::GetQInfo( struct QChannelInfoCmd far * qInfo )
{

	qInfo->command = GET_QCHNL_INFO ;
	Setup( IOCTL_READ, ( VFP ) qInfo, sizeof( QChannelInfoCmd ) ) ;
	DoCmd() ;
	return theRequest.rqh.status ;

}


//********************************************************
//
//		IOCTL::Play  :-
//
//		play a span of audio usg the specified addressing
//		mode.  the play audio fn reqs a different procedure
//		from the rest of the other operations bec it uses
//		a different layout for the ioctl cmd packet, so
//		we can't use the Setup() mbr fn....
//
//********************************************************/

WORD	IOCTL::Play( DWORD stAddr, DWORD nSects, BYTE addrMode )
{

	PlayCommand	* playCmd = ( PlayCommand * ) ( ( void * ) &theRequest ) ;

	playCmd->rqh.len = sizeof( PlayCommand ) ;
	playCmd->rqh.unit = subUnitNbr ;
	playCmd->rqh.status = 0 ;
	playCmd->rqh.command = PLAY_AUDIO ;
	playCmd->startAddr = stAddr ;
	playCmd->nbrSects = nSects ;
	playCmd->addressMode = addrMode ;
	DoCmd() ;
	return playCmd->rqh.status ;

}


//********************************************************
//
//		IOCTL::Stop  :-
//
//		stop/resume the audio pgm based on the incoming
//		flag....
//
//********************************************************/

WORD	IOCTL::Stop( Boolean fStop )
{

	WORD	cmd ;

	if ( fStop )
		cmd = STOP_AUDIO ;
	else cmd = RESUME_AUDIO ;

	Setup( cmd, ( VFP ) NULL, 0 ) ;
	DoCmd() ;
	return theRequest.rqh.status ;

}


//********************************************************
//
//		IOCTL::GetUPC  :-
//
//		get the upc code from the disk....
//
//********************************************************/

WORD	IOCTL::GetUPC( struct UPCCommand far * upcData )
{

	upcData->command = GET_UPC ;
	Setup( IOCTL_READ, ( VFP ) upcData, sizeof( UPCCommand ) ) ;
	DoCmd() ;
	return theRequest.rqh.status ;

}


//********************************************************
//
//		IOCTL::GetPlayStatus  :-
//
//		get the current play status from the disk (is the
//		disk pgm paused & starting/ending addresses of the
//		curr audio pgm)....
//
//********************************************************/

WORD	IOCTL::GetPlayStatus( struct PlayStatusCmd far * playStatus )
{

	playStatus->command = GET_PLAY_STATUS ;
	playStatus->startAddress = playStatus->endAddress = 0L ;
	Setup( IOCTL_READ, ( VFP ) playStatus, sizeof( PlayStatusCmd ) ) ;
	DoCmd() ;
	return theRequest.rqh.status ;

}


/*****************************************************************

	IOCTL private mbr fns

*****************************************************************/


//********************************************************
//
//		IOCTL::DoCmd  :-
//
//		execute the device driver command specified in
//		theRequest, by calling the device driver's
//		strategy fn, then following it up w/ a call to
//		the interrupt fn.
//
//********************************************************/

void	IOCTL::DoCmd( void )
{

	VFP			rqh = ( VFP ) &theRequest ;
	VFP			devStrat = devStrategy, devIntr = devInterrupt ;

	_asm {
		mov		es, word ptr rqh+2
		mov		bx, word ptr rqh
		call	dword ptr devStrat		// setup the desired operation
		call	dword ptr devIntr		// now do it !
	}
	return ;

}

⌨️ 快捷键说明

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