From: leo@dcs.warwick.ac.uk (Leo Hendry)
Subject: Re: How do you set a disk's volume label?
Organization: Department of Computer Science, Warwick University, England
Date: Mon, 4 Jan 1993 20:30:23 GMT

In article <H.ea.kYwLB_Rm3xg@kynes.bison.mb.ca> rdo@kynes.bison.mb.ca writes:
>Using the following code, I can find the volume label on a disk:
>
>#include <stdio.h>
>#include <string.h>
>#include <osbind.h>
>#include <ostruct.h>
>
>/* Get disk vol for specified drive */
>char *
>getvol(char drive)
>{
>	_DTA	*dta;
>	char	path[8];
>	char	*vol = NULL;
>
>	path[0] = '/';
>	path[1] = drive;
>	path[2] = '\0';
>	chdir(path);
>	Fsfirst("*.*", FA_LABEL);
>	do {
>		dta = (_DTA *)Fgetdta();
>		printf("name: %s\n", dta->dta_name);
>		if (dta->dta_attribute == FA_LABEL) {
>			vol = strdup(dta->dta_name);
>			break;
>		}
>	} while (Fsnext() == 0);
>
>	if (vol != NULL)
>		return vol;
>	else
>		return NULL;
>}

I doubt it - there are several problems with this.  Firstly, you set aside
8 bytes for "path", then only use 3 of them.  Then (more importantly) you set
path to the string "/D", where D is the drive (Note the slash is the wrong
way round).  Note that anyway chdir("a:\") will simply change the current
directory on drive A: to the root, not change to drive A:.
  Next you call Fsfirst without first setting the DTA - by default this is
over the area where the command line is stored.  Then you assume that
Fsfirst has found something when it might not have done.  Next you call
Fgetdta inside a loop where the DTA address never changes and check that the
attribute really is FA_LABEL, which it always will be (this is not a bug -
just a waste of time). You then call Fsnext to find the next file with the
FA_LABEL - even if for some reason there were two labels on the disk the
"break" would mean the second one would be ignored.  Finally "if (vol!=NULL)
return vol; else return NULL;" can be reduced to "return vol".
  Sorry to be so negative, but here's how I'd do it:

char *getvol(char drive)
 {
 _DTA dta;
 static char search[]="X:\\*.*";

 *search=drive;
 Fsetdta(&dta);
 if (!Fsfirst(search, FA_LABEL))
  return strdup(dta.dta_name);
 return NULL;
 }

Two backslashes are required in "search" because backslash is used as an
escape character in C - "X:\*.*" will be interpreted as "X:*.*" or maybe
"X:.*", I can't remember which.  Note that the above this changes the DTA's
address - it might be a good idea to save it at the beginning and restore it
afterwards.

>Now, what I'd like to do is be able to change an existing label.  Or, if one
>doesn't exist, I'd like to create it.

Simple - as you know, the volume label is simply a file with the attribute
FA_LABEL, so to change it you simply delete this file and create a new one
with the name you require.  The following sets the label of the specified
drive to "new_vol" (or insures there is no volume label if new_vol is NULL
and returns the old label (or NULL if there was previously none).

char *setvol(char drive, char *new_vol)
 {
 char *old_vol;

 if (old_vol=getvol(drive))
  Dremove(old_vol);
 if (new_vol)
  Dclose(Dcreat(FA_LABEL, new_vol));
 return old_vol;
 }

It is more than possible that I have made a mistake somewhere (eg. Dremove may
be called something else, and Dcreat may take it's arguments in the opposite
order) as I have not tested either of the above.  However, this should at
least give you the general idea.

- Leo