home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 14
/
CD_ASCQ_14_0694.iso
/
maj
/
653
/
setvol.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-03
|
5KB
|
223 lines
/*
** 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