SayoriOS 0.3.3

fat12.c
1
10 #include <kernel.h>
11 #include <io/ports.h>
12 #include <fs/fat12.h>
13 struct volume_t* volume = {0};
14 FAT_ENTRY ebat[32] = {0};
15 void _FATDetectType(int clus, int ss){
16 if (ss == 0){
17 qemu_log("[FAT] exFAT");
18 return;
19 } else if(clus < 4085){
20 qemu_log("[FAT] FAT12");
21 return;
22 } else if(clus < 65525){
23 qemu_log("[FAT] FAT16");
24 return;
25 } else {
26 qemu_log("[FAT] FAT32");
27 return;
28 }
29 }
30
31 void fatStringPath(char* String, int Count){
32 qemu_log("[FAT] SP1: %s",String);
33 String[Count-1] = 0;
34 qemu_log("[FAT] SP2: %s",String);
35 }
36
37 void fatPrint(FAT_BOOT_SECTOR fbs){
38 qemu_log(" |--- jump_code => %d | %d | %d",fbs.jump_code[0],fbs.jump_code[1],fbs.jump_code[2]);
39 qemu_log(" |--- oem_name => %s",fbs.oem_name);
40 qemu_log(" |--- bytes_per_sector => %d",fbs.bytes_per_sector);
41 qemu_log(" |--- sectors_per_cluster => %d",fbs.sectors_per_cluster);
42 qemu_log(" |--- reserved_sectors => %d",fbs.reserved_sectors);
43 qemu_log(" |--- fat_count => %d",fbs.fat_count);
44 qemu_log(" |--- root_dir_capacity => %d",fbs.root_dir_capacity);
45 qemu_log(" |--- logical_sectors16 => %d",fbs.logical_sectors16);
46 qemu_log(" |--- media_type => %d",fbs.media_type);
47 qemu_log(" |--- sectors_per_fat => %d",fbs.sectors_per_fat);
48 qemu_log(" |--- chs_sectors_per_track => %d",fbs.chs_sectors_per_track);
49 qemu_log(" |--- chs_tracks_per_cylinder => %d",fbs.chs_tracks_per_cylinder);
50 qemu_log(" |--- hidden_sectors => %d",fbs.hidden_sectors);
51 qemu_log(" |--- logical_sectors32 => %d",fbs.logical_sectors32);
52 qemu_log(" |--- media_id => %d",fbs.media_id);
53 qemu_log(" |--- chs_head => %d",fbs.chs_head);
54 qemu_log(" |--- ext_bpb_signature => %d",fbs.ext_bpb_signature);
55 qemu_log(" |--- serial_number => %x",fbs.serial_number);
56 qemu_log(" |--- volume_label => %s",fbs.volume_label);
57 qemu_log(" |--- fsid => %s",fbs.fsid);
58 qemu_log(" |--- boot_code => %d|%d|%d|%d|%d|%d|%d|",fbs.boot_code[0],fbs.boot_code[1],fbs.boot_code[2],fbs.boot_code[3],fbs.boot_code[4],fbs.boot_code[5],fbs.boot_code[6]);
59 qemu_log(" |--- magic => %x",fbs.magic);
60
61 }
62
63 void _FATDebugPrintEntity(uint32_t* ent){
64 if (ent == 0x0){
65 qemu_log("[FAT] Ignore Entity: %d|%x",ent,ent);
66 return;
67 }
68 qemu_log("[FAT] Debug Entity: %d|%x",ent,ent);
69 FAT_ENTRY* e = kmalloc((uint32_t)sizeof(FAT_ENTRY));
70 memcpy(ent,&e,(uint32_t)sizeof(FAT_ENTRY));
71 __com_formatString(0x3f8,"Name => %s\n",e->Name);
72 __com_formatString(0x3f8,"Size => %d\n",e->Size);
73
74 //__com_formatString(0x3f8,"[%d] %x | %x\n",i,table[i],table[i+1]);
75 }
76
77 uint32_t* _FATTable(const uint8_t* fat, uint32_t clusters_count){
78 uint32_t * fat_data = kmalloc(sizeof(uint32_t) * (clusters_count+1));
79 if(fat_data == nullptr) return nullptr;
80 for(int i = 0, j = 0; i < (int)clusters_count; i += 2, j+= 3){
81 uint8_t b1 = fat[j];
82 uint8_t b2 = fat[j + 1];
83 uint8_t b3 = fat[j + 2];
84
85 /*uint16_t n1 = ((uint16_t)(b2 & 0x0F) << 8) | b1;
86 uint16_t n2 = ((uint16_t)b3 << 4) | ((b2 & 0xF0) >> 4);*/
87 uint32_t n1 = ((b2 & 0x0F) << 8) | b1;
88 uint32_t n2 = ((b2 & 0xF0) >> 4) | (b3 << 4);
89
90 fat_data[i] = n1;
91 fat_data[i + 1] = n2;
92 }
93 return fat_data;
94 }
95
96 void _FATTableDebug(uint32_t* table,uint32_t clusters_count){
97 qemu_log("[FAT TABLE] DEBUG");
98 for (int i=0; i < (int) clusters_count;i+=2){
99 if (table[i] == 0x0) continue;
100 __com_formatString(0x3f8,"[%d] %x | %x\n",i,table[i],table[i+1]);
101 _FATDebugPrintEntity(table[i]);
102 _FATDebugPrintEntity(table[i+1]);
103 }
104 }
105
106 void _FATDuck(unsigned char* FAT_table,int active_cluster,int first_fat_sector,int section_size){
107 unsigned int fat_offset = active_cluster + (active_cluster / 2);// multiply by 1.5
108 unsigned int fat_sector = first_fat_sector + (fat_offset / section_size);
109 unsigned int ent_offset = fat_offset % section_size;
110
111 //at this point you need to read from sector "fat_sector" on the disk into "FAT_table".
112
113 unsigned short table_value = *(unsigned short*)&FAT_table[ent_offset];
114 qemu_log("[FAT] tv = %d | %x",table_value);
115 if(active_cluster & 0x0001){
116 table_value = table_value >> 4;
117 qemu_log("[FAT] tv2 = %d | %x",table_value);
118 } else {
119 table_value = table_value & 0x0FFF;
120 qemu_log("[FAT] tv3 = %d | %x",table_value);
121 }
122 }
123
124
125
126 int _FATValide(FAT_BOOT_SECTOR fbs){
127 // Step 1 - Сначала проверем ебанный множитель
128 // Я чесно не ебу зачем, но это так написано в документации
129 // Тип поиск подходящего класстера?
130 int loop_err = 0;
131 for (int i = 1; i <= 128; i=i*2){
132 if (fbs.sectors_per_cluster == i){
133 loop_err = 1;
134 break;
135 }
136 }
137 if (loop_err != 1) return -1;
138 // Step 2 - Чекаем логику секторов
139 if(!((fbs.logical_sectors16 == 0 && fbs.logical_sectors32 != 0) || (fbs.logical_sectors16 !=0 && fbs.logical_sectors32 == 0))){
140 // Значения не валидны, съебываем нахуй
141 return -1;
142 }
143 // Step 3 - Проверяем доступные методы работы с FAT
144 if(!(fbs.fat_count == 1 || fbs.fat_count == 2)){
145 // Тоже съебываем, если что-то не так.
146 // Мне проблемы не нужны
147 return -1;
148 }
149 if (fbs.fat_count == 2){
150 // Ясень хуй, мы только с этим типом работать можем
151 uint32_t fat1_pos = fbs.reserved_sectors;
152 uint32_t fat2_pos = fat1_pos + fbs.sectors_per_fat;
153 uint8_t* fat1 = kmalloc(fbs.sectors_per_fat * fbs.bytes_per_sector);
154 if (fat1 == nullptr){
155 kfree(fat1_pos);
156 kfree(fat2_pos);
157 qemu_log("[FAT] [Valid] F1 ERROR Malloc");
158 return -1;
159 }
160 uint8_t* fat2 = kmalloc(fbs.sectors_per_fat * fbs.bytes_per_sector);
161 if(fat2 == nullptr){
162 qemu_log("[FAT] [Valid] F2 ERROR Malloc");
163 kfree(fat1);
164 kfree(fat1_pos);
165 kfree(fat2_pos);
166 return -1;
167 }
168 int read = 0;
169 read = _FloppyRead(0,fat1,fat1_pos,fbs.sectors_per_fat);
170 if (read != 9){
171 qemu_log("[FAT] [Valid] Result: (%x - ERR) | (%x - ERR)",fat1_pos,fat2_pos);
172 qemu_log("[FAT] F1 READING %d!=9 bytes.",read);
173 kfree(fat1);
174 kfree(fat2);
175 kfree(fat1_pos);
176 kfree(fat2_pos);
177 kfree(read);
178 return -1;
179 }
180 read = _FloppyRead(0,fat2,fat2_pos,fbs.sectors_per_fat);
181 if (read != 9){
182 qemu_log("[FAT] [Valid] Result: (%x - PASS) | (%x - ERR)",fat1_pos,fat2_pos);
183 qemu_log("[FAT] F2 READING %d!=9 bytes.",read);
184 kfree(fat1);
185 kfree(fat2);
186 kfree(fat1_pos);
187 kfree(fat2_pos);
188 kfree(read);
189 return -1;
190 }
191 qemu_log("[FAT] [Valid] Result: (%x - PASS) | (%x - PASS)",fat1_pos,fat2_pos);
192 kfree(fat1);
193 kfree(fat2);
194 kfree(fat1_pos);
195 kfree(fat2_pos);
196 kfree(read);
197 return 1;
198 }
199 return -1;
200 }
201
202
203 uint16_t _FATGetClusterValue(uint32_t cl){
204 int root = (volume->super.reserved_sectors + 0 * volume->super.sectors_per_fat) * volume->super.bytes_per_sector;
205 uint16_t data;
206 int read = 0;
207 read = _FloppyRead(0,&data,root + cl * sizeof(data),sizeof(data));
208 qemu_log("[FAT] [Get Cluster Value] Reading %d bytes. Value: %d|%x",read,data,data);
209 kfree(read);
210 return data;
211 //_FATDebugPrintEntity(data);
212 }
213
214 addr_t _FATFindEntry(uint32_t clusterIndex, bool free, int32_t skip, int32_t* index) {
215 uint16_t rootEntryCount = volume->super.root_dir_capacity;
216 uint32_t start = _FATGetClusterValue(clusterIndex);
217 for (int32_t offset = skip; offset < rootEntryCount; offset++) {
218 struct dir_entry_t *entry = kmalloc(sizeof(struct dir_entry_t));
219 _FloppyRead(0,&entry,start + offset * sizeof(struct dir_entry_t) + offsetof(struct dir_entry_t, name),sizeof(struct dir_entry_t));
220 if (free ^ (entry->name[0] != ENTRY_AVAILABLE && entry->name[0] != ENTRY_ERASED)) {
221 if (index) *index = offset;
222 return start + offset * sizeof(struct dir_entry_t);
223 }
224 }
225 }
226
227
228 int _FATReadData(uint32_t clusterIndex, void* data, uint32_t len, size_t skip) {
229 uint32_t bytesPerCluster = volume->super.sectors_per_cluster * volume->super.bytes_per_sector;
230
231 // Skip empty files
232 if (len == 0) return 0;
233
234 uint16_t endOfChainValue = _FATGetClusterValue(1);
235 uint32_t read_size = 0;
236 uint8_t *p = (uint8_t *)data;
237
238 // Copy data one cluster at a time.
239 while (clusterIndex != endOfChainValue && len > (uint32_t)(p-(uint8_t*)data)) {
240 if (read_size + bytesPerCluster > skip) {
241 // Determine amount of data to copy
242 uint32_t start = read_size > skip ? 0 : skip - read_size;
243 uint32_t count = len - (p-(uint8_t*)data);
244 if (count > bytesPerCluster) count = bytesPerCluster;
245
246 // Transfer bytes into image at cluster location
247 uint32_t offset = _FATGetClusterValue(clusterIndex);
248 int read = 0;
249 read = _FloppyRead(0,p,offset+start,count);
250 qemu_log("[FAT] [READ DATA] Reading %d bytes.",read);
251 //disk_read(d, p, offset+start, count);
252 p += count;
253 }
254 read_size += bytesPerCluster;
255 clusterIndex = _FATGetClusterValue(clusterIndex);
256 }
257 return p - (uint8_t *)data;
258 }
259
260 void fatTest(){
261 qemu_log("[FAT] В пизду"); return;
262 qemu_log("[FAT] TEST INIT");
263 qemu_log("[FAT] Struct\n\tvolume_t: %d\n\tFAT_BOOT_SECTOR: %d",sizeof(struct volume_t),sizeof(FAT_BOOT_SECTOR));
264 qemu_log("[FAT] Trying to allocate %d bytes for a struct",sizeof(struct volume_t));
265
266 int read = 0;
267 read = _FloppyRead(0,&volume->super,0,sizeof(FAT_BOOT_SECTOR));
268 qemu_log("[FAT] READING %d bytes.",read);
269 //fatStringPath(volume->super.oem_name,8); ///> Вроде не требуется этот момент патчить
270 fatStringPath(volume->super.volume_label,11);
271 fatStringPath(volume->super.fsid,8);
272 fatPrint(volume->super);
273 if (_FATValide(volume->super) != 1) return;
274 uint32_t fat1_pos = volume->super.reserved_sectors;
275 uint32_t root_dir_pos = fat1_pos + volume->super.fat_count * volume->super.sectors_per_fat;
276 uint32_t root_dir_sectors = (volume->super.root_dir_capacity * (uint32_t)sizeof(FAT_ENTRY)) / volume->super.bytes_per_sector;
277 if((volume->super.root_dir_capacity * (uint32_t)sizeof(FAT_ENTRY)) % volume->super.bytes_per_sector != 0){
278 root_dir_sectors += 1;
279 }
280 uint32_t clusters2_pos = root_dir_pos + root_dir_sectors;
281 uint32_t volume_sectors = volume->super.logical_sectors16 == 0 ? volume->super.logical_sectors32 : volume->super.logical_sectors16;
282 uint32_t data_clusters = (volume_sectors - (volume->super.fat_count * volume->super.sectors_per_fat) - root_dir_sectors ) / volume->super.sectors_per_cluster;
283
284 uint8_t* fat1 = kmalloc(sizeof(uint8_t) * volume->super.sectors_per_fat * volume->super.bytes_per_sector);
285 if (fat1 == nullptr){
286 kfree(volume);
287 qemu_log("[FAT] F1 ERROR MALLOC");
288 return;
289 }
290 read = _FloppyRead(0,fat1,fat1_pos,volume->super.sectors_per_fat);
291 if (read != 9){
292 qemu_log("[FAT] Result: (%x - ERR)",fat1_pos);
293 qemu_log("[FAT] F1 READING %d!=9 bytes.",read);
294 kfree(fat1);
295 kfree(fat1_pos);
296 kfree(read);
297 return;
298 }
299
300
301 int RootTable = (volume->super.reserved_sectors + 0 * volume->super.sectors_per_fat) * volume->super.bytes_per_sector;
302 qemu_log("RootTable: %d|%x",RootTable,RootTable);
303 uint32_t * converted_fat = _FATTable(fat1, data_clusters + 2);
304 if(converted_fat == nullptr){
305 qemu_log("[FAT] Fatal Table");
306 kfree(fat1);
307 kfree(volume);
308 return;
309 }
310 kfree(fat1);
311 _FATTableDebug(converted_fat,data_clusters + 2);
312 volume->fat1_pos = fat1_pos;
313 volume->cluster2_pos = clusters2_pos;
314 volume->root_pos = root_dir_pos;
315 volume->root_sectors = root_dir_sectors;
316 //volume->disk = pdisk;
317 volume->fat_table = converted_fat;
318 int total_sectors = volume_sectors;
319
320 uint32_t rds = ((volume->super.root_dir_capacity * 32) + (volume->super.bytes_per_sector - 1)) / volume->super.bytes_per_sector;
321 int first_data_sector = volume->super.reserved_sectors + (volume->super.fat_count * volume_sectors) + root_dir_sectors;
322 int first_fat_sector = volume->super.reserved_sectors;
323
324 int fat_size = volume->super.sectors_per_fat;
325
326 int data_sectors = volume_sectors - (volume->super.reserved_sectors + (volume->super.fat_count * fat_size) + root_dir_sectors);
327 int total_clusters = data_sectors / volume->super.sectors_per_cluster;
328 qemu_log("[FAT] Init Complete");
329 qemu_log("volume_sectors: %d",volume_sectors);
330 qemu_log("data_clusters: %d",data_clusters);
331 qemu_log("root_dir_sectors: %d|%d",root_dir_sectors,rds);
332 qemu_log("first_data_sector: %d",first_data_sector);
333 qemu_log("first_fat_sector: %d",first_fat_sector);
334 qemu_log("total_clusters: %d",total_clusters);
335 int first_root_dir_sector = first_data_sector - root_dir_sectors ;
336 qemu_log("first_root_dir_sector: %d",first_root_dir_sector);
337 int first_sector_of_cluster = ((0 - 2) * volume->super.sectors_per_cluster) + first_data_sector;
338 qemu_log("first_sector_of_cluster: %d",first_sector_of_cluster);
339
340 //uint16_t frds = _FATGetClusterValue(first_root_dir_sector);
341
342 //FAT_ENTRY *e = kmalloc(sizeof(FAT_ENTRY*));
343 read = _FloppyRead(0,&ebat[0],first_data_sector,sizeof(FAT_ENTRY));
344 qemu_log("[READ] %d",read);
345 qemu_log("[READ] Name: %s\nSize: %d",ebat[0].Name,ebat[0].Size);
346 //__com_formatString(0x3f8,"Name => %s\n",e->Name);
347 //__com_formatString(0x3f8,"Size => %d\n",e->Size);
348 uint32_t data = 0;
355 //_FATDebugPrintEntity(first_sector_of_cluster);
356 //_FATGetClusterValue(0);
357 //_FATGetClusterValue(first_root_dir_sector);
358 //_FATDuck(converted_fat,0,int first_fat_sector,int section_size);
359 //_FATDetectType(total_clusters,1);
360 return;
361
362 //qemu_log("[FAT] volume_label: %s",volume->super.volume_label);
363 }
364
_FloppyRead
size_t _FloppyRead(int device, char *dst, uint32_t addr, uint32_t size)
[Floppy] Чтение данных на устройство
Definition: floppy.c:343
memcpy
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
FAT_ENTRY
Definition: fat12.h:48
FAT_ENTRY::Size
uint32_t Size
Размер файла в байтах.
Definition: fat12.h:60
FAT_ENTRY::Name
char Name[11]
8.3 имя файла. Первые 8 символов — это имя, а последние 3 — расширение.
Definition: fat12.h:49
dir_entry_t
Definition: fat12.h:63
volume_t
Definition: fat12.h:78