Article View: comp.os.msdos.programmer
Article #6537Two volume labels per disk!
From: Stan Brown
Date: Fri, 18 Dec 1992 08:07
Date: Fri, 18 Dec 1992 08:07
137 lines
7080 bytes
7080 bytes
In my relentless pursuit of quality in the FAQ list, I recently thought
I found a simpler answer to the question on reading and setting the
volume label: DOS function 69, introduced in DOS 4.0. However, I was
surprised to discover that though I could change _a_ volume label using
that function, _the_ volume label displayed by theDIR, VOL, or LABEL
command was unchanged.
Following is the altered text of that portion of the FAQ, based on my
experiments. I would welcome feedback, either suggestions for improving
clarity or (gulp!) factual corrections. Please email, don't post, so
that I'm sure not to miss your comments. Please make your comments as
specific as possible.
Q408. How can I read, create, change, or delete the volume label?
In DOS 5.0 (and, I believe, in 4.0 as well), there are actually two
volume labels: one, the traditional one, is an entry in the root
directory of the disk and the other is in the boot record along with
the serial number (see next Q). The DIR and VOL commands report the
traditional label; the LABEL command reports the traditional one but
changes both of them.
In DOS 4.0 and later, use INT 21 function 69 to access the boot
record's serial number and volume label together; see the next Q.
But more likely by "volume label" you mean the traditional one, the
one that DIR and VOL display. Though it's a directory entry in the
root directory, you can't change it using the modern DOS file-access
functions (3C, 41, 43); instead, use the old FCB-oriented directory
functions. Specifically, you need to allocate a 64-byte buffer and
a 41- byte extended FCB (file control block). Call INT 21 AH=1A to
find out whether there is a volume label. If there is, AL returns 0
and you can change the label using DOS function 17 or delete it
using DOS function 13. If there's no volume label, function 1A will
return FF and you can create a label via function 16. Important
points to notice are that ? wildcards are allowed but * are not;
the volume label must be space filled not null-terminated.
The following MSC 7.0 code worked for me in DOS 5.0; the functions
it uses have been around since DOS 2.0. The function parameter is 0
for the current disk, 1 for a:, 2 for b:, etc. It doesn't matter
what your current directory is; these functions always search the
root directory for volume labels. (I didn't try to change the
volume label of any networked drives.)
// Requires DOS.H, STDIO.H, STRING.H
void vollabel(unsigned char drivenum) {
static unsigned char extfcb[41], dta[64], status, *newlabel;
int chars_got = 0;
#define DOS(buff,func) __asm { __asm mov dx,offset buff \
__asm mov ax,seg buff __asm push ds __asm mov ds,ax \
__asm mov ah,func __asm int 21h __asm pop ds \
__asm mov status,al }
#define getlabel(buff,prompt) newlabel = buff; \
memset(newlabel,' ',11); printf(prompt); \
scanf("%11[^\n]%n", newlabel, &chars_got); \
if (chars_got < 11) newlabel[chars_got] = ' ';
// Set up the 64-byte transfer area used by function 1A.
DOS(dta, 1Ah)
// Set up an extended FCB and search for the volume label.
memset(extfcb, 0, sizeof extfcb);
extfcb[0] = 0xFF; // denotes extended FCB
extfcb[6] = 8; // volume-label attribute bit
extfcb[7] = drivenum; // 1=A, 2=B, etc.; 0=current drive
memset(&extfcb[8], '?', 11); // wildcard *.*
DOS(extfcb,11h)
if (status == 0) { // DTA contains volume label's FCB
printf("volume label is %11.11s\n", &dta[8]);
getlabel(&dta[0x18], "new label (\"delete\" to delete): ");
if (chars_got == 0)
printf("label not changed\n");
else if (strncmp(newlabel,"delete ",11) == 0) {
DOS(dta,13h)
printf(status ? "label failed\n" : "label deleted\n");
}
else { // user wants to change label
DOS(dta,17h)
printf(status ? "label failed\n" : "label changed\n");
}
}
else { // no volume label was found
printf("disk has no volume label.\n");
getlabel(&extfcb[8], "new label (<Enter> for none): ");
if (chars_got > 0) {
DOS(extfcb,16h)
printf(status ? "label failed\n" : "label created\n");
}
}
} // end function vollabel
Q409. How can I get the disk serial number?
Use INT 21. AX=6900 gets the serial number; AX=6901 sets it. See
Ralf Brown's interrupt list, or page 496 of the July 1992 {PC
Magazine}, for details.
This function also gets and sets the volume label, but it's the
volume label in the boot record, not the volume label that a DIR
command displays. See the preceding Q.
I tested the following MSC 7.0 code under DOS 5.0. The function
parameter is 0 for the current disk, 1 for a:, 2 for b:, etc.
// Requires DOS.H, STDIO.H, STRING.H
void labserial(unsigned char drivenum) {
static unsigned char bpb[0x19], *label = &bpb[6];
static unsigned *serial = (unsigned *)(&bpb[2]);
int chars_got = 0;
#define DOS(func) __asm { __asm mov bl,drivenum \
__asm mov dx,offset bpb __asm mov ax,seg bpb __asm push ds \
__asm mov ds,ax __asm mov ax,func __asm int 21h __asm pop ds }
// Read the disk information.
DOS(6900h)
printf("serial number: %04X-%04X\n", serial[1], serial[0]);
printf("volume label: [%-.11s]\n", label);
// Get the new label and serial number.
memset(label, ' ', 11);
printf("new label (\"NO NAME\" to delete): ");
scanf("%11[^\n]%n", label, &chars_got);
if (chars_got == 0)
printf("label not changed\n");
else {
if (chars_got < 11)
label[chars_got] = ' ';
printf("new serial number (8 hex digits): ");
scanf("%lx", (unsigned long *)serial);
DOS(6901h)
}
} // end function labserial
--
Stan Brown, Oak Road Systems brown@Ncoast.ORG
"There are no good guys. There's bad guys and worse guys. The best one
can hope for is to defend the bad against the worse."
-- {Almost History} by Christopher Bram
Technical Details
Message-ID:
<BzG3x4.Jv6@NCoast.ORG>Path:
arc1-ca.pugleaf.net!sparky!uunet!spool.mu.edu!agate!usenet.ins.cwru.edu!ncoast!brownShow Full Headers
Complete Article Headers
Newsgroups: comp.os.msdos.programmer Path: arc1-ca.pugleaf.net!sparky!uunet!spool.mu.edu!agate!usenet.ins.cwru.edu!ncoast!brown From: brown@NCoast.ORG (Stan Brown) Subject: Two volume labels per disk! Organization: Oak Road Systems, Cleveland Ohio USA Date: Fri, 18 Dec 1992 08:07:51 GMT Message-ID: <BzG3x4.Jv6@NCoast.ORG> Followup-To: sender Lines: 137