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 
size_t _FloppyRead(int device, char *dst, uint32_t addr, uint32_t size)
[Floppy] Чтение данных на устройство
Definition: floppy.c:343
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
uint32_t Size
Размер файла в байтах.
Definition: fat12.h:60
char Name[11]
8.3 имя файла. Первые 8 символов — это имя, а последние 3 — расширение.
Definition: fat12.h:49
Definition: fat12.h:63
Definition: fat12.h:78