home *** CD-ROM | disk | FTP | other *** search
- /*
- * DDI - Device information program
- *
- * Written By: Steve Rodgers
- * Conception: 5-4-86
- *
- * Copyright (C) 1987 Steve Rodgers
- *
- *
- * Functional Description
- * ----------------------
- *
- * This program displays information about installable device drivers
- * loaded under DOS 2.0 or later. If the command is typed without any
- * arguments, a summary will be printed which shows the order of the devices
- * in the chain. If a device name is typed following the command, detailed
- * information pertinent to that device will be displayed. This program
- * works with either character or block devices as arguments.
- *
- *
- * Revision History
- * ----------------
- *
- * First Release Version 0.1 released 5-7-86
- * Second Release Version 0.2 released 3-12-87
- * Third Release Version 1.0 released 2-18-88
- *
- * Compilation instructions
- * ------------------------
- *
- * Use the Microsoft C compiler version 3.00 or later.
- * Compile with the -Zp switch.
- *
- * Dependencies
- * ------------
- *
- * This module requires the following include files:
- *
- * stdio.h
- * dos.h
- * string.h
- *
- *
- * Linking instructions
- * --------------------
- *
- * Use the Microsoft linker version 3.00 or later.
- *
- * LINK COMMAND LINE : link di;
- *
- *
- *
- */
-
- #include <stdio.h>
- #include <dos.h>
- #include <string.h>
-
- /*
- * Device attribute definitions
- */
-
- #define CHARACTER_DEVICE 0x8000
- #define IOCTL_SUPPORT 0x4000
- #define NON_IBM_FORMAT 0x2000
- #define OPEN_CLOSE_SUPPORT 0x800
- #define IS_CLOCK 8
- #define IS_NUL 4
- #define IS_STDIN 2
- #define IS_STDOUT 1
-
- /*
- * Structure definitions
- *
- *
- * Device header
- */
-
- struct DEV_HDR
- {
- struct DEV_HDR far *next_hdr ; /* pointer next device header */
- unsigned int attribute ; /* attribute bits */
- unsigned int strategy ; /* strategy offset */
- unsigned int interruptx ; /* interrupt offset */
- unsigned char name[8] ; /* device name */
- } ;
-
- /*
- * Disk Parameter Block - Returned by DOS function 32H
- */
-
- struct DPB
- {
- unsigned char ad ; /* current assigned disk */
- unsigned char alt_ad ; /* alternate assigned disk */
- unsigned int bps ; /* bytes per sector */
- unsigned char last_sic ; /* max sector addr in a cluster */
- unsigned char last_head ; /* max useable head address */
- unsigned int rs ; /* total reserved sectors */
- unsigned char cf ; /* copies of the FAT */
- unsigned int d ; /* max root directory entries */
- unsigned int fus ; /* first useable sector */
- unsigned int tccplusone ; /* total clusters available + 1 */
- unsigned char spf ; /* sectors per FAT */
- unsigned int fds ; /* first directory sector */
- struct DEV_HDR far *dda ; /* device driver address */
- unsigned char md ; /* media discriptor */
- struct DISK_DPB far *next_dpb ; /* address of next dpb in chain */
- unsigned int cwd_cluster ; /* cluster of CWD (DOS 2.x only) */
- unsigned char cwd_string[64] ; /* CWD string (DOS 2.x only) */
- } ;
-
- /*
- * Function declarations
- */
-
- struct DPB far *disk_dpb() ;
- struct DEV_HDR far *device_chain() ;
-
- /*
- * Static Declarations
- */
-
- union REGS ir,or ;
- struct SREGS sr ;
-
- int is_disk = 0 ;
-
- /*
- * Attribute bit table
- */
-
- int attr_bit_masks[] = {CHARACTER_DEVICE,IOCTL_SUPPORT,NON_IBM_FORMAT,
- OPEN_CLOSE_SUPPORT,IS_CLOCK,IS_NUL,IS_STDIN,IS_STDOUT};
-
- /*
- * Global pointer variables
- */
-
- struct DEV_HDR far *current_device, far *previous_device ;
- struct DPB far *current_dpb ;
-
- /*
- * Global device type counters
- */
-
- int block_drivers = 0,character_drivers = 0 ;
-
- /*
- * Function: main()
- */
-
- main(argc,argv)
- int argc ;
- char *argv[] ;
- {
- int i ;
- char *device_name ;
-
- printf("\nDDI - Device Driver Information Program\n") ;
- printf("Version 1.0 (2-18-88) Copyright (C) 1988 Steve Rodgers\n\n") ;
-
- if(argc < 2) /* if no argument, print the device list */
- {
- list_devices() ;
- exit(0) ;
- }
-
- if((device_name = strupr(strdup(argv[1]))) == NULL)
- abort() ;
- print_single_device(device_name) ;
- }
-
- /*
- * Function: print_single_device()
- *
- * Print information for a single device.
- */
-
- print_single_device(device_name)
- char device_name[] ;
- {
- int i ;
-
- /*
- *
- * Function: get_device() ;
- *
- * Get pointer for a specific device.
- * If it doesn't exist print an error message.
- */
-
- get_device(device_name) ;
- if(current_device == NULL)
- {
- printf("No such device: %s\n",device_name) ;
- exit(1) ;
- }
-
- /*
- * Print the device address, type, and name.
- */
-
- print_device_columns() ;
- print_device_info(current_device) ;
-
- /*
- * Print the detailed information for the device
- */
-
- printf("\n") ;
- printf(" A T T R I B U T E S\n") ;
- printf("------------------------------------------------------------------------\n") ;
- printf("| CHAR | IOCTL | NONIBM | OPNCLS | STDCLK | NULDEV | STDOUT | STDIN |\n") ;
- for(i = 0 ; i < 8 ; i++)
- {
- printf(" ") ;
- if((attr_bit_masks[i] & current_device->attribute))
- printf("yes ") ;
- else
- printf("no ") ;
- }
- printf("\n\n") ;
- printf("Strategy entry point\t\t: %04X:%04X\n",
- FP_SEG(current_device),
- current_device->strategy) ;
-
- printf("Interrupt entry point\t\t: %04X:%04X\n",
- FP_SEG(current_device),
- current_device->interruptx) ;
-
- /*
- * Return to DOS
- */
-
- exit(0) ;
- }
-
- /*
- * Function: list_devices()
- *
- * Print a summary of all devices in the chain.
- */
-
- list_devices()
- {
-
- /*
- * Get the head of the device list.
- * If this isn't possible, print an error message and exit
- */
-
- if((current_device = device_chain()) == NULL)
- no_device_chain() ;
-
- /*
- * Print the column information
- */
-
- print_device_columns() ;
-
- /*
- * Follow the chain until a -1 is reached
- */
-
- while(FP_OFF(current_device) != -1)
- {
- print_device_info(current_device) ;
- current_device = current_device->next_hdr ;
- }
- printf("\nSystem has %d character drivers, and %d block drivers\n",
- character_drivers,block_drivers) ;
- }
-
- /*
- * Function: get_device()
- *
- * Find character or block device driver.
- * Fill in current device pointer, previous device pointer, and
- * current DPB if block device.
- *
- */
-
- get_device(d)
- char d[] ;
- {
- int i ;
- char device_string[9] ;
-
- current_device = NULL ;
- current_dpb = NULL ;
- if(strlen(d) > 8)
- return ;
-
- /*
- * If there is a colon in the second character position, user
- * is requesting information about a block device.
- */
-
- if(d[1] != ':')
- {
-
- /*
- * The name specified is probably a character device.
- * If a colon follows the device name, delete it from the string.
- */
-
- if(d[strlen(d) - 1] == ':') /* kill colon at end of device name */
- d[strlen(d) - 1] = 0 ;
- /*
- * Attempt to get the pointer to the first device in the chain.
- * if it comes back NULL, the user probably did not install the
- * trace device driver.
- */
-
- if((current_device = device_chain()) == NULL)
- no_device_chain() ; /* no device chain available */
-
- /*
- * Trace the device chain until device name matches a
- * device in the chain
- */
-
- while(FP_OFF(current_device) != -1)
- {
- for(i = 0 ; i < 8 ; i++)
- device_string[i] = current_device->name[i] ;
- device_string[8] = 0 ;
- if(!strncmp(device_string,d,strlen(d)))
- if((strlen(d) == 8) ||
- (current_device->name[strlen(d)] == ' '))
- return ;
- previous_device = current_device ;
- current_device = current_device->next_hdr ;
- }
-
- /*
- * If no match, set the current device to NULL and return
- */
-
- current_device = NULL ;
- return ;
- }
-
- /*
- * A colon was found in the second character position of the device
- * name, check for a valid block device.
- */
-
- else
- is_disk = 1 ; /* set a flag to signify a disk device */
-
- if(strlen(d) > 2) /* length must be less than or equal to 2 */
- return ;
-
- /*
- * Get the disk DPB for the drive specified.
- * If the disk doesn't exist, the current_dpb pointer will be
- * set to NULL, print a message and exit if this is the case.
- */
-
- if((current_dpb = disk_dpb(d[0] - 0x40)) == NULL)
- no_disk_dpb() ;
- current_device = current_dpb->dda ;
- previous_device = NULL ;
- return ;
- }
-
- /*
- * Function: print_device_columns()
- *
- * This function prints the headings and columns when listing
- * all device drivers.
- */
-
- print_device_columns()
- {
- printf("Base Address\t\t\tType\t\t\tName/Units\n") ;
- printf("------------\t\t\t----\t\t\t----------\n") ;
- }
-
- /*
- * Function: print_device_info()
- *
- * This function prints detailed information for a specific device.
- */
-
- print_device_info(device)
- struct DEV_HDR far *device ;
- {
- char device_string[9] ;
- int i ;
- printf("%04X:%04X\t\t\t",FP_SEG(device),FP_OFF(device)) ; /* print base address */
- if(device->attribute & CHARACTER_DEVICE)
- {
- ++character_drivers ;
- for(i = 0 ; i < 8 ; i++)
- device_string[i] = device->name[i] ; /* copy it into local data segment */
- device_string[8] = 0 ;
- printf("Char\t\t\t%s\n",device_string) ; /* print "Char" and name */
- }
- else
- {
- ++block_drivers ;
- printf("Block\t\t\t%u units\n",(int) device->name[0]) ;/* block dev.*/
- }
- }
-
- /*
- *
- * Function: disk_dpb()
- *
- * Return the address of the Disk Parameter Block (DPB) for the
- * drive specified. This DOS function is undocumented in current
- * DOS documentation.
- */
-
- struct DPB far *disk_dpb(drive)
- int drive ;
- {
- char far *dsk_dpb ;
-
- ir.x.ax = 0x3200 ; /* Function call 32H */
- ir.h.dl = drive ;
- intdosx(&ir,&or,&sr) ;
- if(++or.h.al == 0)
- return (char far *) NULL ;
- FP_SEG(dsk_dpb) = sr.ds ;
- FP_OFF(dsk_dpb) = or.x.bx ;
- return (struct DPB far *) dsk_dpb ;
- }
-
- /*
- * Function: device_chain()
- *
- * Return the address of the first device in the device
- * chain.
- */
-
-
- struct DEV_HDR far *device_chain()
- {
- struct DEV_HDR far *dev_chain ;
- auto char far *search_ptr = (char far *) 0x00600000 ; /* start search at 0060:0000 */
- static char *nuldev = "NUL " ;
- unsigned int x,i ;
-
- for(x = 0, i = 0 ; x < 65535 ; x++)
- {
- if(*search_ptr == *nuldev) /* if first character matches, check others*/
- {
- for(i = 0 ; i < 8 ; i++)
- {
- if(*(search_ptr + i) != nuldev[i])
- break ;
- }
- if(i == 8) /* if i = 8 then the NUL device has been found */
- break ;
- }
- search_ptr++ ;
- }
- if(x == 0)
- return NULL ;
-
- search_ptr -= 10 ; /* get to device header */
- return (struct DEV_HDR far *) search_ptr ;
- }
-
- /*
- *
- * Function: no_device_chain()
- *
- * Print message "Can't find device chain" and exit
- */
-
- no_device_chain()
- {
- fprintf(stderr,"Can't find device chain\n") ;
- exit(1) ;
- }
-
- /*
- *
- * Function: no_disk_dpb()
- *
- * Print message "Can't get DPB - Possible invalid drive\n" and exit
- */
-
- no_disk_dpb()
- {
- fprintf(stderr,"Can't get DPB - Possible invalid drive\n") ;
- exit(1) ;
- }
-