home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.os.msdos.programmer
- Path: 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
-
- 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
-