1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12 /**************************************************************************/ 13 /**************************************************************************/ 14 /** */ 15 /** FileX Component */ 16 /** */ 17 /** Media */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 #define FX_SOURCE_CODE 23 24 25 /* Include necessary system files. */ 26 27 #include "fx_api.h" 28 #include "fx_system.h" 29 #include "fx_media.h" 30 #include "fx_utility.h" 31 32 33 /**************************************************************************/ 34 /* */ 35 /* FUNCTION RELEASE */ 36 /* */ 37 /* _fx_media_boot_info_extract PORTABLE C */ 38 /* 6.1.10 */ 39 /* AUTHOR */ 40 /* */ 41 /* William E. Lamie, Microsoft Corporation */ 42 /* */ 43 /* DESCRIPTION */ 44 /* */ 45 /* This function extracts and validates the information from the boot */ 46 /* record found in the memory buffer. If the boot record is invalid, */ 47 /* an FX_MEDIA_INVALID status is returned to the caller. */ 48 /* */ 49 /* The FAT boot sector (512 bytes) that is operated on by this */ 50 /* function must look like the following: */ 51 /* */ 52 /* Byte Offset Meaning Size */ 53 /* */ 54 /* 0x000 Jump Instructions 3 */ 55 /* 0x003 OEM Name 8 */ 56 /* 0x00B *Bytes per Sector 2 */ 57 /* 0x00D *Sectors per Cluster 1 */ 58 /* 0x00E *Reserved Sectors 2 */ 59 /* 0x010 *Number of FATs 1 */ 60 /* 0x011 *Max Root Dir Entries 2 */ 61 /* 0x013 *Number of Sectors 2 */ 62 /* 0x015 Media Type 1 */ 63 /* 0x016 *Sectors per FAT 2 */ 64 /* 0x018 *Sectors per Track 2 */ 65 /* 0x01A *Number of Heads 2 */ 66 /* 0x01C *Hidden Sectors 4 */ 67 /* 0x020 *Huge Sectors 4 */ 68 /* 0x024 Drive Number 1 */ 69 /* 0x025 Reserved 1 */ 70 /* 0x026 Boot Signature 1 */ 71 /* 0x027 Volume ID 4 */ 72 /* 0x02B Volume Label 11 */ 73 /* 0x036 File System Type 8 */ 74 /* ... ... ... */ 75 /* 0x1FE **Signature (0x55aa) 2 */ 76 /* */ 77 /* * Denotes which elements of the boot record */ 78 /* FileX uses. */ 79 /* */ 80 /* **Denotes the element is checked by the I/O */ 81 /* driver. This eliminates the need for a minimum */ 82 /* 512-byte buffer for FileX. */ 83 /* */ 84 /* Note: All values above are in little endian format, i.e. the LSB is */ 85 /* in the lowest address. */ 86 /* */ 87 /* INPUT */ 88 /* */ 89 /* media_ptr Media control block pointer */ 90 /* */ 91 /* OUTPUT */ 92 /* */ 93 /* return status */ 94 /* */ 95 /* CALLS */ 96 /* */ 97 /* _fx_utility_16_unsigned_read Read a UINT from buffer */ 98 /* _fx_utility_32_unsigned_read Read a ULONG from buffer */ 99 /* _fx_utility_64_unsigned_read Read a ULONG64 from memory */ 100 /* */ 101 /* CALLED BY */ 102 /* */ 103 /* _fx_media_open Media open function */ 104 /* */ 105 /* RELEASE HISTORY */ 106 /* */ 107 /* DATE NAME DESCRIPTION */ 108 /* */ 109 /* 05-19-2020 William E. Lamie Initial Version 6.0 */ 110 /* 09-30-2020 William E. Lamie Modified comment(s), */ 111 /* resulting in version 6.1 */ 112 /* 01-31-2022 Bhupendra Naphade Modified comment(s), added */ 113 /* check for bimap cache size, */ 114 /* resulting in version 6.1.10 */ 115 /* */ 116 /**************************************************************************/ _fx_media_boot_info_extract(FX_MEDIA * media_ptr)117UINT _fx_media_boot_info_extract(FX_MEDIA *media_ptr) 118 { 119 120 UCHAR *boot_sector; 121 122 123 /* Move the buffer pointer into a local copy. */ 124 boot_sector = media_ptr -> fx_media_driver_buffer; 125 126 /* Extract the number of bytes per sector. */ 127 media_ptr -> fx_media_bytes_per_sector = _fx_utility_16_unsigned_read(&boot_sector[FX_BYTES_SECTOR]); 128 if (media_ptr -> fx_media_bytes_per_sector == 0) 129 return(FX_MEDIA_INVALID); 130 131 132 /* FAT12/16/32 volume. */ 133 /* Extract the number of sectors per track. */ 134 media_ptr -> fx_media_sectors_per_track = _fx_utility_16_unsigned_read(&boot_sector[FX_SECTORS_PER_TRK]); 135 136 /* Extract the number of heads. */ 137 media_ptr -> fx_media_heads = _fx_utility_16_unsigned_read(&boot_sector[FX_HEADS]); 138 139 /* Extract the total number of sectors. */ 140 media_ptr -> fx_media_total_sectors = _fx_utility_16_unsigned_read(&boot_sector[FX_SECTORS]); 141 if (media_ptr -> fx_media_total_sectors == 0) 142 { 143 media_ptr -> fx_media_total_sectors = _fx_utility_32_unsigned_read(&boot_sector[FX_HUGE_SECTORS]); 144 } 145 146 if (media_ptr -> fx_media_total_sectors == 0) 147 { 148 return(FX_MEDIA_INVALID); 149 } 150 151 /* Extract the number of reserved sectors before the first FAT. */ 152 media_ptr -> fx_media_reserved_sectors = _fx_utility_16_unsigned_read(&boot_sector[FX_RESERVED_SECTORS]); 153 if (media_ptr -> fx_media_reserved_sectors == 0) 154 { 155 return(FX_MEDIA_INVALID); 156 } 157 158 /* Extract the number of sectors per cluster. */ 159 media_ptr -> fx_media_sectors_per_cluster = ((UINT)boot_sector[FX_SECTORS_CLUSTER] & 0xFF); 160 161 /* There should always be at least one reserved sector, representing the boot record itself. */ 162 if (media_ptr -> fx_media_sectors_per_cluster == 0) 163 { 164 return(FX_MEDIA_INVALID); 165 } 166 167 /* Extract the number of sectors per FAT. */ 168 media_ptr -> fx_media_sectors_per_FAT = _fx_utility_16_unsigned_read(&boot_sector[FX_SECTORS_PER_FAT]); 169 if (media_ptr -> fx_media_sectors_per_FAT == 0) 170 { 171 media_ptr -> fx_media_sectors_per_FAT = _fx_utility_32_unsigned_read(&boot_sector[FX_SECTORS_PER_FAT_32]); 172 } 173 174 if (media_ptr -> fx_media_sectors_per_FAT == 0) 175 { 176 return(FX_MEDIA_INVALID); 177 } 178 179 /* Extract the number of FATs. */ 180 media_ptr -> fx_media_number_of_FATs = ((UINT)boot_sector[FX_NUMBER_OF_FATS] & 0xFF); 181 if (media_ptr -> fx_media_number_of_FATs == 0) 182 { 183 return(FX_BOOT_ERROR); 184 } 185 186 /* Extract the number of hidden sectors. */ 187 #ifdef FX_DRIVER_USE_64BIT_LBA 188 media_ptr -> fx_media_hidden_sectors = _fx_utility_64_unsigned_read(&boot_sector[FX_HIDDEN_SECTORS]); 189 #else 190 media_ptr -> fx_media_hidden_sectors = _fx_utility_32_unsigned_read(&boot_sector[FX_HIDDEN_SECTORS]); 191 #endif 192 /* Extract the number of root directory entries. */ 193 media_ptr -> fx_media_root_directory_entries = _fx_utility_16_unsigned_read(&boot_sector[FX_ROOT_DIR_ENTRIES]); 194 195 /* Extract root directory starting cluster (32 bit only) and compute start sector */ 196 media_ptr -> fx_media_root_cluster_32 = _fx_utility_32_unsigned_read(&boot_sector[FX_ROOT_CLUSTER_32]); 197 198 199 /* Return a successful status. */ 200 return(FX_SUCCESS); 201 } 202 203