home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / os / msdos / programm / 11501 < prev    next >
Encoding:
Text File  |  1992-12-21  |  6.8 KB  |  148 lines

  1. Newsgroups: comp.os.msdos.programmer
  2. Path: sparky!uunet!spool.mu.edu!agate!usenet.ins.cwru.edu!ncoast!brown
  3. From: brown@NCoast.ORG (Stan Brown)
  4. Subject: Two volume labels per disk!
  5. Organization: Oak Road Systems, Cleveland Ohio USA
  6. Date: Fri, 18 Dec 1992 08:07:51 GMT
  7. Message-ID: <BzG3x4.Jv6@NCoast.ORG>
  8. Followup-To: sender
  9. Lines: 137
  10.  
  11. In my relentless pursuit of quality in the FAQ list, I recently thought
  12. I found a simpler answer to the question on reading and setting the
  13. volume label: DOS function 69, introduced in DOS 4.0.  However, I was
  14. surprised to discover that though I could change _a_ volume label using
  15. that function, _the_ volume label displayed by theDIR, VOL, or LABEL
  16. command was unchanged.
  17.  
  18. Following is the altered text of that portion of the FAQ, based on my
  19. experiments.  I would welcome feedback, either suggestions for improving
  20. clarity or (gulp!) factual corrections.  Please email, don't post, so
  21. that I'm sure not to miss your comments.  Please make your comments as
  22. specific as possible.
  23.  
  24. Q408. How can I read, create, change, or delete the volume label?
  25.  
  26.     In DOS 5.0 (and, I believe, in 4.0 as well), there are actually two
  27.     volume labels: one, the traditional one, is an entry in the root
  28.     directory of the disk and the other is in the boot record along with
  29.     the serial number (see next Q).  The DIR and VOL commands report the
  30.     traditional label; the LABEL command reports the traditional one but
  31.     changes both of them.
  32.  
  33.     In DOS 4.0 and later, use INT 21 function 69 to access the boot
  34.     record's serial number and volume label together; see the next Q.
  35.  
  36.     But more likely by "volume label" you mean the traditional one, the
  37.     one that DIR and VOL display.  Though it's a directory entry in the
  38.     root directory, you can't change it using the modern DOS file-access
  39.     functions (3C, 41, 43); instead, use the old FCB-oriented directory
  40.     functions.  Specifically, you need to allocate a 64-byte buffer and
  41.     a 41- byte extended FCB (file control block).  Call INT 21 AH=1A to
  42.     find out whether there is a volume label.  If there is, AL returns 0
  43.     and you can change the label using DOS function 17 or delete it
  44.     using DOS function 13.  If there's no volume label, function 1A will
  45.     return FF and you can create a label via function 16.  Important
  46.     points to notice are that ? wildcards are allowed but * are not;
  47.     the volume label must be space filled not null-terminated.
  48.  
  49.     The following MSC 7.0 code worked for me in DOS 5.0; the functions
  50.     it uses have been around since DOS 2.0.  The function parameter is 0
  51.     for the current disk, 1 for a:, 2 for b:, etc.  It doesn't matter
  52.     what your current directory is; these functions always search the
  53.     root directory for volume labels.  (I didn't try to change the
  54.     volume label of any networked drives.)
  55.  
  56.     // Requires DOS.H, STDIO.H, STRING.H
  57.     void vollabel(unsigned char drivenum) {
  58.         static unsigned char extfcb[41], dta[64], status, *newlabel;
  59.         int chars_got = 0;
  60.         #define DOS(buff,func) __asm { __asm mov dx,offset buff \
  61.             __asm mov ax,seg buff  __asm push ds  __asm mov ds,ax \
  62.             __asm mov ah,func  __asm int 21h  __asm pop ds \
  63.             __asm mov status,al }
  64.         #define getlabel(buff,prompt) newlabel = buff;  \
  65.             memset(newlabel,' ',11);  printf(prompt);   \
  66.             scanf("%11[^\n]%n", newlabel, &chars_got);  \
  67.             if (chars_got < 11) newlabel[chars_got] = ' ';
  68.  
  69.         // Set up the 64-byte transfer area used by function 1A.
  70.         DOS(dta, 1Ah)
  71.         // Set up an extended FCB and search for the volume label.
  72.         memset(extfcb, 0, sizeof extfcb);
  73.         extfcb[0] = 0xFF;             // denotes extended FCB
  74.         extfcb[6] = 8;                // volume-label attribute bit
  75.         extfcb[7] = drivenum;         // 1=A, 2=B, etc.; 0=current drive
  76.         memset(&extfcb[8], '?', 11);  // wildcard *.*
  77.         DOS(extfcb,11h)
  78.         if (status == 0) {            // DTA contains volume label's FCB
  79.             printf("volume label is %11.11s\n", &dta[8]);
  80.             getlabel(&dta[0x18], "new label (\"delete\" to delete): ");
  81.             if (chars_got == 0)
  82.                 printf("label not changed\n");
  83.             else if (strncmp(newlabel,"delete     ",11) == 0) {
  84.                 DOS(dta,13h)
  85.                 printf(status ? "label failed\n" : "label deleted\n");
  86.             }
  87.             else {                    // user wants to change label
  88.                 DOS(dta,17h)
  89.                 printf(status ? "label failed\n" : "label changed\n");
  90.             }
  91.         }
  92.         else {                        // no volume label was found
  93.             printf("disk has no volume label.\n");
  94.             getlabel(&extfcb[8], "new label (<Enter> for none): ");
  95.             if (chars_got > 0) {
  96.                 DOS(extfcb,16h)
  97.                 printf(status ? "label failed\n" : "label created\n");
  98.             }
  99.         }
  100.     }   // end function vollabel
  101.  
  102. Q409. How can I get the disk serial number?
  103.  
  104.     Use INT 21.  AX=6900 gets the serial number; AX=6901 sets it.  See
  105.     Ralf Brown's interrupt list, or page 496 of the July 1992 {PC
  106.     Magazine}, for details.
  107.  
  108.     This function also gets and sets the volume label, but it's the
  109.     volume label in the boot record, not the volume label that a DIR
  110.     command displays.  See the preceding Q.
  111.  
  112.     I tested the following MSC 7.0 code under DOS 5.0.  The function
  113.     parameter is 0 for the current disk, 1 for a:, 2 for b:, etc.
  114.  
  115.     // Requires DOS.H, STDIO.H, STRING.H
  116.     void labserial(unsigned char drivenum) {
  117.         static unsigned char bpb[0x19], *label = &bpb[6];
  118.         static unsigned *serial = (unsigned *)(&bpb[2]);
  119.         int chars_got = 0;
  120.         #define DOS(func) __asm { __asm mov bl,drivenum \
  121.           __asm mov dx,offset bpb __asm mov ax,seg bpb __asm push ds \
  122.           __asm mov ds,ax __asm mov ax,func __asm int 21h __asm pop ds }
  123.  
  124.         // Read the disk information.
  125.         DOS(6900h)
  126.         printf("serial number: %04X-%04X\n", serial[1], serial[0]);
  127.         printf("volume label: [%-.11s]\n", label);
  128.  
  129.         // Get the new label and serial number.
  130.         memset(label, ' ', 11);
  131.         printf("new label (\"NO NAME\" to delete): ");
  132.         scanf("%11[^\n]%n", label, &chars_got);
  133.         if (chars_got == 0)
  134.             printf("label not changed\n");
  135.         else {
  136.             if (chars_got < 11)
  137.                 label[chars_got] = ' ';
  138.             printf("new serial number (8 hex digits): ");
  139.             scanf("%lx", (unsigned long *)serial);
  140.             DOS(6901h)
  141.         }
  142.     }   // end function labserial
  143. -- 
  144. Stan Brown, Oak Road Systems                      brown@Ncoast.ORG
  145. "There are no good guys.  There's bad guys and worse guys.  The best one
  146. can hope for is to defend the bad against the worse."
  147.                                  -- {Almost History} by Christopher Bram
  148.