Listing 6 chandle.cpp adds character-device specific capability to class IoctlHandle
#include <string.h> #include "chandle.h" struct { char *dname; int dtype; } static dcat[]= { { "COM", 1 },{ "AUX", 1 }, { "CON", 3 },{ "LPT", 5 }, { "PRN", 5 },{ 0, 0 } }; static int getcat( const char *dname ) { for( int i = 0; dcat[i].dname; i++ ) if( strnicmp( dcat[i].dname, dname, 3 ) == 0 ) break; return dcat[i].dtype; } charHandle::charHandle( const char *device ) : IoctlHandle( device ) { _cat = getcat( device ); } charHandle *charHandle::Init(const char *device) { charHandle *obj = new charHandle( device ); if( obj->_handle == -1 || //bad handle obj->isFile() || //can't be a file obj->_cat == 0 ) { //unknown device delete obj; return (charHandle *) 0; } return obj; } void charHandle::handle_info( int handle, unsigned info ) { /* Set device information word */ _iregs.x.dx = info & 0x00ff; //dh must be 0 _iregs.x.bx = handle; int21_44h(set_handle_info); } unsigned charHandle::ioctl_data( ioctl_cmd fn, unsigned count, void *buffer ) { /* Send/receive I/O Control data to char device */ _iregs.x.bx = _handle; _iregs.x.cx = count; //#bytes to read/write _iregs.x.dx = FP_OFF( (void far *) buffer ); _sregs.ds = FP_SEG( (void far *) buffer ); int21_44h(fn); //function number (2/3) return _oregs.x.ax; //#bytes xfered } int charHandle::char_ioctl( char_cmd minor_code, void *param_block ) { /* Access DOS int21h/44h/0Ch for the current * handle and device category, generic ioctl for * character devices. */ _iregs.x.bx = _handle; _iregs.h.ch = (char) _cat; _iregs.h.cl = (char) minor_code; _iregs.x.dx = FP_OFF( (void far *) param_block ); _sregs.ds = FP_SEG( (void far *) param_block ); int21_44h( gen_ioctl_char ); return_dos_error ? _oregs.x.ax: 0; } int charHandle::sendIoctl( unsigned *count, void *data ) { /* Send ioctl data to current device. */ *count = ioctl_data( send_ioctl_char, *count, data ); return _dos_error ? _oregs.x.ax : 0; } int charHandle::readIoctl( unsigned *count, void *data ) { *count = ioctl_data( read_ioctl_char, *count, data ); return _dos_error ? _oregs.x.ax : 0; } unsigned charHandle::busyCount( void ) { /* Return LPTx device busy count, 0 on error. */ unsigned count_buf; if( _cat != 5 ) return 0; //error char_itoctl ( get_iter count, (void *) &count_buf ); return _dos_error ? 0 : count_buf; } unsigned charHandle::busyCount( unsigned count ) { /* Set LPTx device busy count. Return new count, * or 0 on error........ */ if( _cat != 5 ) return 0; //error char_ioctl( set_iter_count, (void *) &count); return busyCount(); } int charHandle::getANSIdata( struct ANSIdata *dis) { /* Get config data for an ANSI display driver. */ if( _cat != 3 ) return -1; //error dis->info = 0; dis->block_length = 14; char_ioctl( get_display_mode, (void *) dis); return _dos_error ? -1 : 0; } int charHandle::setANSIdata( struct ANSidata *dis) { /* Set config data for an ANSI display driver. */ if( _cat != 3 ) return -1; //error dis->info = 0; dis->block_length = 14; char_ioctl( set_display_mode, (void *) dis); return _dos_error ? -1 : 0; } // End of File