[comp.sys.ibm.pc.programmer] Setting Volume Label: summary, solution

E.Ireland@massey.ac.nz (Evan Ireland) (05/29/90)

In my message of 24 April I asked how to go about setting the volume
label on a DOS formatted disk, and allowing it to contain `unusual'
characters.

Several people replied that I should use the FCB functions of DOS,
suggesting a number of books describing them, and one person sent
me C source code to use the FCB functions.  However, I found that
the FCB functions would not create `unusual' volume labels, in
effect doing nothing more than the DOS _CREAT interrupt (which is
not documented as being able to create volume labels, as far as I
can tell).

Thuan-Tit Ewe (tte@metaware.com) replied as follows (an answer I had
hoped I would not get!)

> What you want is a tall order. I however got around to doing this by
> first creating a file of known name; read the directory sectors searching
> for the file and then zapping the file name with whatever character I
> choose.

and also sent me a program that could do this.  However, since I
wanted to set volume labels from within my own application, I decided that
now was the time to learn about DOS disk structure!

Fortunately, last year I found an article "Disk File Organisation: A
Bit's Eye View" in Computer Language (March 1987 issue) and the other
day I pulled out my copy.  This article describes DOS partition, boot,
FAT, and directory tables in some detail, and with this information I
was able to write a working "set volume label" function for my
program.

For anyone else who wants to try this (I could send you some code),
what follows is the outline of my disk label function:

    Read the disk's boot sector (sector 0, if using DOS calls).

    From the boot sector, work out the number of root directory
    sectors (# root directory entries * size of directory entry (32) /
    bytes per sector) and the number of the first root directory
    sector (boot sectors + FAT sectors)

    For each directory sector:

        Read the directory sector.

	Search the sector for an unused (first byte of filename = 0)
	or erased (first byte of filename = 0x2e) directory entry, and
	if found set the filename to the required volume label (11
	characters max.), set the file attribute to LABEL (8), set
	date and time (volume creation time, displayed by CHKDSK),
	set file starting cluster and size to zero, and write the
	sector to disk.

	If not already found, continue searching for the previous
	volume label entry, and erase it (make first byte of filename
	= 0x2e).

Points to note
--------------

(a) It would appear that the only characters you cannot put in a volume
    label are 0 (meaning UNUSED entry) and 0x2e (meaning ERASED entry,
    can sometimes be unerased), and each of these cannot be used only
    for the first filename character.  Certainly graphic characters are
    permitted.  However you may get unusual effects if you put control
    characters in the label (I haven't tried this out yet).

(b) The Turbo C 1.5 absread and abswrite functions do not appear to
    restore register values correctly, so I had to compile with
    option -r- (register variables disabled).

Other questions
---------------

(a) Are there any IBM PC or compatible systems with other than 512
    byte disk sectors?  There is a field for sector size (in bytes) in
    the boot table but I imagine a lot of software assumes 512 byte
    sectors.

(b) The root directory may contain entries for subdirectories, and the
    starting cluster is given, but the file size field is always 0.
    Do all subdirectory tables only contain one cluster of sectors, or
    is it necessary to follow a chain of clusters in the FAT?  In
    other words, how do you determine the number of sectors/entries in
    a subdirectory?

(c) Has anybody else discovered the problem with TC 1.5 absread &
    abswrite, and a way to get around it without disabling register
    variables?  I could send a small (19 line) C program demonstrating
    this error to anybody who is interested.

				  Evan Ireland (E.Ireland@massey.ac.nz),
School of Information Sciences, Massey University, Palmerston North, NZ.

dmurdoch@watstat.uwaterloo.ca (Duncan Murdoch) (05/29/90)

In article <326sis-b@massey.ac.nz> E.Ireland@massey.ac.nz writes:
>what follows is the outline of my disk label function:
>
>    Read the disk's boot sector (sector 0, if using DOS calls).
>
>    From the boot sector, work out the number of root directory
>    sectors (# root directory entries * size of directory entry (32) /
>    bytes per sector) and the number of the first root directory
>    sector (boot sectors + FAT sectors)

You should be warned that not all disks fill in the boot sector properly:
if they're loaded using a device driver that already knows all the stuff
that would normally be put there, there's no need.  For example, certain
ramdisks just zero the boot sector.  It's fairly easy to recognize that
what's stored there is garbage, but the only way to correct it is an
undocumented dos call to get the BPB for the drive.  It's described in
Ralf Brown's interrupt list (INTER290.ZIP).

>
>(a) Are there any IBM PC or compatible systems with other than 512
>    byte disk sectors?  There is a field for sector size (in bytes) in
>    the boot table but I imagine a lot of software assumes 512 byte
>    sectors.

Yes - again, they're mostly drives run from a device driver.  I think 
Ontrack's disk manager, which allows >32Meg partitions in DOS 2 and 3,
does it by using big sectors.
>
>(b) The root directory may contain entries for subdirectories, and the
>    starting cluster is given, but the file size field is always 0.
>    Do all subdirectory tables only contain one cluster of sectors, or
>    is it necessary to follow a chain of clusters in the FAT?  In
>    other words, how do you determine the number of sectors/entries in
>    a subdirectory?

The only way is to follow the chain through the FAT.  There will be more
than one cluster if you get enough files in the subdirectory.

Duncan Murdoch
dmurdoch@watstat.waterloo.edu

P.S. My mailer doesn't like something about your address. If you have an 
alternate one, you might add it to your signature. 

keeler@jeanne.enet.dec.com (06/01/90)

> From: E.Ireland@massey.ac.nz (Evan Ireland)
> Newsgroups: comp.sys.ibm.pc.programmer
> Subject: Setting Volume Label: summary, solution
> Keywords: Volume, Label

> 
> Other questions
> ---------------
> 
> (a) Are there any IBM PC or compatible systems with other than 512
>     byte disk sectors?  There is a field for sector size (in bytes) in
>     the boot table but I imagine a lot of software assumes 512 byte
>     sectors.
> 
> (b) The root directory may contain entries for subdirectories, and the
>     starting cluster is given, but the file size field is always 0.
>     Do all subdirectory tables only contain one cluster of sectors, or
>     is it necessary to follow a chain of clusters in the FAT?  In
>     other words, how do you determine the number of sectors/entries in
>     a subdirectory?
> 
> (c) Has anybody else discovered the problem with TC 1.5 absread &
>     abswrite, and a way to get around it without disabling register
>     variables?  I could send a small (19 line) C program demonstrating
>     this error to anybody who is interested.
> 

Evan,

I can't answer your first question, however in regards to the other two.

Subdirectories are not like the root directory. That is there is no limit of
files in them, thus you must follow the cluster chain within the FAT if you are
working at that level.

I also discovered the problem with TURBOC 1.5 with absread and abswrite. The
following code segment was used to solve the problem in my case. I found that
the only register that was corrupted was CX and thus I just saved it prior to
the call and then restored it after. 
..................
unsigned sav_cx;

#ifdef __TURBOC__
/*    This code inserted to overcome bug in TurboC V1.5     */
   sav_cx = _CX;
#endif  
   if (absread(drive_no,nsects,i,&diskin[0]) == -1)
   {
    errno &= 0x000D;
    sprintf(error_msg,"%s\n",errno,errlist[errno]);
    return(TRUE);
   }
#ifdef __TURBOC__
/*    This code inserted to overcome bug in TurboC V1.5     */
   _CX = sav_cx;
#endif  

Thanks for the info on the r switch I didn't even think of that.

Gary
 root directory
>     sectors (# root directory entries * size of directory entry (32) /
>     byt

jearly@lehi3b15.csee.Lehigh.EDU (John Early) (06/05/90)

In article <326sis-b@massey.ac.nz> E.Ireland@massey.ac.nz (Evan Ireland) writes:
>   In my message of 24 April I asked how to go about setting the volume
>   label on a DOS formatted disk, and allowing it to contain `unusual'
>   characters.

[useful DOS tips omitted]

I missed this discussion.  Just wanted to say that the must useful
application of writing "unusual" characters is to imbed ANSI codes.
Unfortunately, IBM (in their infinite wisdom) allocated a mere 11
characters to play with.  On one of my PCs at work I changed my volume
label to be pink (on black; the rest of the DIR is lt.blue) but had to
hack command.com to change DIR so that it would reset the colors back.
John.

John Early                             |
jearly@lehi3b15.csee.lehigh.edu        |  I was just a child then;
JPE1@Lehigh.Bitnet                     |  now I'm only a man.  [pf]
LUJPE@VAX1.cc.lehigh.edu               |