home *** CD-ROM | disk | FTP | other *** search
- /*
- LABEL Create, modify or remove drive volume labels.
- Compile using Borland or Turbo C++.
- Copyright (C) 1994 Max Brante
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- /***************************************************************************/
-
- #include <conio.h>
- #include <dos.h>
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
-
- /***************************************************************************/
- /* Comment out the BETA define if not beta version */
-
- // #define BETA
- #define VERSION "1.1"
-
- /***************************************************************************/
- /* Process errors and exit */
-
- void error(int errnum) {
- switch (errnum&0xFF) {
- case 0x00:
- printf("Write protect error.\n");
- break;
- case 0x01:
- printf("Unknown unit.\n");
- break;
- case 0x02:
- printf("Drive not ready.\n");
- break;
- case 0x03:
- printf("Unknown command.\n");
- break;
- case 0x04:
- printf("Data error (bad CRC).\n");
- break;
- case 0x05:
- printf("Bad request structure length.\n");
- break;
- case 0x06:
- printf("Seek error.\n");
- break;
- case 0x07:
- printf("Unknown media type.\n");
- break;
- case 0x08:
- printf("Sector not found\n");
- break;
- case 0x0A:
- printf("Write fault.\n");
- break;
- case 0x0B:
- printf("Read fault.\n");
- break;
- case 0x0C:
- printf("General failiure.\n");
- break;
- }
- exit(1);
- }
-
- /***************************************************************************/
- /* Show how to use LABEL */
-
- void usage() {
- printf("Creates, changes or deletes the volume label of a disk.\n\n");
- printf("LABEL [drive:][label]\n");
- }
-
- /***************************************************************************/
- /* Main function */
-
- void main(int argc,char **argv) {
- char label[12],oldlabel[12];
- unsigned char buf[512],ch;
- unsigned char *dirent;
- unsigned nument;
- int drive,haslabel=0,getlabel=1,savedlabel=0;
- long dirstart,i,lsect;
- unsigned serhi,serlo;
- time_t timer;
- struct tm tblock;
- char far *mdbptr;
- union REGS regs;
-
- #ifdef BETA
- printf("LABEL %s beta version\n",VERSION);
- #endif
-
- memcpy(label,0,sizeof(label));
-
- /* Process the command line parameters */
- switch(argc) {
- case 1:
-
- /* getdisk() returns the current drive number */
- drive=getdisk();
- break;
- case 3:
- strcpy(label,argv[2]);
- getlabel=0;
- case 2:
- if (strcmp("/?",argv[1])==0) {
- usage();
- exit(0);
- }
- if (argv[1][1]==':' && strlen(argv[1])==2 && isalpha(argv[1][0]))
- drive=toupper(argv[1][0])-'A';
- else if (argc==2) {
- memcpy(label,argv[1],11);
- drive=getdisk();
- getlabel=0;
- }
- break;
- default:
- usage();
- exit(1);
- }
-
- /* Get time and date */
- /* time() returns time of day in seconds, elapsed since 00:00:00 GMT,
- January 1, 1970. */
- timer = time(NULL);
-
- /* localtime() converts date and time to a structure */
- memcpy(&tblock,localtime(&timer),sizeof(struct tm));
-
- /* Get drive info */
- regs.h.ah=0x1c;
- regs.h.dl=drive+1;
- /* intdos() generates a dos interrupt*/
- intdos(®s,®s);
- /* If drive not valid */
- if (regs.h.al==0xFF)
- error(2);
-
-
- /* Read boot record of logical disk */
- /* absread() reads absolute disk sectors */
- if (absread(drive,1,0,buf)==-1)
- error(errno);
-
- /* Get number of root directory entries */
- nument=*(unsigned *)&buf[0x11];
-
- /* Get the start block number of the root directory */
- dirstart=buf[0x10]*(*(unsigned *)&(buf[0x16]))+1;
-
- /* Get volume serial number */
- serlo=*(unsigned *)&buf[0x27];
- serhi=*(unsigned *)&buf[0x29];
-
- /* Loop through the entries in the root directory */
- for(i=0;i<nument*32;i+=32){
-
- /* If we crossed a block boundary, read next one */
- if ((i%512)==0) {
- if (absread(drive,1,dirstart+i/512,buf)==-1)
- error(errno);
- drive=drive;
- }
-
- /* Point dirent at current entry in the root directory */
- dirent=&buf[i%512];
-
- /* If first byte in directory entry is 0 no more entries */
- if (*dirent==0)
- break;
-
- /* If volume label attribute is set and the label isn't deleted
- we have found the volume label */
- if ((dirent[0x0B]&8)==8 && *dirent!=0xE5) {
-
- /* Get volume the label and the number of the block in which the entry
- containing the label is. */
- memcpy(oldlabel,dirent,11);
- oldlabel[11]=0;
- lsect=dirstart+i/512;
- haslabel=1;
- break;
- }
- }
-
- /* If the user didn't enter a label on the command line, get one*/
- if (getlabel) {
- if (haslabel)
- printf("Volume in drive %c is %s\n",drive+'A',oldlabel);
- else
- printf("Volume in drive %c has no label\n",drive+'A');
- printf("Volume Serial Number is %04X-%04X\n",serhi,serlo);
- printf("Volume label (11 characters, ENTER for none)? ");
- fgets(label,11,stdin);
- if(label[strlen(label)-1]=='\n')
- label[strlen(label)-1]=0;
- }
- if (strlen(label)!=0)
- memset(&label[strlen(label)],32,11-strlen(label));
- strupr(label);
-
- /* If we didn't get a new label */
- if (getlabel && strlen(label)==0) {
- if(haslabel) {
- printf("\nDelete current volume label (y/N)? ");
- /* getche() returns the next keypress and echos to screen */
- ch=tolower(getche());
- if (ch=='y') {
-
- /* Delete the old label */
- *dirent=0xE5;
-
- /* abswrite() writes absolute disk sectors */
- if (abswrite(drive,1,lsect,buf)==-1)
- error(errno);
- if (absread(drive,1,0,buf)==-1)
- error(errno);
-
- /* Change the label field in the boot block */
- memcpy(&buf[43],"NO NAME ",11);
- if (abswrite(drive,1,0,buf)==-1)
- error(errno);
- }
- }
- }
-
- /* If we did get a new label */
- else {
-
- /* If the volume had a old label, change it */
- if (haslabel) {
- memcpy(dirent,label,11);
- savedlabel=1;
- }
-
- /* The volume had no label so find a unused directory entry
- and save the label */
- else {
-
- /* Loop through the entries in the root directory */
- for(i=0;i<nument*32;i+=32){
-
- /* If we crossed a block boundary, read next one */
- if ((i%512)==0) {
- if (absread(drive,1,dirstart+i/512,buf)==-1)
- error(errno);
- drive=drive;
- }
-
- /* Point dirent at current entry in the root directory */
- dirent=&buf[i%512];
-
- /* If the directory entry deleted or isn't used, save label there */
- if (*dirent==0xE5 || *dirent==0) {
- memset(dirent,0,32);
- memcpy(dirent,label,11);
- dirent[0x0B]=0x28;
- lsect=dirstart+i/512;
- savedlabel=1;
- break;
- }
- }
- }
-
- if (savedlabel) {
- /* Save the time and date of the change in the directory entry */
- *(unsigned*)&dirent[0x16]=(tblock.tm_hour&31)<<11 |
- (tblock.tm_min&63)<<5 |
- (tblock.tm_sec&31);
- *(unsigned*)&dirent[0x18]=((80-tblock.tm_year)&127)<<9 |
- ((1+tblock.tm_mon)&15)<<5 |
- (tblock.tm_mday&31);
-
- /* Write the dirictory entry to the volume */
- if (abswrite(drive,1,lsect,buf)==-1)
- error(errno);
-
- /* Update the label field in the boot record */
- if (absread(drive,1,0,buf)==-1)
- error(errno);
- memcpy(&buf[43],label,11);
- if (abswrite(drive,1,0,buf)==-1)
- error(errno);
- }
- }
- }
-