Extract Floppy Disk Geometry from the Boot Sector

Introduction

This article explains the structure of the BOOT sector of a floppy disk, which is formatted in the Windows environment for the FAT File System.

The boot sector in a floppy disk resides in sector zero (0) of the disk. The size of the boot sector will always be 512 bytes for a floppy formatted with FAT. In the FAT file system, the boot code is closely interwoven with the file system. In this article, you will learn how to interpret this data to get floppy disk geometry.

Floppy Disk BOOT Sector Analysis

As I mentioned before, the boot sector size for a floppy disk is 512 bytes. Out of these 512 bytes, the first 36 bytes contain important information about floppy disk geometry. Before starting to dig in this area, please refer to the FAT specification as mentioned by Microsoft at http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx.

Data Structure for FAT Boot Sector

Byte Range Stored Information
0 - 2 Assembly Instruction for jump code.
3 - 10 OEM Name.
11 - 12 Bytes per sector.
13 Sector per cluster.
14 - 15 Number of reserved sector(Boot Sector)
16 Number of File Allocation Table
17 - 18 Maximum entries possible under root directory.
19 - 20 Total number of sectors in file system.
21 Media Type(According to Microsoft 0xf8 for fixed disk and 0xf0 for removable disk.
22 - 23 Sectors allocated for each File allocation table.
24 - 25 Sectors per track.
26 - 27 Number of head in storage device.
28 - 31 Number of sectors before start of partition(Not applicable for floppy).
32 - 35 Number of sectors in file system(32-bit value, not applicable for floppy).
36 BIOS INT13h drive number.
37 Not Used.
38 Extended boot signature.
39 - 42 Volume Serial Number.
43 - 53 Volume label in ASCII.
54 - 61 File System Type.
62 - 509 Boot Code, otherwise contains information to replace disk.
510 - 511 Signature for File System.

Data Structure for C++

From the above mentioned table, you got the boot sector information for a floppy disk formatted with FAT. Your next step will be to create a equivalent data structure in C++ to hold data read from the boot structure. So, I have created one structure as shown below:

typedef struct _BIOS_PARAM_BLOCK
{
   BYTE jumpCode[3];
   BYTE oemName[8];
   WORD bytes_Sector;
   BYTE sec_Cluster;
   WORD size_Sector_Reserved;
   BYTE fatCount;
   WORD Max_Root_Entry;
   WORD Total_Sector_FS;
   BYTE Media_Type;
   WORD sectors_per_fat;
   WORD sectors_per_track;
   WORD total_Head_Count;
   DWORD no_Sectors_Before_Part;
   DWORD no_Sector_FS32;
   BYTE BIOS_13h_Drive_No;
   BYTE reserved;
   BYTE ext_Boot_Part_Signature;
   DWORD vol_Serial_Number;
   BYTE vol_Lebel_Name[11];
   BYTE FS_Type[8];
   BYTE boot_Code[448];
   WORD signature;
} BPB;

Now, the structure is ready to hold data from the boot sector. The next step is to open the device and read sector zero. (This is the boot sector for a floppy formatted with FAT.) This step can be achieved with two WIN32 APIs, "CreateFile()" and "ReadFile()". For details of these two API, please refer to the MSDN documentation.

How to use the CreateFile() API

Please look at the following code:

HANDLE hFloppy = NULL;
hFloppy = CreateFile(
          "\\\\.\\A:",        // Floppy drive to open
          GENERIC_READ,       // Access mode
          FILE_SHARE_READ,    // Share Mode
          NULL,               // Security Descriptor
          OPEN_EXISTING,      // How to create
          0,                  // File attributes
          NULL);              // Handle to template

This code snippet opens a floppy disk and returns a handle. This handle will be used to read the floppy boot sector.

Integrate CreateFile() API with the ReadFile() API

The following code snippet is used to read the boot sector for a floppy and store it into a buffer of size 512. Then, I used memcpy() to copy the boot information from the buffer to the structured data.

#pragma pack(1)
typedef struct _BIOS_PARAM_BLOCK
{
   BYTE jumpCode[3];
   BYTE oemName[8];
   WORD bytes_Sector;
   BYTE sec_Cluster;
   WORD size_Sector_Reserved;
   BYTE fatCount;
   WORD Max_Root_Entry;
   WORD Total_Sector_FS;
   BYTE Media_Type;
   WORD sectors_per_fat;
   WORD sectors_per_track;
   WORD total_Head_Count;
   DWORD no_Sectors_Before_Part;
   DWORD no_Sector_FS32;
   BYTE BIOS_13h_Drive_No;
   BYTE reserved;
   BYTE ext_Boot_Part_Signature;
   DWORD vol_Serial_Number;
   BYTE vol_Lebel_Name[11];
   BYTE FS_Type[8];
   BYTE boot_Code[448];
   WORD signature;
} BPB;
#pragma pack()

void PrintFloppyInformation(BPB _bpb);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
   int nRetCode = 0;
   // initialize MFC and print an error on failure
   if (!AfxWinInit(::GetModuleHandle(NULL), NULL,
       ::GetCommandLine(), 0))
   {
      // TODO: change error code to suit your needs
      cerr << _T("Fatal Error: MFC initialization failed") << endl;
      nRetCode = 1;
   }
   else
   {
      // TODO: code your application's behavior here.
      BYTE bBootSector[512];
      memset(bBootSector, 0, 512);
      DWORD dwBytesRead(0);
      BPB _bpb;

      HANDLE hFloppy = NULL;
      hFloppy = CreateFile("\\\\.\\A:",    // Floppy drive to open
                GENERIC_READ,              // Access mode
                FILE_SHARE_READ,           // Share Mode
                NULL,                      // Security Descriptor
                OPEN_EXISTING,             // How to create
                0,                         // File attributes
                NULL);                     // Handle to template

      if(hFloppy != NULL)
      {
         // Read the boot sector
         if (!ReadFile(hFloppy, bBootSector, 512, &dwBytesRead, NULL))
         {
            printf("Error in reading floppy disk\n");
         }
         else
         {
            memcpy(&_bpb, bBootSector, 512);
            // Print floppy information on Console.
            PrintFloppyInformation(_bpb);
         }

         CloseHandle(hFloppy);
         // Close the handle
      }
   }

   return nRetCode;
}

Now, I have printed values on the console using the following code snippet.

void PrintFloppyInformation(BPB _bpb)
{
   printf("Floppy Disk Information: \n");
   printf("===========================\n");
   printf("Assembly Instruction to jump to Boot code: 0x%x\n",
          _bpb.jumpCode);
   printf("OEM Name: %s\n", _bpb.oemName);
   printf("Bytes per sector: %d\n", _bpb.bytes_Sector);
   printf("Sector per cluster: %d\n", _bpb.sec_Cluster);
   printf("Size in sector for reserved area(Boot Sector): %d\n",
          _bpb.size_Sector_Reserved);
   printf("Number of FATs(File Allocation Table): %d\n",
          _bpb.fatCount);
   printf("Number of files for root directory: %d\n",
           _bpb.Max_Root_Entry);
   printf("Number of Sectors in File System: %d\n",
          _bpb.Total_Sector_FS);
   printf("Media Type\n(According to Microsoft,
          0xF8 == fixed disk and 0xF0 == Removable disk):
          0x%x\n", _bpb.Media_Type);
   printf("Number of Sectors for each FAT: %d\n",
          _bpb.sectors_per_fat);
   printf("Sectors per track: %d\n", _bpb.sectors_per_track);
   printf("Number of head in storage device: %d\n",
          _bpb.total_Head_Count);
   printf("BIOS INT13h Drive number: 0x%x\n", _bpb.BIOS_13h_Drive_No);
   printf("Volume Serial Number: %d\n", _bpb.vol_Serial_Number);
   printf("Volume label Name: %s\n", _bpb.vol_Lebel_Name);
   printf("Boot Sector Signature: 0x%x\n", _bpb.signature);
}

That's all. Now, run the program and you will have all the information about a floppy disk. Please look at following picture and assemble all the required information and floppy disk geometry is in front of you.

Do some calculation based on the picture above:

  1. 0th Sector reserved one (Boot Sector).
  2. The next 18 sectors are allocated for FAT (you have two copies of the FAT with nine sectors each).
  3. It means that the First 19 sectors for Boot Sector + FATs.
  4. The next few sectors are for file name entry with cluster address (called as root directory).
  5. Now, from the picture above, it is clear that the FAT for a floppy will have 224 max entries.
  6. Each entry is 32 bytes in size. Then total bytes are allocated for root entries are (32*224) bytes, which is 7168 bytes.
  7. 7168 bytes is equal to 14 sectors because each sector is 512 bytes in size.
  8. You have 2880 total sectors for the floppy. Please refer to the picture above.
  9. Out of the 2880 sectors for the floppy, the boot sector + FATs sectors + Root Directory sectors are fixed. This comes to 33 sectors altogether.
  10. The rest of the sectors are used for data storage. In other words, 2847 sectors are used for data storage.

So, in summary, the floppy geometry looks like the following figure:



About the Author

Mufti Mohammed

Small-Talk and Small-Programming working together. My Blog

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Event Date: April 15, 2014 The ability to effectively set sales goals, assign quotas and territories, bring new people on board and quickly make adjustments to the sales force is often crucial to success--and to the field experience! But for sales operations leaders, managing the administrative processes, systems, data and various departments to get it all right can often be difficult, inefficient and manually intensive. Register for this webinar and learn how you can: Align sales goals, quotas and …

  • Live Event Date: August 14, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Data protection has long been considered "overhead" by many organizations in the past, many chalking it up to an insurance policy or an extended warranty you may never use. The realities of today makes data protection a must-have, as we live in a data-driven society -- the digital assets we create, share, and collaborate with others on must be managed and protected for many purposes. Check out this upcoming eSeminar and join Seagate Cloud …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds