home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / SETVOL.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  5KB  |  215 lines

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