4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice, this
11 * list of conditions and the following disclaimer in the documentation and/or
12 * other materials provided with the distribution.
14 * Neither the name of the NXP Semiconductor nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
41 int Fat::Open(string filename
)
43 m_filename
= filename
;
45 shared_ptr
<FileBuffer
> pbuff
= get_file_buffer(m_filename
);
48 if (pbuff
->size() < 512)
50 set_last_err_string("File too small");
53 if (pbuff
->at(510) != 0x55|| pbuff
->at(511) != 0xAA)
55 set_last_err_string("Partition signature miss matched");
59 Partition
*pPart
= (Partition
*)(pbuff
->data() + 446);
61 m_fat_part_start
= pPart
->lba_start
* 512;
63 uint8_t *boot
= pbuff
->data() + m_fat_part_start
;
64 if (boot
[510] != 0x55 || boot
[511] != 0xAA)
66 set_last_err_string("Boot Sector signature miss matched");
70 m_logical_sector_perfat
= boot
[0x16];
71 m_logical_sector_perfat
+= boot
[0x17] << 8;
72 if (m_logical_sector_perfat
== 0)
74 m_logical_sector_perfat
= boot
[0x24];
75 m_logical_sector_perfat
+= boot
[0x25] << 8;
76 m_logical_sector_perfat
+= boot
[0x26] << 16;
77 m_logical_sector_perfat
+= boot
[0x27] << 24;
80 m_fat_table_offset
= boot
[0xE];
81 m_fat_table_offset
+= boot
[0xF] << 8;
83 m_fat_table_offset
*= 512;
85 m_cluster
= boot
[0xD];
88 int num_of_fat
= boot
[0x10];
90 m_root_dir_offset
= m_logical_sector_perfat
* 512 * num_of_fat
+ m_fat_table_offset
;
92 m_num_of_rootdir
= boot
[0x11];
93 m_num_of_rootdir
= boot
[0x12] << 8;
96 entry
= (FatDirEntry
*)(boot
+ m_root_dir_offset
);
99 for (int i
= 0; i
< m_num_of_rootdir
; i
++)
102 if (entry
->attr
== 0x8)
105 if (entry
->filename
[0] == 0)
110 while (entry
->attr
== 0xF)
112 filename
.insert(0, lfn2string((FatLFN
*)entry
));
116 if (filename
.empty())
118 filename
.append((char*)entry
->filename
, 8);
121 filename
.append(".");
122 filename
.append((char*)entry
->ext
, 3);
125 m_filemap
[filename
] = *entry
;
128 if (entry
->filename
[0] == 0)
134 int Fat::get_next_cluster(shared_ptr
<FileBuffer
> p
, int cluster
)
136 uint16_t *pfat
= (uint16_t*)(p
->data() + m_fat_part_start
+ m_fat_table_offset
);
137 return pfat
[cluster
];
140 void *Fat::get_data_buff(shared_ptr
<FileBuffer
> p
, int cluster
)
142 void *p1
= p
->data() + m_fat_part_start
+ m_root_dir_offset
+ (cluster
-2) * m_cluster
+ m_num_of_rootdir
* 32;
146 int Fat::get_file_buff(string filename
, shared_ptr
<FileBuffer
>p
)
148 if (m_filemap
.find(filename
) == m_filemap
.end())
151 err
= "Can't find file ";
153 set_last_err_string(err
);
157 shared_ptr
<FileBuffer
> pbuff
= get_file_buffer(m_filename
);
159 size_t filesize
= m_filemap
[filename
].file_size
;
162 int cur
= m_filemap
[filename
].start_cluster
;
165 for (off
= 0; off
< filesize
; off
+= m_cluster
)
174 set_last_err_string("Early finished at fat");
177 void *pcluster
= get_data_buff(pbuff
, cur
);
178 memcpy(p
->data() + off
, pcluster
, sz
);
180 cur
= get_next_cluster(pbuff
, cur
);
185 std::string
Fat::lfn2string(FatLFN
*p
)
188 for (int i
= 0; i
< 10; i
+= 2)
189 if (p
->name1
[i
] == 0)
194 for (int i
= 0; i
< 12; i
+= 2)
195 if (p
->name2
[i
] == 0)
200 for (int i
= 0; i
< 4; i
+= 2)
201 if (p
->name3
[i
] == 0)