home *** CD-ROM | disk | FTP | other *** search
- /* DRVRLIST.C
- list the device drivers in OS/2
- Art Rothstein, 1990
-
- we assume the first driver in the chain is NUL and is in the global data
- segment, and that the second driver (CON) is the same segment.
-
- cl -AL drvrlist.c (four-byte data pointers required for memchr)
- */
- #define INCL_DOSDEVICES
- #include <os2.h>
- #include <process.h>
- #include <stdio.h>
- #include <string.h>
- #include "devhlp.h"
-
- USHORT devhlp ;
-
- SEL MakeSel( SEL selValue)
- {
- extern USHORT devhlp ;
- REGS regs ;
- USHORT ret ;
-
- regs.dx = DevHlp_VirtToPhys ; // function requested
- regs.ds = selValue ; // selector
- regs.es = 0 ; // avoid trap
- regs.si = 0 ; // offset
- ret = DosDevIOCtl( ®s, ®s, 0x60, 128, devhlp) ;
- if ( ret != 0 || regs.flags.carry != 0)
- return 0 ;
- // physical address in ax:bx
- regs.cx = 0 ; // limit 65,535
- regs.dx = MAKEUSHORT( DevHlp_PhysToUVirt, UVirt_ReadWrite);
- regs.es = 0 ; // avoid trap
- ret = DosDevIOCtl( ®s, ®s, 0x60, 128, devhlp) ;
- if ( ret != 0 || regs.flags.carry != 0) // if error
- return 0 ;
- return regs.es ; // return the selector
- }
-
- BOOL ReleaseSel( SEL selValue)
- {
- extern USHORT devhlp ;
- REGS regs ;
- USHORT ret ;
-
- regs.ax = selValue ; // selector to free
- regs.dx = MAKEUSHORT( DevHlp_PhysToUVirt, UVirt_Release);
- regs.ds = 0 ; // safety
- regs.es = 0 ;
- ret = DosDevIOCtl( ®s, ®s, 0x60, 128, devhlp) ;
- if ( ret != 0 || regs.flags.carry != 0) // if error
- return FALSE ;
- return TRUE ; // successful return
- }
-
- void main( void)
- {
- USHORT usOffsetDriver
- , usBytesLeft; // in search for NUL device
- PCH pchGlobal ; // pointer to system global data
- static CHAR szDriverName[] = "DEVHLPXX" // device helper driver
- , szNullDriver[] = "NUL "; // first driver in system
-
- typedef struct _DDHEADER { // device driver header
- struct _DDHEADER * pddNext ; // chain to next driver
- USHORT fsAttribute ; // driver attributes
- USHORT usStrategyEntryOffset ;
- USHORT usIDCEntryOffset ; // inter device communication
- CHAR chName[ 8] ; // name for character devices
- USHORT usIDCEntrySegmentProt ;
- USHORT usIDCDataSegmentProt ;
- USHORT usIDCEntrySegmentReal ;
- USHORT usIDCDataSegmentReal ;
- } DDHEADER ;
- typedef DDHEADER * PDDHEADER ;
- PDDHEADER pddCurrent // current DCB
- , pddNext; // next DCB
- SEL selDriver ; // selector of DCB
-
- // open the DEVHLP device
- if ((devhlp = open(szDriverName, 0)) == -1) {
- puts( "Can't find DEVHLP.SYS") ;
- exit( 1) ;
- }
-
- // locate the first driver
- selDriver = 0x50 ; // global data segment
- usOffsetDriver = 0 ;
- usBytesLeft = 32000 ; // should be large enough
- pchGlobal = MAKEP( MakeSel( selDriver), usOffsetDriver) ;
- do {
- PCH pchMatch ;
-
- pchMatch = memchr( pchGlobal + 1, 'N', usBytesLeft); //look for first char
- if ( pchMatch == NULL) { // if no match
- ReleaseSel( SELECTOROF( pchGlobal)) ; // release the selector
- puts( "NUL driver not found") ; // and give up
- exit( 1) ;
- } // if no match
- // partial match
- usBytesLeft -= pchMatch - pchGlobal ; // reduce residual count
- pchGlobal = pchMatch ; // point to start of match
- } while ( memcmp( pchGlobal // break out if name matches
- , szNullDriver // exactly
- , sizeof szNullDriver - 1) != 0);
-
- // run the chain
- printf( " Address Name\n") ; // column headings
- for ( usOffsetDriver = OFFSETOF( pchGlobal) - 0x0a // back up to DCB start
- , pddCurrent = ( PDDHEADER) ( pchGlobal - 0x0a)
- , selDriver = SELECTOROF( pddCurrent->pddNext) // selector of next DCB
- ; ; ) {
- printf( "%4X:%04X ", selDriver, usOffsetDriver);
- if ( ( pddCurrent->fsAttribute & 0x8000) == 0) // if block driver
- printf( "Block device, %d logical units\n"
- , pddCurrent->chName[ 0]); // number of units
- else // if character driver
- printf( "%-8.8s\n", pddCurrent->chName);
- selDriver = SELECTOROF( pddCurrent->pddNext) ; // point to next DCB
- usOffsetDriver = OFFSETOF( pddCurrent->pddNext) ;
- if ( usOffsetDriver == 0xffff) // if end of chain
- break ; // we are done
- pddNext = MAKEP( MakeSel( selDriver), usOffsetDriver) ;
- ReleaseSel( SELECTOROF( pddCurrent)) ; // free previous DCB
- pddCurrent = pddNext ; // age the pointer
- } // loop once for each device driver
-
- // release the last selector
- ReleaseSel( SELECTOROF( pddCurrent)) ;
-
- exit( 0) ;
- }
-