home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / SNIP9404.ZIP / SETVOL.C < prev    next >
C/C++ Source or Header  |  1994-04-03  |  5KB  |  223 lines

  1. /*
  2. **  SETVOL.C - set, change, or kill a disk volume label
  3. **
  4. **  public domain demo by Bob Stout
  5. **  DOS 5 enhancements suggested by Keith Beedle
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12. #include <dos.h>
  13. #include <io.h>
  14. #include "portable.h"         /* Also in SNIPPETS     */
  15.  
  16. #define NUL '\0'
  17.  
  18. #if defined(__TURBOC__)
  19.  #pragma option -a-
  20.  #include <dir.h>
  21.  #include <io.h>
  22.  #define _A_VOLID FA_LABEL
  23.  #define _far far
  24. #else
  25.  #include <direct.h>
  26.  #if defined(__ZTC__)
  27.   #pragma ZTC align 1
  28.  #else /* MSC/QC/WATCOM/METAWARE */
  29.   #pragma pack(1)
  30.  #endif
  31.  struct fcb {
  32.          char   fcb_drive;
  33.          char   fcb_name[8];
  34.          char   fcb_ext[3];
  35.          short  fcb_curblk;
  36.          short  fcb_recsize;
  37.          long   fcb_filsize;
  38.          short  fcb_date;
  39.          char   fcb_resv[10];
  40.          char   fcb_currec;
  41.          long   fcb_random;
  42.  };
  43.  
  44.  struct xfcb {
  45.          char           xfcb_flag;
  46.          char           xfcb_resv[5];
  47.          char           xfcb_attr;
  48.          struct fcb     xfcb_fcb;
  49.  };
  50. #endif
  51.  
  52. #include "dos5boot.h"   /* SNIPPETS file with DOS 5 boot record structure  */
  53.  
  54. /*
  55. **  NOTE: The following use functions in four other SNIPPETS files,
  56. **        ABSDISK.ASM, ABSDISKC.C, DRVALID.C, and PUSHDIR.C
  57. */
  58.  
  59. int AbsDiskRead(unsigned short, size_t, size_t, void *);
  60. int AbsDiskWrite(unsigned short, size_t, size_t, void *);
  61. int getdrv(void);
  62. int PushDir(char *);
  63. int PopDir(void);
  64.  
  65. /*
  66. **  Erase an existing volume label
  67. */
  68.  
  69. void vol_kill(char *fname)
  70. {
  71.       union REGS regs;
  72.       struct SREGS sregs;
  73.       struct xfcb buf;
  74.  
  75.       /* Parse the filename into an FCB               */
  76.  
  77.       segread(&sregs);
  78.       regs.h.ah = 0x29;
  79.       regs.h.al = 0;
  80.       regs.x.si = (unsigned)fname;
  81.       regs.x.di = (unsigned)&buf.xfcb_fcb;
  82.       sregs.es  = sregs.ds;
  83.       intdosx(®s, ®s, &sregs);
  84.  
  85.       /* Volume labels require extended FCB's         */
  86.  
  87.       buf.xfcb_flag = 0xff;
  88.       buf.xfcb_attr = _A_VOLID;
  89.  
  90.       /* Delete the old label                         */
  91.  
  92.       regs.h.ah = 0x13;
  93.       regs.x.dx = (unsigned)&buf;
  94.       intdos(®s, ®s);
  95. }
  96.  
  97. /*
  98. **  Create a new volume label
  99. */
  100.  
  101. void setvol(char *label)
  102. {
  103.       char new_label[13];     /* name + ext + '.' + NUL       */
  104.       struct xfcb buf;
  105.       union REGS regs;
  106.       struct SREGS sregs;
  107.       const char pattern[] = "????????";
  108.       char _far *dta;
  109.  
  110.       /*
  111.       **  Change to root directory.
  112.       */
  113.       
  114.       PushDir("\\");
  115.  
  116.       /* If drive is already labeled, remove it               */
  117.  
  118.       segread(&sregs);
  119.       regs.h.ah = 0x2f;
  120.       intdosx(®s, ®s, &sregs);
  121.       dta = MK_FP(sregs.es, regs.x.bx);
  122.       
  123.       buf.xfcb_flag = 0xff;
  124.       buf.xfcb_attr = _A_VOLID;
  125.       buf.xfcb_fcb.fcb_drive = 0;
  126.       memcpy(buf.xfcb_fcb.fcb_name, pattern, 8);
  127.       memcpy(buf.xfcb_fcb.fcb_ext, pattern, 3);
  128.  
  129.       regs.h.ah = 0x11;
  130.       regs.x.dx = (unsigned)&buf;
  131.       intdos(®s, ®s);
  132.  
  133.       if (0 == regs.h.al)
  134.       {
  135.             int i;
  136.             char oldlabel[13], _far *p, *q;
  137.  
  138.             for (i = 0, p = dta + 8, q =oldlabel; i < 8; ++i, ++p, ++q)
  139.             {
  140.                   *q = *p;
  141.             }
  142.             *q++ = '.';
  143.             for (i = 0, p = dta + 16; i < 3; ++i, ++p, ++q)
  144.             {
  145.                   *q = *p;
  146.             }
  147.             vol_kill(oldlabel);
  148.       }
  149.  
  150.       strcpy(new_label, label);
  151.       if (8 < strlen(label))
  152.       {
  153.             new_label[8] = '.';
  154.             strcpy(&new_label[9], &label[8]);
  155.       }
  156.  
  157.       /* Parse the filename into an FCB               */
  158.  
  159.       segread(&sregs);
  160.       regs.h.ah = 0x29;
  161.       regs.h.al = 0;
  162.       regs.x.si = (unsigned)new_label;
  163.       regs.x.di = (unsigned)&buf.xfcb_fcb;
  164.       sregs.es  = sregs.ds;
  165.       intdosx(®s, ®s, &sregs);
  166.  
  167.       /* Volume labels require extended FCB's         */
  168.  
  169.       buf.xfcb_flag = 0xff;
  170.       buf.xfcb_attr = _A_VOLID;
  171.  
  172.       /* Create the new label                         */
  173.  
  174.       regs.h.ah = 0x16;
  175.       regs.x.dx = (unsigned)&buf;
  176.       intdos(®s, ®s);
  177.  
  178.       /* Close the new label                          */
  179.  
  180.       regs.h.ah = 0x10;
  181.       regs.x.dx = (unsigned)&buf;
  182.       intdos(®s, ®s);
  183.  
  184.       /*
  185.       **  For DOS 5.0 replace the boot record too.
  186.       */
  187.  
  188.       if(_osmajor > 3)
  189.       {
  190.             int index, drive = getdrv();
  191.             B_REC boot_record;
  192.  
  193.             AbsDiskRead(drive, 1, 0, &boot_record);
  194.             if(0 == strcmp(boot_record.bsOemName, "MSDOS5.0"))
  195.             {
  196.                   index = 0;
  197.                   while (NUL != label[index])
  198.                   {
  199.                         boot_record.bsVolumeLabel[index] = label[index];
  200.                         index++;
  201.                   }
  202.                   for(index; index < 11; index++)
  203.                         boot_record.bsVolumeLabel[index] = 0x20;
  204.                   AbsDiskWrite(drive, 1, 0, &boot_record);
  205.             }
  206.       }
  207.       PopDir();
  208. }
  209.  
  210. #ifdef TEST
  211.  
  212. void main(int argc, char *argv[])
  213. {
  214.       if (2 > argc)
  215.       {
  216.             puts("\aUsage: SETVOL new_name");
  217.             abort();
  218.       }
  219.       setvol(argv[1]);
  220. }
  221.  
  222. #endif
  223.