home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / QFORMAT.ZIP / QFORMAT.C next >
Text File  |  1992-07-26  |  11KB  |  349 lines

  1. /* qformat.c  version 1.0  July 26, 1992
  2.  * Quick format of diskette drives - 3.5" and 5.25"
  3.  * Compiled with IBM C Set/2 compiler
  4.  * NOTE: This program will not format 2.88MB diskettes
  5.  * Program runs in OS/2 Win or OS/2 FS modes
  6.  * usage: qformat <drive>:
  7.  *
  8.  * Author - John K. Gotwals     (317)494-2564 phone
  9.  *                              (317)496-1212 fax
  10.  *                              gotwals@vm.cc.purdue.edu
  11.  *                              jgotwals (bix)
  12.  *
  13.  * Copyright John K. Gotwals 1992
  14. */
  15.  
  16. #define INCL_BASE
  17.  
  18. #include <os2.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21.  
  22. #define MAX_SECTORS 18
  23. #define SECTOR_SIZE 512
  24. #define DIR_ENTRY_SIZE 32
  25.  
  26. typedef _Packed struct
  27.     {
  28.     USHORT bytesSector;
  29.     UCHAR  sectorsCluster;
  30.     USHORT reservedSectors;
  31.     UCHAR  numFats;
  32.     USHORT rootDirEntries;
  33.     USHORT totallSectors;
  34.     UCHAR  mediaDescriptor;
  35.     USHORT sectorsFat;
  36.     USHORT sectorsTrack;
  37.     USHORT numHeads;
  38.     ULONG  hiddenSectors;
  39.     ULONG  largeTotalSectors;
  40.     CHAR   reserved[6];
  41.     USHORT numCylinders;
  42.     UCHAR  type;
  43.     USHORT attributes;
  44.     } diskDevice;
  45.  
  46. typedef _Packed struct
  47.     {
  48.     UCHAR  command;
  49.     USHORT head;
  50.     USHORT cylinder;
  51.     USHORT firstSector;
  52.     USHORT numSectors;
  53.     CHAR   table[MAX_SECTORS * 4];
  54.     } diskTrack;
  55.  
  56. typedef struct
  57.     {
  58.     UCHAR command;
  59.     UCHAR drive;
  60.     } parmList;
  61.  
  62.  
  63. void readTrack(char *buffer, int cyl, int head, int firstSector,
  64.     int sectors);
  65. void writeTrack(char *buffer, int cyl, int head, int firstSector,
  66.     int sectors);
  67. void format(int fatInit);
  68. void mediaError(int errorNum);
  69. void error(char *msg, int error);
  70.  
  71. diskDevice device;
  72. ULONG deviceLength = sizeof(device);
  73.  
  74. diskTrack track;
  75. ULONG trackLength  = sizeof(track);
  76.  
  77. parmList parm;
  78. ULONG parmLength   = sizeof(parm);
  79.  
  80. char DriveName[3] = "x:";
  81. HFILE FileHandle;
  82. ULONG Action;
  83.  
  84. char trackBuffer[MAX_SECTORS * SECTOR_SIZE];
  85.  
  86. int main(int argc, char **argv)
  87.     {
  88.     int i;
  89.     APIRET rc;      /* return code */
  90. /*
  91.  * Check command line for drive letter
  92. */
  93.     if (argc > 1)
  94.         DriveName[0] = tolower(*argv[1]);
  95.     else
  96.         {
  97.         printf("usage: qformat drive:\n");
  98.         return 0;
  99.         }
  100. /*
  101.  * Do not procede if improper device!
  102. */
  103.     if ((DriveName[0] != 'a') && (DriveName[0] != 'b'))
  104.         error("Only a: or b: can be formated!", 1);
  105. /*
  106.  * Get access to the device
  107. */
  108.     rc = DosOpen(
  109.         DriveName,
  110.         &FileHandle,
  111.         &Action,
  112.         0L,                 /* file size     */
  113.         FILE_NORMAL,        /* file attribue */
  114.         OPEN_ACTION_OPEN_IF_EXISTS,
  115.         OPEN_FLAGS_DASD             |
  116.         OPEN_FLAGS_WRITE_THROUGH    |
  117.         OPEN_FLAGS_NOINHERIT        |
  118.         OPEN_SHARE_DENYREADWRITE    |
  119.         OPEN_ACCESS_READWRITE,
  120.         0L);                /* no extended attributes */
  121.     if (rc != NO_ERROR)
  122.         error("DosOpen", rc);
  123. /*
  124.  * Lock the drive
  125. */
  126.     rc = DosDevIOCtl(
  127.         FileHandle,
  128.         0x08L,                  /* device catagory          */
  129.         0x00L,                  /* function code            */
  130.         0,                      /* parameter packet address */
  131.         0,                      /* parm list length         */
  132.         0,                      /* parm list length address */
  133.         0,                      /* address of extended BPB  */
  134.         0,                      /* length of extended BPB   */
  135.         0);                     /* address of ext BPB len   */
  136.     if (rc != NO_ERROR)
  137.         error("DosDevIOCtl lock", rc);
  138. /*
  139.  * Get the device parameters
  140.  * (BPB = BIOS Parameter Block)
  141. */
  142.     parm.command = 1;           /* return the BPB for the media
  143.                                    currently in the drive   */
  144.     rc = DosDevIOCtl(
  145.         FileHandle,
  146.         0x08L,                  /* device catagory          */
  147.         0x63L,                  /* function code            */
  148.         &parm,                  /* parameter packet address */
  149.         parmLength,             /* parm list length         */
  150.         &parmLength,
  151.         &device,                /* address of extended BPB  */
  152.         deviceLength,           /* length of extended BPB   */
  153.         &deviceLength);
  154.  
  155.     if (rc != NO_ERROR)
  156.         error("DosDevIOCtl get BPB", rc);
  157. /*
  158.  * Build the parameter packet
  159.  * (see page 18-154 of Physical Device Driver Reference)
  160. */
  161.     memset(&track, 0, sizeof(track));
  162.     for (i = 0; i < MAX_SECTORS; i++)
  163.         {
  164.         track.table[4 * i] = i + 1;
  165.         track.table[4 * i + 3] = 2;     /* 512 bytes per sector */
  166.         }
  167. /*
  168.  * get permission before formatting
  169. */
  170.     printf("\nPress enter to format drive %s\n", DriveName);
  171.     while (getchar() != '\n');
  172. /*
  173.  * Determine type of diskette and carry out format
  174. */
  175.     memset(trackBuffer, 0, sizeof(trackBuffer));
  176.     switch (device.mediaDescriptor)
  177.         {
  178.         case 0xf9:
  179.             if (device.type == 2  ||  device.type == 7)
  180.                 format(0xfffff9);       /* 720KB */
  181.             else if (device.type == 1)
  182.                 format(0xfffff9);       /* 1.2MB */
  183.             else
  184.                 mediaError(1);
  185.             break;
  186.         case 0xfd:
  187.             if (device.type == 1  ||  device.type == 0)
  188.                 format(0xfffffd);       /* 360KB */
  189.             else
  190.                 mediaError(2);
  191.             break;
  192.         case 0xf0:
  193.             if (device.type == 7)
  194.                 format(0xfffff0);       /* 1.44MB */
  195.             else
  196.                 mediaError(3);
  197.             break;
  198.         default:
  199.             mediaError(4);
  200.             break;
  201.         }
  202. /*
  203.  * Redetermine the media
  204. */
  205.     rc = DosDevIOCtl(
  206.         FileHandle,
  207.         0x08L,                  /* device catagory          */
  208.         0x02L,                  /* function code            */
  209.         0,                      /* parameter packet address */
  210.         0,                      /* parm list length         */
  211.         0,                      /* parm list length address */
  212.         0,                      /* address of extended BPB  */
  213.         0,                      /* length of extended BPB   */
  214.         0);                     /* address of ext BPB len   */
  215.     if (rc != NO_ERROR)
  216.         error("DosDevIOCtl redetermine", rc);
  217. /*
  218.  * Unlock the media
  219. */
  220.     rc = DosDevIOCtl(
  221.         FileHandle,
  222.         0x08L,                  /* device catagory          */
  223.         0x01L,                  /* function code            */
  224.         0,                      /* parameter packet address */
  225.         0,                      /* parm list length         */
  226.         0,                      /* parm list length address */
  227.         0,                      /* address of extended BPB  */
  228.         0,                      /* length of extended BPB   */
  229.         0);                     /* address of ext BPB len   */
  230.     if (rc != NO_ERROR)
  231.         error("DosDevIOCtl unlock", rc);
  232. /*
  233.  * Close the device
  234. */
  235.     rc = DosClose(FileHandle);
  236.     if (rc != NO_ERROR)
  237.         error("DosClose", rc);
  238.     return 0;
  239.     }
  240.  
  241. /*
  242.  * format() zeros FATs and root directory and
  243.  * initializes both FATs
  244. */
  245. void format(int fatInit)
  246.     {
  247.     int zeroSectorsTrack0;
  248.     int zeroSectorsTrack1;
  249.     int fatSectors;
  250.     int dirSectors;
  251.     int *ptrackBuffer = (int *)trackBuffer;
  252.  
  253.     fatSectors = device.numFats * device.sectorsFat;
  254.     dirSectors = (device.rootDirEntries * DIR_ENTRY_SIZE) / SECTOR_SIZE;
  255.     zeroSectorsTrack0 = device.sectorsTrack - 1;
  256.     zeroSectorsTrack1 = fatSectors + dirSectors - zeroSectorsTrack0;
  257.     writeTrack(trackBuffer, 0, 0, 1, zeroSectorsTrack0);
  258.     writeTrack(trackBuffer, 0, 1, 0, zeroSectorsTrack1);
  259.     *ptrackBuffer = fatInit;
  260.     writeTrack(trackBuffer, 0, 0, 1, 1);  /* 1st FAT */
  261.     writeTrack(trackBuffer, 0, 0, 1 + device.sectorsFat, 1);
  262.     return;
  263.     }
  264.  
  265. #ifdef TESTING
  266. /*
  267.  * readTrack() can read up to 1 track (for testing purposes)
  268. */
  269. void readTrack(char *buffer, int cyl, int head, int firstSector,
  270.     int sectors)
  271.     {
  272.     APIRET rc;
  273.     ULONG bufferLength = SECTOR_SIZE * sectors;
  274.  
  275.     track.command = 1;  /* track layout starts with sector 1 and */
  276.                         /* contains only consecutive sectors     */
  277.     track.head = head;
  278.     track.cylinder = cyl;
  279.     track.firstSector = firstSector;
  280.     track.numSectors = sectors;
  281.     rc = DosDevIOCtl(
  282.         FileHandle,
  283.         0x08L,          /* device catagory          */
  284.         0x64L,          /* function code            */
  285.         &track,         /* parameter packet address */
  286.         trackLength,    /* parameter packet length  */
  287.         &trackLength,
  288.         buffer,         /* data packet address      */
  289.         bufferLength,
  290.         &bufferLength);
  291.     if (rc != NO_ERROR)
  292.         error("DosDevIOCtl during track read", rc);
  293.     return;
  294.     }
  295.  
  296. #endif
  297.  
  298. /*
  299.  * writeTrack() can write up to 1 track
  300. */
  301. void writeTrack(char *buffer, int cyl, int head, int firstSector,
  302.     int sectors)
  303.     {
  304.     APIRET rc;
  305.     ULONG bufferLength = SECTOR_SIZE * sectors;
  306.  
  307.     track.command = 1;  /* track layout starts with sector 1 and */
  308.                         /* contains only consecutive sectors     */
  309.     track.head = head;
  310.     track.cylinder = cyl;
  311.     track.firstSector = firstSector;
  312.     track.numSectors = sectors;
  313.     rc = DosDevIOCtl(
  314.         FileHandle,
  315.         0x08L,          /* device catagory          */
  316.         0x44L,          /* function code            */
  317.         &track,         /* parameter packet address */
  318.         trackLength,    /* parameter packet length  */
  319.         &trackLength,
  320.         buffer,         /* data packet address      */
  321.         bufferLength,
  322.         &bufferLength);
  323.     if (rc != NO_ERROR)
  324.         error("DosDevIOCtl during track write", rc);
  325.     return;
  326.     }
  327.  
  328. /*
  329.  * mediaError() - Display error message and info about diskette.
  330.  *                Then exit() program.
  331. */
  332. void mediaError(int errorNum)
  333.     {
  334.     fprintf(stderr, "Error %d: Can not quick format diskette.\n",
  335.         errorNum);
  336.     fprintf(stderr, "drive type = %d  media descriptor = %d\n",
  337.         (int)device.type, (int)device.mediaDescriptor);
  338.     exit(errorNum);
  339.     }
  340.  
  341. /*
  342.  * error() - Display message, error number and exit program
  343. */
  344. void error(char *msg, int error)
  345.     {
  346.     fprintf(stderr, "Error %d - %s\n", error, msg);
  347.     exit(error);
  348.     }
  349.