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)117 UINT  _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