use ref_name as release name
[mfgtools.git] / libuuu / fat.cpp
blob816ccf7e0502b005ce194f394384034adaa1bb40
1 /*
2 * Copyright 2018 NXP.
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.
32 #include <string.h>
33 #include <iostream>
34 #include <fstream>
35 #include "libcomm.h"
36 #include "libuuu.h"
37 #include "liberror.h"
39 #include "fat.h"
41 int Fat::Open(string filename)
43 m_filename = filename;
45 shared_ptr<FileBuffer> pbuff = get_file_buffer(m_filename);
46 if (pbuff == nullptr)
47 return -1;
48 if (pbuff->size() < 512)
50 set_last_err_string("File too small");
51 return -1;
53 if (pbuff->at(510) != 0x55|| pbuff->at(511) != 0xAA)
55 set_last_err_string("Partition signature miss matched");
56 return -1;
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");
67 return -1;
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];
86 m_cluster *= 512;
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;
95 FatDirEntry *entry;
96 entry = (FatDirEntry*)(boot + m_root_dir_offset);
97 m_filemap.clear();
99 for (int i = 0; i < m_num_of_rootdir; i++)
101 string filename;
102 if (entry->attr == 0x8)
103 entry++;
105 if (entry->filename[0] == 0)
106 break;
108 filename.clear();
110 while (entry->attr == 0xF)
112 filename.insert(0, lfn2string((FatLFN *)entry));
113 entry++;
116 if (filename.empty())
118 filename.append((char*)entry->filename, 8);
119 if (entry->ext[0])
121 filename.append(".");
122 filename.append((char*)entry->ext, 3);
125 m_filemap[filename] = *entry;
126 entry++;
128 if (entry->filename[0] == 0)
129 break;
131 return 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;
143 return p1;
146 int Fat::get_file_buff(string filename, shared_ptr<FileBuffer>p)
148 if (m_filemap.find(filename) == m_filemap.end())
150 string err;
151 err = "Can't find file ";
152 err += filename;
153 set_last_err_string(err);
154 return -1;
157 shared_ptr<FileBuffer> pbuff = get_file_buffer(m_filename);
159 size_t filesize = m_filemap[filename].file_size;
160 p->resize(filesize);
162 int cur = m_filemap[filename].start_cluster;
164 size_t off;
165 for (off = 0; off < filesize; off += m_cluster)
167 size_t sz;
168 sz = filesize - off;
169 if (sz > m_cluster)
170 sz = m_cluster;
172 if (cur == 0xFFFF)
174 set_last_err_string("Early finished at fat");
175 return -1;
177 void *pcluster = get_data_buff(pbuff, cur);
178 memcpy(p->data() + off, pcluster, sz);
180 cur = get_next_cluster(pbuff, cur);
182 return 0;
185 std::string Fat::lfn2string(FatLFN *p)
187 string str;
188 for (int i = 0; i < 10; i += 2)
189 if (p->name1[i] == 0)
190 return str;
191 else
192 str += p->name1[i];
194 for (int i = 0; i < 12; i += 2)
195 if (p->name2[i] == 0)
196 return str;
197 else
198 str += p->name2[i];
200 for (int i = 0; i < 4; i += 2)
201 if (p->name3[i] == 0)
202 return str;
203 else
204 str += p->name3[i];
206 return str;