Chapter – 16
Developing more Utilities for Disks
Introduction
In this chapter we shall discuss, how to use the information of MBR, DBR, FAT and Root Directories to develop utility programs which may help us in managing the data, in optimizing the storage or in may disk troubleshooting tasks.
Usually, these programs are solution to some specific problem. Some utility programs and their programming have been discussed in this chapter.
Hiding Partitions
Generally, the partition hiding utility is used by those users who work on such computer system which is used by users. If there are many users for same the computer, there may be a great possibility, that data of another user may be read, stolen, or deleted.
In such case, where user has some important data or some confidential information in the same computer, he may be willing to hide the partition in which he has his data in such a way that the partition should not be accessed by the Operating system, so that the may not be accessed by other user.
When the user wants to work on the system, he can access the partition back, just by unhiding the partition. Generally these types of events take place in the professional institutions, where the computers are used by many students but senior students are always worried about their important data or project work. As in lack of knowledge, the new student may harm or even delete their data.
How the partition becomes hidden
The following table represents the format of partition in partition table of MBR:
Offset |
Meaning |
Size |
Description |
00H |
Boot Type Indicator Byte |
1 Byte |
If Byte is 00H, the Partition is Inactive and if Byte is 80H, The Partition is Active (or Bootable) |
01H |
Head Number of Beginning of the Partition |
1 Byte |
Starting Head number of the Partition in Hexadecimal System |
02H |
Sector and Cylinder Number of Beginning of the Partition |
2 Bytes |
6 Bits of First Byte make Starting Sector Number and Combination of remaining 2 Bits (as Two Most Significant Bits) plus 8 Bits of another Byte (Rest 8 least Significant Bits of the 10-Bit Number ) make the Starting Cylinder Number of the Partition |
04H |
File System indicator Byte |
1 Byte |
File System Indicator Byte in Hexadecimal system (for complete list of partition indicator bytes, refer the chapter “Logical Approach to Disks and OS” discussed earlier in this book) |
05H |
Head Number of End of the Partition |
1 Byte |
Ending Head Number of the Partition in Hexadecimal System |
06H |
Sector and Cylinder Number of End of the Partition |
2 Bytes |
6 Bits of First Byte make Ending Sector Number and Combination of remaining 2 Bits (as Two Most Significant Bits) plus 8 Bits of another Byte (Rest 8 least Significant Bits of the 10-Bit Number ) make the Ending Cylinder Number of the Partition |
08H |
Absolute Sector number of Beginning of the Partition |
4 Bytes |
Number of Sectors Between the MBR and the First Sector in the Partition |
0CH |
Absolute Sector number of End of the Partition |
4 Bytes |
Number of Sectors in the Partition |
|
|
Total = 16 Bytes |
|
At the offset 04H, in every partition entry, there is a file system indicator byte. This indicator byte represents the type of file system of that partition. If the value of this byte is changed, the identity of the partition is changed.
For example, the value of partition indicator byte for “DOS 12-Bit FAT” is 0x01. If this value is changed to 0x11, The identity of file system in the partition table entry is changed to “Hidden DOS 12-Bit FAT” (for complete list of partition indicator bytes, refer the chapter “Logical Approach to Disks and OS” discussed earlier in this book).
The table given next shows some more examples of file system indicator byte for some partition types:
Partition type indicator Byte |
Description of File System of Partition |
0x01 |
DOS 12–bit FAT |
0x11 |
Hidden DOS 12–bit FAT |
0x04 |
DOS 16–bit FAT (<=32MB) |
0x14 |
Hidden DOS 16–bit FAT (<=32MB) |
0x05 |
DOS Extended |
0x15 |
Hidden DOS Extended |
0x06 |
DOS 16–bit big (> 32MB) |
0x16 |
Hidden DOS 16–bit big (> 32MB) |
0x07 |
NTFS |
0x17 |
Hidden NTFS |
0x0B |
Windows FAT32 |
0x1B |
Hidden Windows FAT32 |
0x0C |
Windows FAT32 (LBA) |
0x1C |
Hidden Windows FAT32 (LBA) |
0x0E |
Windows FAT16 (LBA) |
0x1E |
Hidden Windows FAT16 (LBA) |
0x0F |
Windows Extended |
0x1F |
Hidden Windows Extended |
Here we see that the corresponding hidden partition for any file system is found by adding the value 0x10 to its system indicator byte.
Although it is not the hard and fast rule for hiding the partition yet it works even for most of the file system. The reason behind it is that when we change the value of partition indicator byte, the identity of file system in the partition table entry is changed. And it is very rare that the new file system is also supported by the same operating system.
Writing program to hide partition
The program given next is used to hide the partition using the partition entry of that partition from partition table of MBR. If you want to hide other logical partitions in the extended volume you should access the extended MBRs.
The coding of the program has been given next:
/* Program to hide the partition using Partition table entry of that Partition from MBR */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo;
int result, tohide;
int i;
static char dbuf[512];/* Data Buffer to read-Write the
Sector information */
clrscr();
dinfo.drive = 0x80; /* drive number for First
Hard Disk */
dinfo.head = 0; /* disk head number */
dinfo.track = 0; /* track number */
dinfo.sector = 1; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
/* Read the First Sector of the Disk */
result = _bios_disk(_DISK_READ, &dinfo);
if ((result & 0xff00) == 0)
{
printf("The Partition Codes of Four Partition Entries are,
0x%02x, 0x%02x, 0x%02x And 0x%02x.\n",
dbuf[450] & 0xff, dbuf[466] & 0xff,
dbuf[482] & 0xff, dbuf[498] & 0xff);
textcolor(15);
gotoxy(5,5);cprintf("Partition Entry in MBR is as
follows:");
gotoxy(10,7);cprintf("1. "); showtype(dbuf[450] & 0xff);
gotoxy(10,8);cprintf("2. "); showtype(dbuf[466] & 0xff);
gotoxy(10,9);cprintf("3. "); showtype(dbuf[482] & 0xff);
gotoxy(10,10);cprintf("4. "); showtype(dbuf[498] & 0xff);
/* get the User Input for Hiding the Partition */
gotoxy(1,15);
printf("Enter The partition no. you want to hide,
Or Press any other key to Exit... ");
tohide=getche();
switch(tohide)
{
case '1': /* Hide First Partition in partition Table */
dbuf[450] = dbuf[450] +16;
result = _bios_disk(_DISK_WRITE, &dinfo);
break;
case '2': /* Hide second Partition in partition Table */
dbuf[466] = dbuf[466]+16;
result = _bios_disk(_DISK_WRITE, &dinfo);
break;
case '3': /* Hide third Partition in partition Table */
dbuf[482] = dbuf[482] +16;
result = _bios_disk(_DISK_WRITE, &dinfo);
break;
case '4': /* Hide Fourth Partition in partition Table */
dbuf[498] = dbuf[498]+16;
result = _bios_disk(_DISK_WRITE, &dinfo);
break;
default:
exit(0);
}
if ((result & 0xff00) == 0)
{
printf("\n\nThe New Partition Codes of Four Partition
Entries are, 0x%02x, 0x%02x, 0x%02x And 0x%02x.\n",
dbuf[450] & 0xff, dbuf[466] & 0xff,
dbuf[482] & 0xff, dbuf[498] & 0xff);
getch();
}
else
{
printf("Cannot Change the Byte, status = 0x%02x\n",
result);
getch();
}
}
return 0;
}
Comments on coding:
The program reads file system indicator bytes of all four partition entries in partition table of MBR. The function showtype( ) is used to show the name of file system for the corresponding value of file system indicator byte.
The user selects the partition to hide from the menu displayed on the screen and then 16 (0x10) is added to the value of file system indicator byte of that partition to hide it.
The coding of the function showtype( ) is as follows:
/* Function to show the name of file system corresponding to the value of file system indicator byte */
showtype(i)
{
switch (i)
{
case 0x00 :cprintf("Empty"); break;
case 0x01 :cprintf("DOS 12-bit FAT"); break;
case 0x02 :cprintf("XENIX root"); break;
case 0x03 :cprintf("XENIX usr"); break;
case 0x04 :cprintf("DOS 16-bit <32M"); break;
case 0x05 :cprintf("Extended"); break;
case 0x06 :cprintf("DOS 16-bit >=32M"); break;
case 0x07 :cprintf("OS/2 HPFS"); break;
case 0x08 :cprintf("AIX"); break;
case 0x09 :cprintf("AIX bootable"); break;
case 0xa :cprintf("OS/2 Boot Manag"); break;
case 0xb :cprintf("Win95/98/ME FAT32"); break;
case 0xc :cprintf("Win95/98/ME FAT32 (LBA)"); break;
case 0xd :cprintf("Win95 FAT16"); break;
case 0xe :cprintf("Win95 FAT16 (LBA)"); break;
case 0xf :cprintf("Win95 Extended"); break;
case 0x11 :cprintf("Hidden FAT-12");break;
case 0x12 :cprintf("Compaq Diagnostics");break;
case 0x14 :cprintf("Hidden FAT-16 (<32)");break;
case 0x15 :cprintf("Hidden Extended");break;
case 0x16 :cprintf("Hidden FAT-16");break;
case 0x17 :cprintf("NTFS"); break;
case 0x40 :cprintf("Venix 80286"); break;
case 0x51 :cprintf("Novell?"); break;
case 0x52 :cprintf("Microport"); break;
case 0x63 :cprintf("GNU HURD"); break;
case 0x64 :
case 0x65 :cprintf("Novell Netware"); break;
case 0x75 :cprintf("PC/IX"); break;
case 0x80 :cprintf("Old MINIX"); break;
case 0x81 :cprintf("Linux/MINIX"); break;
case 0x82 :cprintf("Linux swap"); break;
case 0x83 :cprintf("Linux native"); break;
case 0x85 :cprintf("Linux Extended"); break;
case 0x93 :cprintf("Amoeba"); break;
case 0x94 :cprintf("Amoeba BBT"); break;
case 0xa5 :cprintf("BSD/386"); break;
case 0xa6 :cprintf("OpenBSD"); break;
case 0xa7 :cprintf("NEXTSTEP"); break;
case 0xb7 :cprintf("BSDI fs"); break;
case 0xb8 :cprintf("BSDI swap"); break;
case 0xc7 :cprintf("Syrinx"); break;
case 0xdb :cprintf("CP/M"); break;
case 0xe1 :cprintf("DOS access"); break;
case 0xe3 :cprintf("DOS R/O"); break;
case 0xf2 :cprintf("DOS secondary"); break;
case 0xff :cprintf("BBT"); break;
default :cprintf("UNKOWN");
}
return 0;
}
Writing program to Unhide the Partition
The program to unhide the hidden partition works just opposite to the program which hides the program. In this program we subtract 16 (0x10) from the value of file system indicator byte of the hidden partition.
The coding of the program in as follows:
/* Program to unhide the partition hidden by the previous program */
#include <bios.h>
#include <stdio.h>
int main(void)
{
struct diskinfo_t dinfo;
int result, tohide;
int i;
static char dbuf[512];/* Data buffer */
clrscr();
dinfo.drive = 0x80; /* drive number for
First Hard Disk */
dinfo.head = 0; /* disk head number */
dinfo.track = 0; /* track number */
dinfo.sector = 1; /* sector number */
dinfo.nsectors = 1; /* sector count */
dinfo.buffer = dbuf; /* data buffer */
result = _bios_disk(_DISK_READ, &dinfo);
if ((result & 0xff00) == 0)
{
printf("The Partition Codes of Four Partition
Entries are, 0x%02x, 0x%02x, 0x%02x And 0x%02x.\n",
dbuf[450] & 0xff, dbuf[466] & 0xff,
dbuf[482] & 0xff, dbuf[498] & 0xff);
textcolor(15);
gotoxy(5,5);
cprintf("Partition Entry in MBR is as follows:");
gotoxy(10,7);cprintf("1. "); showtype(dbuf[450] & 0xff);
gotoxy(10,8);cprintf("2. "); showtype(dbuf[466] & 0xff);
gotoxy(10,9);cprintf("3. "); showtype(dbuf[482] & 0xff);
gotoxy(10,10);cprintf("4. "); showtype(dbuf[498] & 0xff);
/* Get the Use input to unhide the partition */
gotoxy(1,15);printf("Enter The partition no., Which to
unhide, Or Press any other key to
Exit... ");
tohide=getche();
switch(tohide)
{
/* Unhide first partition of partition table */
case '1':
dbuf[450] = dbuf[450] -16;
result = _bios_disk(_DISK_WRITE, &dinfo);
break;
/* Unhide second partition of partition table */
case '2':
dbuf[466] = dbuf[466]-16;
result = _bios_disk(_DISK_WRITE, &dinfo);
break;
/* Unhide third partition of partition table */
case '3':
dbuf[482] = dbuf[482] -16;
result = _bios_disk(_DISK_WRITE, &dinfo);
break;
/* Unhide fourth partition of partition table */
case '4':
dbuf[498] = dbuf[498]-16;
result = _bios_disk(_DISK_WRITE, &dinfo);
break;
default:
exit(0);
}
if ((result & 0xff00) == 0)
{
printf("\n\nThe New Partition Codes of Four Partition
Entries are, 0x%02x, 0x%02x, 0x%02x And 0x%02x.\n",
dbuf[450] & 0xff, dbuf[466] & 0xff,
dbuf[482] & 0xff, dbuf[498] & 0xff);
getch();
}
else
{
printf("Cannot Change the Byte, status = 0x%02x\n",
result);
getch();
}
}
return 0;
}
Comments on Program
Be careful while giving the partition number to unhide. If the number of partition is entered wrong by mistake, the file system information of that partition will be changed and partition may become inaccessible. However the program previously discussed to hide the partitions, may help you to cure the file system indicator byte of that partition.
Writing program to delete Partition
The program to delete partition is used for troubleshooting purpose. For example, assume that you had the FAT32 file system partitions in your disk. Now you decided to install the LINUX operating system in your disk simultaneously.
If any how, the installation of operating system is interrupted in between, at the stage when the modifications were being made to the partition table of the MBR. In such cases there are a lot of possibilities that the partition, in which you were going to install the other operating system, becomes inaccessible.
In this case the disk space of the lost partition becomes useless due to being inaccessible. However if we delete the partition information of that partition from partition table any how, we can again make this space usable using FDISK command of DOS.
The program to delete the partition entry from the partition table of MBR has been given next:
/* Program to delete the second partition entry from the partition table of MBR */
# include <bios.h>
/* structure to read the partition entry from partition table */
struct partition
{
/* Active Partition Byte */
unsigned char bootable ;
/* Starting Head */
unsigned char start_side ;
/* combination of Starting sector and cylinder number */
unsigned int start_sec_cyl ;
/* File system Indicator Byte */
unsigned char parttype ;
/* Ending Head */
unsigned char end_side ;
/* combination of Starting sector and cylinder number */
unsigned int end_sec_cyl ;
/* Relative Sector Number */
unsigned long part_beg ;
/* Partition length in sectors */
unsigned long plen ;
} ;
/* Structure to read-write MBR */
struct part
{
/* IPL (Initial Program Loader) */
unsigned char master_boot[446] ;
/* Partition table */
struct partition pt[4] ;
/* Magic Number */
int lasttwo ;
} ;
struct part p ;
void main()
{
unsigned int t1,t2;
clrscr();
biosdisk ( 2, 0x80, 0, 0, 1, 1, &p ) ;
display(); /* display the information of
Partition table */
getch();
p.pt[1].bootable = 0;
p.pt[1].start_side = 0 ;
p.pt[1].start_sec_cyl = 0 ;
p.pt[1].parttype = 0;
p.pt[1].end_side = 0;
p.pt[1].end_sec_cyl = 0;
p.pt[1].part_beg = 0;
p.pt[1].plen = 0;
printf("\n\n\n After Deleting the Second Partition
Entry From MBR Partition Table,");
printf("\n The Partition Table will Be Changed as
Follows: ");
/* To Delete Second Partition Information from partition
table of MBR Remove the forward slashes from the
biosdisk( ) function. Do not use Carelessly, Partition
information of Second Partition of Partition Table will
be Erased Completely. */
////// biosdisk ( 3, 0x80, 0, 0, 1, 1, &p ) ;
display(); /* Display the information of partition
table after modification */
getch();
}
Comments on program:
Uncomment the biosdisk ( 3, 0x80, 0, 0, 1, 1, &p ) function to delete the second partition from the partition table of MBR.
To delete the partition, all the parameters of it, are set to 0 in partition table entry in MBR. Always remember that if you delete the extended partition, all the logical partitions of that extended partition will also become inaccessible.
The Function display( ) is used to display the partition table of MBR. The coding of the function is as follows:
/* Function to display partition table of MBR */
display()
{
unsigned int s_sec, s_trk, e_sec, e_trk, i, t1, t2 ;
char type[20], boot[5] ;
printf("\n\nPart. Boot Starting location Ending Location
Relative Number of");
printf("\nType Side Cylinder Sector Side Cylinder
Sector Sectors Sectors\n");
for ( i = 0 ; i <= 3 ; i++ )
{
if ( p.pt[i].bootable == 0x80 )
strcpy ( boot, "Yes" ) ;
else
strcpy ( boot, "No" ) ;
switch ( p.pt[i].parttype )
{
case 0x00 :
strcpy ( type, "Unused" ) ; break ;
case 0x1 :
strcpy ( type, "FAT12" ) ; break ;
case 0x2 :
strcpy ( type, "Xenix" ) ; break ;
case 0x3 :
strcpy ( type, "Xenix:usr" ) ; break ;
case 0x4 :
strcpy ( type, "FAT16<32M" ) ; break ;
case 0x5 :
strcpy ( type, "DOS-Ext." ) ; break ;
case 0x6 :
strcpy ( type, "FAT16>32M" ) ; break ;
case 0x7 :
strcpy ( type, "NTFS" ) ; break ;
case 0x0b :
strcpy ( type, "FAT32" ) ; break ;
case 0x0c :
strcpy ( type, "FAT32-LBA" ) ; break ;
case 0x0d :
strcpy ( type, "VFAT16" ) ; break ;
case 0x0e :
strcpy ( type, "VFAT16-LBA" ) ; break ;
case 0x0f :
strcpy ( type, "FAT EXT" ) ; break ;
case 0x17 :
strcpy ( type, "HPFS" ) ; break ;
case 0x81 :
strcpy ( type, "Old LINUX" ) ; break ;
case 0x82 :
strcpy ( type, "LinuxSwap" ) ; break ;
case 0x83 :
strcpy ( type, "LinuxNative" ) ; break ;
case 0x85 :
strcpy ( type, "Linux Ext." ) ; break ;
default :
strcpy ( type, "Unknown" ) ; break ;
}
s_sec = ( p.pt[i].start_sec_cyl & 0x3f ) ;
t1 = ( p.pt[i].start_sec_cyl & 0xff00 ) >> 8 ;
t2 = ( p.pt[i].start_sec_cyl & 0x00c0 ) << 2 ;
s_trk = t1 | t2 ;
e_sec = ( p.pt[i].end_sec_cyl & 0x3f ) ;
t1 = ( p.pt[i].end_sec_cyl & 0xff00 ) >> 8 ;
t2 = ( p.pt[i].end_sec_cyl & 0x00c0 ) << 2 ;
e_trk = t1 | t2 ;
printf ( "\n%6s %3s", type, boot ) ;
printf ( "%4d %6d %8d", p.pt[i].start_side,
s_trk,s_sec ) ;
printf ( "%7d %6u %8u", p.pt[i].end_side, e_trk,
e_sec ) ;
printf ( " %10lu %10lu", p.pt[i].part_beg,
p.pt[i].plen ) ;
}
return 0;
}
Formatting “Track 0 Bad” floppy
This program is used to format those floppies which have bad sectors on their track 0 and when are formatted with DOS or windows, display error messages like “Track 0 BAD”. However you can also use it to format normal floppies.
The coding of the program has been given in the disk included with this book with the name “TTFORMAT.C”. The working logic of the program is same as the program published in PCQUEST computer magazine, in February 2003 edition.
In this program, we try to make this type of floppies reusable by formatting them. The program sounds that you can handle the floppy disk even with some bad sectors on it. However, if the first sector of the disk is bad, the floppy can not be formatted.
The program rewrites all the DBR, FAT and Root Directory information. If there are bad sectors on the surface of the disk, they are marked as bad in FAT.
In the coding of the program, the structure BPB is used to writer the BIOS Parameter Block of the DBR. The structure boot_sector is used to write the DBR of the disk. The structure address_field is used for interacting with number of cylinder, heads, and sectors per track and with the size of the sector.
Different functions used in the coding of the program and their description have been given in the table given next.
The Volume Serial Number of the Floppy disk is calculated by the DOS according to current date and time of the system clock.
The first part of the serial number is calculated by the sum of the time (seconds and hundredths of a second) and the date (month and day). The second part of the serial number is equal to the sum of the time (hours and minutes) and date (year).
All the calculations are performed in hexadecimal system. For example, let us assume that you formatted the floppy in DOS environment at 11:16:28:65 on 10/23/2003. Now let us calculate the serial number of the disk.
The time in (seconds and Hundredths of seconds) format is
= (28 and 65)
= (1CH and 41H)
Write it as 1C41
Similarly, date in (month and day) format is
= (10 and 23)
= (0AH and 17H)
Write it as 0A17
Similarly, time in (hours and minutes) format is,
= (11 and 16)
= (0BH and 10H)
Write it as 0B10
And the year will be
= 2003
= 07D3
Now, let us calculate the serial number of the floppy disk, according to the description given before. The first part of the serial number well be (1C41 + 0A17) = 2658 and the second part of the serial number will be (0B10 + 07D3) = 12E3.
Writing the Disk Editing Tool
The coding of the disk editing program has been given in the disk included with this book, with the file name “TTEDITOR.C”. You can use this program to analyze the hard disks or floppy disks surface. Even most of the study while writing this book, I have used TTEDITOR to analyze the disk surface or perform the disk modifications.
Some of the important tasks, this editing program can perform are as follows:
- Read per sector information of the surface of hard disks and floppy disks.
- Write the backup of any sector to file.
- Restore the data of the sector from the file.
- Modify the single byte.
- Hexadecimal to Decimal and Binary calculator.
The program uses biosdisk( ) and _bios_disk( ) function to access the disks. If you want to analyze the disk beyond the 8.4 GB, Modify the program with the use of Extensions of INT 13H. The description of the functions, used in the program has been given in the following table:
Function |
Description |
bkground( ) |
creates the back ground and frame of first screen |
clsline( ) |
Used to clear the complete row from the screen specified by row number. |
refresh( ) |
Function to recall all the display functions on the screen |
writetofile( ) |
Function to write the data of a sector to user defined file. |
writetosector( ) |
Function to restore the sector from specified file. |
msgdisp( ) |
Function to display messages on the screen. |
modify( ) |
Function to modify a single byte of any sector, specified by user. |
frame( ) |
Function to draw the frame structure of sector display |
dispmax( ) |
Display maximum CHS number of the disk (Valid Up to 8.4 GB Disk) |
display( ) |
Display the sector and information on the screen. |
hextodec( ) |
Function to Calculate hexadecimal number to corresponding decimal and binary numbers. |
Page Modified on: 18/01/2022