home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega CD-ROM 1
/
megacd_rom_1.zip
/
megacd_rom_1
/
MAGAZINE
/
PROGJOUR
/
PJ_6_6.ZIP
/
DDI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-10-18
|
11KB
|
494 lines
/*
* 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) ;
}