1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 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(®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
|