15 void _FATDetectType(
int clus,
int ss){
17 qemu_log(
"[FAT] exFAT");
19 }
else if(clus < 4085){
20 qemu_log(
"[FAT] FAT12");
22 }
else if(clus < 65525){
23 qemu_log(
"[FAT] FAT16");
26 qemu_log(
"[FAT] FAT32");
31 void fatStringPath(
char* String,
int Count){
32 qemu_log(
"[FAT] SP1: %s",String);
34 qemu_log(
"[FAT] SP2: %s",String);
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);
63 void _FATDebugPrintEntity(uint32_t* ent){
65 qemu_log(
"[FAT] Ignore Entity: %d|%x",ent,ent);
68 qemu_log(
"[FAT] Debug Entity: %d|%x",ent,ent);
71 __com_formatString(0x3f8,
"Name => %s\n",e->
Name);
72 __com_formatString(0x3f8,
"Size => %d\n",e->
Size);
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){
82 uint8_t b2 = fat[j + 1];
83 uint8_t b3 = fat[j + 2];
87 uint32_t n1 = ((b2 & 0x0F) << 8) | b1;
88 uint32_t n2 = ((b2 & 0xF0) >> 4) | (b3 << 4);
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]);
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);
108 unsigned int fat_sector = first_fat_sector + (fat_offset / section_size);
109 unsigned int ent_offset = fat_offset % section_size;
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);
119 table_value = table_value & 0x0FFF;
120 qemu_log(
"[FAT] tv3 = %d | %x",table_value);
126 int _FATValide(FAT_BOOT_SECTOR fbs){
131 for (
int i = 1; i <= 128; i=i*2){
132 if (fbs.sectors_per_cluster == i){
137 if (loop_err != 1)
return -1;
139 if(!((fbs.logical_sectors16 == 0 && fbs.logical_sectors32 != 0) || (fbs.logical_sectors16 !=0 && fbs.logical_sectors32 == 0))){
144 if(!(fbs.fat_count == 1 || fbs.fat_count == 2)){
149 if (fbs.fat_count == 2){
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){
157 qemu_log(
"[FAT] [Valid] F1 ERROR Malloc");
160 uint8_t* fat2 = kmalloc(fbs.sectors_per_fat * fbs.bytes_per_sector);
162 qemu_log(
"[FAT] [Valid] F2 ERROR Malloc");
169 read =
_FloppyRead(0,fat1,fat1_pos,fbs.sectors_per_fat);
171 qemu_log(
"[FAT] [Valid] Result: (%x - ERR) | (%x - ERR)",fat1_pos,fat2_pos);
172 qemu_log(
"[FAT] F1 READING %d!=9 bytes.",read);
180 read =
_FloppyRead(0,fat2,fat2_pos,fbs.sectors_per_fat);
182 qemu_log(
"[FAT] [Valid] Result: (%x - PASS) | (%x - ERR)",fat1_pos,fat2_pos);
183 qemu_log(
"[FAT] F2 READING %d!=9 bytes.",read);
191 qemu_log(
"[FAT] [Valid] Result: (%x - PASS) | (%x - PASS)",fat1_pos,fat2_pos);
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;
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);
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++) {
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);
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;
232 if (len == 0)
return 0;
234 uint16_t endOfChainValue = _FATGetClusterValue(1);
235 uint32_t read_size = 0;
236 uint8_t *p = (uint8_t *)data;
239 while (clusterIndex != endOfChainValue && len > (uint32_t)(p-(uint8_t*)data)) {
240 if (read_size + bytesPerCluster > skip) {
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;
247 uint32_t offset = _FATGetClusterValue(clusterIndex);
250 qemu_log(
"[FAT] [READ DATA] Reading %d bytes.",read);
254 read_size += bytesPerCluster;
255 clusterIndex = _FATGetClusterValue(clusterIndex);
257 return p - (uint8_t *)data;
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));
267 read =
_FloppyRead(0,&volume->super,0,
sizeof(FAT_BOOT_SECTOR));
268 qemu_log(
"[FAT] READING %d bytes.",read);
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;
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;
284 uint8_t* fat1 = kmalloc(
sizeof(uint8_t) * volume->super.sectors_per_fat * volume->super.bytes_per_sector);
285 if (fat1 ==
nullptr){
287 qemu_log(
"[FAT] F1 ERROR MALLOC");
290 read =
_FloppyRead(0,fat1,fat1_pos,volume->super.sectors_per_fat);
292 qemu_log(
"[FAT] Result: (%x - ERR)",fat1_pos);
293 qemu_log(
"[FAT] F1 READING %d!=9 bytes.",read);
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");
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;
317 volume->fat_table = converted_fat;
318 int total_sectors = volume_sectors;
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;
324 int fat_size = volume->super.sectors_per_fat;
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);
344 qemu_log(
"[READ] %d",read);
345 qemu_log(
"[READ] Name: %s\nSize: %d",ebat[0].Name,ebat[0].Size);
size_t _FloppyRead(int device, char *dst, uint32_t addr, uint32_t size)
[Floppy] Чтение данных на устройство
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
uint32_t Size
Размер файла в байтах.
char Name[11]
8.3 имя файла. Первые 8 символов — это имя, а последние 3 — расширение.