From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/SNIP/setvol.c | 222 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100755 reference/C/CONTRIB/SNIP/setvol.c (limited to 'reference/C/CONTRIB/SNIP/setvol.c') 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 +#include +#include +#include +#include +#include +#include "portable.h" /* Also in SNIPPETS */ + +#define NUL '\0' + +#if defined(__TURBOC__) + #pragma option -a- + #include + #include + #define _A_VOLID FA_LABEL + #define _far far +#else + #include + #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(®s, ®s, &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(®s, ®s); +} + +/* +** 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(®s, ®s, &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(®s, ®s); + + 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(®s, ®s, &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(®s, ®s); + + /* Close the new label */ + + regs.h.ah = 0x10; + regs.x.dx = (unsigned)&buf; + intdos(®s, ®s); + + /* + ** 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 -- cgit v1.2.3-54-g00ecf