summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/setvol.c
diff options
context:
space:
mode:
Diffstat (limited to 'reference/C/CONTRIB/SNIP/setvol.c')
-rwxr-xr-xreference/C/CONTRIB/SNIP/setvol.c222
1 files changed, 222 insertions, 0 deletions
diff --git a/reference/C/CONTRIB/SNIP/setvol.c b/reference/C/CONTRIB/SNIP/setvol.c
new file mode 100755
index 0000000..d31483b
--- /dev/null
+++ b/reference/C/CONTRIB/SNIP/setvol.c
@@ -0,0 +1,222 @@
+/*
+** SETVOL.C - set, change, or kill a disk volume label
+**
+** public domain demo by Bob Stout
+** DOS 5 enhancements suggested by Keith Beedle
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <dos.h>
+#include <io.h>
+#include "portable.h" /* Also in SNIPPETS */
+
+#define NUL '\0'
+
+#if defined(__TURBOC__)
+ #pragma option -a-
+ #include <dir.h>
+ #include <io.h>
+ #define _A_VOLID FA_LABEL
+ #define _far far
+#else
+ #include <direct.h>
+ #if defined(__ZTC__)
+ #pragma ZTC align 1
+ #else /* MSC/QC/WATCOM/METAWARE */
+ #pragma pack(1)
+ #endif
+ struct fcb {
+ char fcb_drive;
+ char fcb_name[8];
+ char fcb_ext[3];
+ short fcb_curblk;
+ short fcb_recsize;
+ long fcb_filsize;
+ short fcb_date;
+ char fcb_resv[10];
+ char fcb_currec;
+ long fcb_random;
+ };
+
+ struct xfcb {
+ char xfcb_flag;
+ char xfcb_resv[5];
+ char xfcb_attr;
+ struct fcb xfcb_fcb;
+ };
+#endif
+
+#include "dos5boot.h" /* SNIPPETS file with DOS 5 boot record structure */
+
+/*
+** NOTE: The following use functions in four other SNIPPETS files,
+** ABSDISK.ASM, ABSDISKC.C, DRVALID.C, and PUSHDIR.C
+*/
+
+int AbsDiskRead(unsigned short, size_t, size_t, void *);
+int AbsDiskWrite(unsigned short, size_t, size_t, void *);
+int getdrv(void);
+int PushDir(char *);
+int PopDir(void);
+
+/*
+** Erase an existing volume label
+*/
+
+void vol_kill(char *fname)
+{
+ union REGS regs;
+ struct SREGS sregs;
+ struct xfcb buf;
+
+ /* Parse the filename into an FCB */
+
+ segread(&sregs);
+ regs.h.ah = 0x29;
+ regs.h.al = 0;
+ regs.x.si = (unsigned)fname;
+ regs.x.di = (unsigned)&buf.xfcb_fcb;
+ sregs.es = sregs.ds;
+ intdosx(&regs, &regs, &sregs);
+
+ /* Volume labels require extended FCB's */
+
+ buf.xfcb_flag = 0xff;
+ buf.xfcb_attr = _A_VOLID;
+
+ /* Delete the old label */
+
+ regs.h.ah = 0x13;
+ regs.x.dx = (unsigned)&buf;
+ intdos(&regs, &regs);
+}
+
+/*
+** Create a new volume label
+*/
+
+void setvol(char *label)
+{
+ char new_label[13]; /* name + ext + '.' + NUL */
+ struct xfcb buf;
+ union REGS regs;
+ struct SREGS sregs;
+ const char pattern[] = "????????";
+ char _far *dta;
+
+ /*
+ ** Change to root directory.
+ */
+
+ PushDir("\\");
+
+ /* If drive is already labeled, remove it */
+
+ segread(&sregs);
+ regs.h.ah = 0x2f;
+ intdosx(&regs, &regs, &sregs);
+ dta = MK_FP(sregs.es, regs.x.bx);
+
+ buf.xfcb_flag = 0xff;
+ buf.xfcb_attr = _A_VOLID;
+ buf.xfcb_fcb.fcb_drive = 0;
+ memcpy(buf.xfcb_fcb.fcb_name, pattern, 8);
+ memcpy(buf.xfcb_fcb.fcb_ext, pattern, 3);
+
+ regs.h.ah = 0x11;
+ regs.x.dx = (unsigned)&buf;
+ intdos(&regs, &regs);
+
+ if (0 == regs.h.al)
+ {
+ int i;
+ char oldlabel[13], _far *p, *q;
+
+ for (i = 0, p = dta + 8, q =oldlabel; i < 8; ++i, ++p, ++q)
+ {
+ *q = *p;
+ }
+ *q++ = '.';
+ for (i = 0, p = dta + 16; i < 3; ++i, ++p, ++q)
+ {
+ *q = *p;
+ }
+ vol_kill(oldlabel);
+ }
+
+ strcpy(new_label, label);
+ if (8 < strlen(label))
+ {
+ new_label[8] = '.';
+ strcpy(&new_label[9], &label[8]);
+ }
+
+ /* Parse the filename into an FCB */
+
+ segread(&sregs);
+ regs.h.ah = 0x29;
+ regs.h.al = 0;
+ regs.x.si = (unsigned)new_label;
+ regs.x.di = (unsigned)&buf.xfcb_fcb;
+ sregs.es = sregs.ds;
+ intdosx(&regs, &regs, &sregs);
+
+ /* Volume labels require extended FCB's */
+
+ buf.xfcb_flag = 0xff;
+ buf.xfcb_attr = _A_VOLID;
+
+ /* Create the new label */
+
+ regs.h.ah = 0x16;
+ regs.x.dx = (unsigned)&buf;
+ intdos(&regs, &regs);
+
+ /* Close the new label */
+
+ regs.h.ah = 0x10;
+ regs.x.dx = (unsigned)&buf;
+ intdos(&regs, &regs);
+
+ /*
+ ** For DOS 5.0 replace the boot record too.
+ */
+
+ if(_osmajor > 3)
+ {
+ int index, drive = getdrv();
+ B_REC boot_record;
+
+ AbsDiskRead(drive, 1, 0, &boot_record);
+ if(0 == strcmp(boot_record.bsOemName, "MSDOS5.0"))
+ {
+ index = 0;
+ while (NUL != label[index])
+ {
+ boot_record.bsVolumeLabel[index] = label[index];
+ index++;
+ }
+ for(index; index < 11; index++)
+ boot_record.bsVolumeLabel[index] = 0x20;
+ AbsDiskWrite(drive, 1, 0, &boot_record);
+ }
+ }
+ PopDir();
+}
+
+#ifdef TEST
+
+void main(int argc, char *argv[])
+{
+ if (2 > argc)
+ {
+ puts("\aUsage: SETVOL new_name");
+ abort();
+ }
+ setvol(argv[1]);
+}
+
+#endif