📄 ioctl.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 + -