home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / ADISK.ZIP / ADISK.C next >
Encoding:
C/C++ Source or Header  |  1988-10-24  |  5.1 KB  |  139 lines

  1. /* ----------------------------------------------------------------------
  2.   Copyright (c) 1988 by Edward V Dong, All Rights Reserved.
  3.  
  4.   This is a code fragment, complete unto itself, to determine the total
  5.   number of sectors on a disk (any disk, hard or floppy), and do a simple
  6.   verification of the disk by simply reading each and every sector on the
  7.   disk.  
  8.  
  9.   Compiler: Turbo C version 1.5.  Should also work with version 1.0.
  10.                   Although I have not yet received TC ver 2.0,
  11.                   this should still work with ver 2.0.
  12.  
  13.   The key Turbo C routine used is "absread", summarized as follows.
  14.         int absread(drive,nsects,sectno,buffer)
  15.         int drive,int nsects,int sectno,void *buffer;
  16.         - reads disk absolute logical sectors
  17.         - drive  = 0(A), 1(B), etc
  18.         - nsects = # of sectors to read
  19.         - sectno = beginning logical sector number
  20.         - buffer = address of buffer
  21.         - returns 0 if OK; -1 on error; 'errno' = DOS error number
  22.         - needs dos.h
  23.    Logical sectors start with 0.  What the manual doesn't tell you is
  24.    that DOS (and Turbo C) doesn't really manage the stacks very well,
  25.    when doing "absread".  The parameters passed to 'absread' should be
  26.    global or static.
  27.   ----------------------------------------------------------------------- */
  28.  
  29. #include <stdio.h>        /* standard I/O library */
  30. #include <dos.h>        /* you need this to use 'absread' */
  31.  
  32. typedef struct xyyx    /* -- defines the structure of the boot sector -- */
  33. {    char    jump[3];    /* NEAR jump to start of boot code */
  34.     char    OEM[8];        /* OEM & version number */
  35.     int    SectSize;    /* bytes per sector */
  36.     char    ClustSize;    /* sectors per cluster */
  37.     int    ResSects;    /* reserved sectors (sectors before 1st FAT) */
  38.     char    FatCnt;        /* number of FATs */
  39.     int    RootSize;    /* max no of root directory entries (32 bytes) */
  40.     unsigned TotSecs;    /* total number of sectors in media */
  41.     char    Media;        /* media descriptor */
  42.     int    FatSize;    /* number of sectors in one FAT */
  43.     int    TrkSecs;    /* sectors per track/cylinder */
  44.     int    HeadCnt;    /* number of read/write heads */
  45.     int    HidnSecs;    /* number of hidden sectors */
  46. } BOOT, *BOOTPTR;
  47.  
  48. char    buffer[16384];        /* arbitrary buffer.  16K allows 1.2M disks */
  49. int    error, count;        /* parameters used with 'absread' */
  50. int    nsects;
  51. unsigned NumSect;        /* actual no. of sectors */
  52.  
  53. main()
  54. {
  55. char string[80], ch;
  56. int  drive;
  57. struct dfree dfree2;
  58. BOOTPTR    bootptr;
  59. static char *bootinfo[12] =
  60. {    "  OEM & Version Number: ",
  61.     "      Bytes Per Sector: ",
  62.     "   Sectors Per Cluster: ",
  63.     "      Reserved Sectors: ",
  64.     "                  FATs: ",
  65.     "  Max Root Dir Entries: ",
  66.     "         Total Sectors: ",
  67.     "      Media Descriptor: ",
  68.     "       Sectors Per FAT: ",
  69.     "     Sectors Per Track: ",
  70.     "      Read/Write Heads: ",
  71.     "        Hidden Sectors: "
  72. };
  73.  
  74. /* setup */
  75.     printf("Simple-Minded Diskette Test (c) 1988 by Edward V. Dong\n");
  76.     printf("Drive to test? (A, B, C...Z): "); 
  77.     ch = getche();
  78.     drive = toupper(ch) - 'A' + 1;
  79.     if ((drive < 1) || (drive > 26))     /* simple sanity check */
  80.         exit(1);
  81.  
  82. /* get number of sectors on disk via 'getdfree' */
  83.     getdfree(drive,&dfree2);
  84.     NumSect = dfree2.df_total * dfree2.df_sclus;
  85.     printf("\nNumber of sectors = %u\n",NumSect);
  86.  
  87. /* convert string into drive number */
  88.     drive -= 1;
  89.     absread(drive,1,0,buffer);
  90.     bootptr = (BOOTPTR)&buffer[0];
  91.  
  92. /* The total number of sectors should be higher than the number reported by
  93.    'getdfree', because 'getdfree' doesn't include boot sector, FAT sectors,
  94.    and DIR sectors.  */
  95.  
  96. /* We print out the disk information.  Interesting, but not useful. */
  97.     count = 0;
  98.     setmem(string,sizeof(string),0);
  99.     memcpy(string,bootptr->OEM,8);
  100.     printf("%s%s\n",bootinfo[count++],string);
  101.     printf("%s%d\n",bootinfo[count++],bootptr->SectSize);
  102.     printf("%s%d\n",bootinfo[count++],bootptr->ClustSize);
  103.     printf("%s%d\n",bootinfo[count++],bootptr->ResSects);
  104.     printf("%s%d\n",bootinfo[count++],bootptr->FatCnt);
  105.     printf("%s%d\n",bootinfo[count++],bootptr->RootSize);
  106.     printf("%s%u\n",bootinfo[count++],bootptr->TotSecs);
  107.     printf("%s%x\n",bootinfo[count++],bootptr->Media);
  108.     printf("%s%d\n",bootinfo[count++],bootptr->FatSize);
  109.     printf("%s%d\n",bootinfo[count++],bootptr->TrkSecs);
  110.     printf("%s%d\n",bootinfo[count++],bootptr->HeadCnt);
  111.     printf("%s%d\n",bootinfo[count++],bootptr->HidnSecs);
  112.     printf("\n");
  113.  
  114.     NumSect = bootptr->TotSecs;
  115.     count = 0;
  116.  
  117. /* This is where we read the disk, sector by sector.  The theory is that
  118.    if there is no read error for a sector, then it's probably OK.  A
  119.    rigorous test would be to write to that sector, verify that it's been
  120.    changed appropriately by reading it back, and restoring (if needed)
  121.    the original contents of the sector.  But this should get 90% of errors. */
  122.  
  123.     nsects = sizeof(buffer) / (bootptr->SectSize);
  124.     printf("Verify disk? (y/n) [N] ");
  125.     if (toupper(getch())!='Y') exit(0);
  126.  
  127. ReadDisk:
  128.     error = absread(drive,nsects,count,buffer);
  129.     if (!error)
  130.         printf("Reading sectors %05d-%05d...\r",count,count+nsects);
  131.         else if (count < (NumSect)) printf("\nBad sector %d\n",count);
  132.     if (count < (NumSect))
  133.     {    count += nsects;
  134.         if (count > (unsigned)(NumSect))
  135.             count = (unsigned)(NumSect) - 2;
  136.         goto ReadDisk;
  137.     }
  138. }
  139.