SayoriOS  0.3.3
fat32.c
1 
10 #include <common.h>
11 #include <fs/fat32.h>
12 #include <io/ports.h>
13 #include <lib/string.h>
14 
15 #include "drv/disk/dpm.h"
16 #include "mem/vmm.h"
17 #include "lib/utf_conversion.h"
18 #include "lib/math.h"
19 #include "fmt/tga.h"
20 #include "io/rgb_image.h"
21 #include "lib/libstring/string.h"
22 #include "lib/php/pathinfo.h"
23 
24 size_t fs_fat32_read(char Disk, const char* Path, size_t Offset, size_t Size,void* Buffer){
25  size_t clust = fs_fat32_evaluate(Disk, Path, true);
26 
27  if(clust == 0) {
28  return 0;
29  }
30 
31  char* filename = pathinfo(Path, PATHINFO_BASENAME);
32 
33 // fat_file_info_t info = fs_fat32_get_object_info(Disk, filename, clust);
34 
35  fs_fat32_read_file_from_dir(Disk, clust, Offset, Size, filename, Buffer);
36 
37  kfree(filename);
38 
39  return Size;
40 }
41 
42 size_t fs_fat32_write(char Disk, const char* Path,size_t Offset,size_t Size,void* Buffer){
43  return 0;
44 }
45 
46 FSM_FILE fs_fat32_info(char Disk, const char* Path) {
47  FSM_FILE file = {0};
48 
49  // Get folder where file is contained
50  size_t clust = fs_fat32_evaluate(Disk, Path, true);
51 
52  if(clust == 0) {
53  qemu_err("File does not exist");
54  return file;
55  }
56 
57  char* filename = pathinfo(Path, PATHINFO_BASENAME);
58 
59  qemu_warn("Path: %s; Filename: %s;", Path, filename);
60 
61  fat_file_info_t info = fs_fat32_get_object_info(Disk, filename, clust);
62  qemu_log("OK?");
63 
64  if(info.filename[0] == 0) {
65  return file;
66  }
67 
68  memset(file.Name, 0, 1024);
69  memcpy(file.Name, info.filename, 256);
70 
71  file.Size = info.size;
72  // PIMNIK98 MAKE MACROS FOR FSM TYPES PLEASE
73  // file.Type = WHAT?????
74 
75  file.Ready = 1;
76 
77  qemu_ok("%s %d", file.Name, file.Size);
78 
79  kfree(filename);
80 
81  return file;
82 }
83 
84 FSM_DIR* fs_fat32_dir(char Disk, const char* Path) {
85  fat_description_t* desc = dpm_metadata_read(Disk);
86 
87  qemu_note("Given path is: %s", Path);
88  size_t clust = fs_fat32_evaluate(Disk, Path, true);
89 
90  qemu_warn("Got cluster: %d", clust);
91 
92  FSM_DIR *Dir = kcalloc(sizeof(FSM_DIR), 1);
93 
94  if(clust == 0) {
95  Dir->Ready = 0;
96  Dir->Count = 0;
97  Dir->CountFiles = 0;
98  Dir->CountDir = 0;
99  Dir->CountOther = 0;
100  Dir->Files = 0;
101 
102  return Dir;
103  }
104 
105  FSM_FILE *Files = kcalloc(sizeof(FSM_FILE), 1);
106 
107  size_t cluster_count = fs_fat32_get_cluster_count(Disk, clust);
108  char* cluster_data = kcalloc(desc->cluster_size, cluster_count);
109 
110  fs_fat32_read_clusters_to_memory(Disk, clust, cluster_data);
111 
112  size_t offset = 0;
113  size_t file_count = 0;
114  size_t directory_count = 0;
115 
116  while(1) {
117  fat_file_info_t file = fs_fat32_read_file_info(cluster_data + offset);
118 
119  if(file.advanced_info.short_file_name[0] == 0)
120  break;
121 
122  size_t len = strlen(file.filename);
123  size_t skip_lfns_count = (len / 13);
124  size_t skip_lfns_remiander = (len % 13);
125 
126  if(skip_lfns_remiander > 0)
127  skip_lfns_count++;
128 
129  if(file.is_lfn)
130  offset += sizeof(LFN_t) * skip_lfns_count;
131 
132  offset += sizeof(fat_object_info_t);
133 
134  Files = krealloc(Files, sizeof(FSM_FILE) * (file_count + directory_count + 1));
135 
136  Files[directory_count + file_count].LastTime.year = 1980 + ((file.advanced_info.last_modif_date >> 9) & 0b1111111);
137  Files[directory_count + file_count].LastTime.month = (file.advanced_info.last_modif_date >> 5) & 0b1111;
138  Files[directory_count + file_count].LastTime.day = (file.advanced_info.last_modif_date >> 0) & 0b11111;
139 
140  Files[directory_count + file_count].LastTime.hour = ((file.advanced_info.last_modif_time >> 11) & 0b11111);
141  Files[directory_count + file_count].LastTime.minute = ((file.advanced_info.last_modif_time >> 5) & 0b111111);
142  Files[directory_count + file_count].LastTime.second = ((file.advanced_info.last_modif_time >> 0) & 0b11111);
143 
144  memset(Files[directory_count + file_count].Name, 0, 1024);
145  memcpy(Files[directory_count + file_count].Name, file.filename, strlen(file.filename));
146  Files[directory_count + file_count].Size = file.size;
147  Files[directory_count + file_count].Ready = 1;
148 
149  qemu_note("File: %s, Size: %d", Files[directory_count + file_count].Name, Files[directory_count + file_count].Size);
150 
151  if(file.advanced_info.attributes & ATTR_DIRECTORY) {
152  Files[directory_count + file_count].Type = 5; // What an undocumented magic?
153 
154  directory_count++;
155  } else {
156  Files[directory_count + file_count].Type = 0; // What an undocumented magic?
157 
158  file_count++;
159  }
160  }
161 
162  kfree(cluster_data);
163 
164  Dir->Ready = 1;
165  Dir->Count = file_count + directory_count;
166  Dir->CountFiles = file_count;
167  Dir->CountDir = directory_count;
168  Dir->CountOther = 0;
169  Dir->Files = Files;
170 
171  return Dir;
172 }
173 
174 int fs_fat32_create(char Disk,const char* Path,int Mode){
175  return 0;
176 }
177 
178 int fs_fat32_delete(char Disk,const char* Path,int Mode){
179  return 0;
180 }
181 
182 void fs_fat32_label(char Disk, char* Label){
183  fat_description_t* desc = dpm_metadata_read(Disk);
184 
185  memcpy(Label, desc->info.volume_label, 11);
186 }
187 
188 vector_t* fs_fat32_get_clusters(char Disk, size_t cluster_number) {
189  fat_description_t* desc = dpm_metadata_read(Disk);
190 
191  vector_t* container = vector_new();
192 
193  uint32_t cur_cluster = cluster_number;
194 
195  do {
196  uint32_t old_cluster = cur_cluster;
197 
198  cur_cluster = desc->fat_table[cur_cluster];
199 // dpm_read(Disk, desc->fat_offset + (cur_cluster * 4), 4, &cur_cluster);
200 
201  vector_push_back(container, old_cluster);
202  } while(!(cur_cluster == 0x0fffffff || cur_cluster == 0x0ffffff8));
203 
204  return container;
205 }
206 
207 void fs_fat32_read_entire_fat(char Disk) {
208  fat_description_t* desc = dpm_metadata_read(Disk);
209 
210  if(desc->fat_table) {
211  qemu_err("Reading FAT second time is not allowed");
212  while(1);
213  }
214 
215  desc->fat_table = kcalloc(1, desc->fat_size);
216 
217  dpm_read(Disk, 0, desc->fat_offset, desc->fat_size, desc->fat_table);
218 }
219 
220 // Make sure buffer size is cluster-size aligned :)
221 void fs_fat32_read_clusters_to_memory(char Disk, size_t cluster_number, void* buffer) {
222  fat_description_t* desc = dpm_metadata_read(Disk);
223 
224  vector_t* cluster_list = fs_fat32_get_clusters(Disk, cluster_number);
225 
226  for(int i = 0; i < cluster_list->size; i++) {
227  size_t current_cluster = vector_get(cluster_list, i).element;
228 
229  size_t addr = ((desc->info.reserved_sectors + (desc->info.fat_size_in_sectors * 2)) \
230  + ((current_cluster - 2) * desc->info.sectors_per_cluster)) * desc->info.bytes_per_sector;
231 
232  dpm_read(Disk, 0, addr, desc->cluster_size, (void*)(((size_t)buffer) + (i * desc->cluster_size)));
233  }
234 
235  vector_destroy(cluster_list);
236 }
237 
238 vector_t* fs_fat32_optimize(vector_t* cluster_list) {
239  vector_t* lists = vector_new();
240 
241  size_t old = vector_get(cluster_list, 0).element;
242  size_t start = vector_get(cluster_list, 0).element;
243 
244  for(int i = 1; i < cluster_list->size; i++) {
245  size_t current = vector_get(cluster_list, i).element;
246 
247  if (current - 1 != old) {
248  vector_push_back(lists, start);
249  vector_push_back(lists, old);
250 
251  start = current;
252  }
253 
254  old = current;
255  }
256 
257  vector_push_back(lists, start);
258  vector_push_back(lists, old);
259 
260  return lists;
261 }
262 
263 void fs_fat32_read_clusters_to_memory_precise(char Disk, size_t cluster_number, void *buffer, size_t byte_offset,
264  size_t len) {
265  fat_description_t* desc = dpm_metadata_read(Disk);
266 
267  qemu_log("Reading cluster chain...");
268  vector_t* cluster_list = fs_fat32_get_clusters(Disk, cluster_number);
269 
270 #if FAT32_LINEAR_OPTIMIZATION==1
271  vector_t* optimized = fs_fat32_optimize(cluster_list);
272 
273  qemu_printf("Optimized: ");
274 
275  for(int i = 0; i < optimized->size; i++) {
276  qemu_printf("%u ", vector_get(optimized, i).element);
277  }
278 
279  qemu_printf("\n");
280 
281  vector_destroy(cluster_list);
282 
283  cluster_list = optimized;
284 #endif
285 
286  qemu_log("Byte offset: %d; Size of read: %d; Cluster size: %d", byte_offset, len, desc->cluster_size);
287 
288  size_t starting_cluster = byte_offset / desc->cluster_size;
289  size_t read_clutser_count = len / desc->cluster_size;
290 
291  if(len % desc->cluster_size > 0) {
292  read_clutser_count++;
293  }
294 
295  qemu_log("Calculated: Starting cluster: %d; Cluster count: %d", starting_cluster, read_clutser_count);
296  qemu_log("Reading file data...");
297 
298 #if FAT32_LINEAR_OPTIMIZATION==1
299  size_t buffer_index = 0;
300 
301  for(int i = 0; i < cluster_list->size; i+=2) {
302  size_t start_cluster = vector_get(cluster_list, i).element;
303  size_t end_cluster = vector_get(cluster_list, i + 1).element;
304  size_t count = end_cluster - start_cluster + 1;
305 
306  qemu_note("START: %u; END: %u; COUNT: %u", start_cluster, end_cluster, count);
307 
308 
309  qemu_note("BUFFER INDEX: %u", buffer_index);
310  qemu_note("STARTING_CLUSTER: %u", starting_cluster);
311 
312  size_t addr = ((desc->info.reserved_sectors + (desc->info.fat_size_in_sectors * 2)) \
313  + ((start_cluster - 2) * desc->info.sectors_per_cluster)) * desc->info.bytes_per_sector;
314 
315  // TODO: byte_offset support
316 
317  qemu_note("LEN: %u", MIN(desc->cluster_size * count, len));
318  qemu_note("LOAD TO: %x", (size_t)buffer);
319 
320  dpm_read(
321  Disk,
322  0,
323  addr,
324  MIN(desc->cluster_size * count, len),
325  (void*)(((size_t)buffer) + (buffer_index * desc->cluster_size))
326  );
327 
328  len -= MIN(desc->cluster_size * count, len);
329  buffer_index += count;
330  }
331 
332  qemu_log("Remaining: %u", len);
333 #else
334  for(size_t i = starting_cluster; i < starting_cluster + read_clutser_count; i++) {
335  size_t buffer_index = i - starting_cluster;
336 
337  size_t current_cluster = vector_get(cluster_list, i).element;
338 
339  size_t addr = ((desc->info.reserved_sectors + (desc->info.fat_size_in_sectors * 2)) \
340  + ((current_cluster - 2) * desc->info.sectors_per_cluster)) * desc->info.bytes_per_sector;
341 
342  dpm_read(
343  Disk,
344  0,
345  addr + byte_offset,
346  MIN(desc->cluster_size, len),
347  (void*)(((size_t)buffer) + (buffer_index * desc->cluster_size))
348  );
349 
350  len -= desc->cluster_size;
351  }
352 #endif
353 
354  vector_destroy(cluster_list);
355 }
356 
357 
358 size_t fs_fat32_get_cluster_count(char Disk, size_t cluster_number) {
359  vector_t* clusters = fs_fat32_get_clusters(Disk, cluster_number);
360 
361  size_t cluster_count = clusters->size;
362 
363  vector_destroy(clusters);
364 
365  return cluster_count;
366 }
367 
368 size_t fs_fat32_read_lfn(char* data, char* out) {
369  size_t encoded_characters = 0;
370 
371  uint16_t* chunk = kcalloc(sizeof(uint16_t), 13);
372  LFN_t lfn = {0};
373 
374  memset(out, 0, 256);
375 
376  while(true) {
377  memcpy(&lfn, data, sizeof lfn);
378 
379  data += sizeof lfn;
380 
381  uint8_t lfn_num = lfn.attr_number & ~LFN_LAST_ENTRY;
382 
383  if(lfn.reserved != 0 || lfn_num > 20 || lfn.attribute != 0x0F) {
384  // It's normal (it may indicate that LFN entries are coming to an end.
385  // qemu_err("Invalid LFN!");
386  return 0;
387  }
388 
389  memcpy(chunk, lfn.first_name_chunk, 10);
390  memcpy(chunk + 5, lfn.second_name_chunk, 12);
391  memcpy(chunk + 11, lfn.third_name_chunk, 4);
392 
393  uint16_t* prepared_chunk = kcalloc(sizeof(uint16_t), 13);
394 
395  for(int i = 0; i < 13; i++) {
396  if(chunk[i] == 0xffff) {
397  break;
398  } else {
399  prepared_chunk[i] = chunk[i];
400  encoded_characters += 2;
401  }
402  }
403 
404  char* x = kcalloc(1, encoded_characters);
405 
406  utf16_to_utf8((short*)prepared_chunk,
407  (int)encoded_characters / 2,
408  x);
409 
410  memmove(out + 13, out, strlen(x));
411  memcpy(out, x, 13);
412 
413  kfree(prepared_chunk);
414  kfree(x);
415 
416  memset(chunk, 0, 26);
417 
418  if(lfn_num == 1) // Is last?
419  break;
420  }
421 
422  kfree(chunk);
423 
424  return encoded_characters;
425 }
426 
427 fat_file_info_t fs_fat32_read_file_info(char* data) {
428  fat_file_info_t info = {0};
429 
430  size_t ecc = fs_fat32_read_lfn(data, info.filename);
431 
432  size_t byte_count = ecc / 2;
433 
434  size_t div = byte_count / 13, rem = byte_count % 13;
435 
436  if(rem > 0) div++;
437 
438  // Skip LFN and get into the file info section
439  data += sizeof(LFN_t) * div;
440 
441  memcpy(&info.advanced_info, data, sizeof info.advanced_info);
442 
443  if(strlen(info.filename) == 0) {
444  for(int i = 0; i < 11; i++) {
445 // if(info.advanced_info.short_file_name[i] == ' ')
446 // break;
447 
448  info.filename[i] = info.advanced_info.short_file_name[i];
449  }
450 
451  info.is_lfn = false;
452  } else {
453  info.is_lfn = true;
454  }
455 
456  info.starting_cluster = (info.advanced_info.first_cluster_high << 16) | info.advanced_info.first_cluster_low;
457  info.size = info.advanced_info.file_size_in_bytes;
458 
459  return info;
460 }
461 
462 fat_file_info_t fs_fat32_get_object_info(char Disk, const char* filename, size_t directory_cluster) {
463  fat_description_t* desc = dpm_metadata_read(Disk);
464 
465  size_t cluster_count = fs_fat32_get_cluster_count(Disk, directory_cluster);
466 
467  char* cluster_data = kcalloc(desc->cluster_size, cluster_count);
468 
469  fs_fat32_read_clusters_to_memory(Disk, directory_cluster, cluster_data);
470 
471  size_t offset = 0;
472 
473  while(1) {
474  fat_file_info_t info = fs_fat32_read_file_info(cluster_data + offset);
475 
476  if(info.advanced_info.short_file_name[0] == 0)
477  break;
478 
479  size_t len = strlen(info.filename);
480  size_t skip_lfns_count = (len / 13);
481  size_t skip_lfns_remiander = (len % 13);
482 
483  if(skip_lfns_remiander > 0)
484  skip_lfns_count++;
485 
486  if(info.is_lfn)
487  offset += sizeof(LFN_t) * skip_lfns_count;
488 
489  offset += sizeof(fat_object_info_t);
490 
491  if(strcmp(info.filename, filename) == 0) {
492  kfree(cluster_data);
493 
494  return info;
495  }
496  }
497 
498  kfree(cluster_data);
499 
500  return (fat_file_info_t){0};
501 }
502 
503 void fs_fat32_read_file_from_dir(char Disk, size_t directory_cluster, size_t byte_offset, size_t length, char *filename,
504  char *out) {
505  fat_description_t* desc = dpm_metadata_read(Disk);
506 
507  size_t cluster_count = fs_fat32_get_cluster_count(Disk, directory_cluster);
508  char* cluster_data = kcalloc(desc->cluster_size, cluster_count);
509 
510  fs_fat32_read_clusters_to_memory(Disk, directory_cluster, cluster_data);
511 
512  size_t offset = 0;
513 
514  while(1) {
515  fat_file_info_t file = fs_fat32_read_file_info(cluster_data + offset);
516 
517  if(file.advanced_info.short_file_name[0] == 0)
518  break;
519 
520  size_t len = strlen(file.filename);
521  size_t skip_lfns_count = (len / 13);
522  size_t skip_lfns_remiander = (len % 13);
523 
524  if(skip_lfns_remiander > 0)
525  skip_lfns_count++;
526 
527  if(file.is_lfn)
528  offset += sizeof(LFN_t) * skip_lfns_count;
529 
530  offset += sizeof(fat_object_info_t);
531 
532  if(memcmp(file.filename, filename, len) == 0) {
533  qemu_ok("File found!");
534 
535 // fs_fat32_read_clusters_to_memory_precise(Disk, file.starting_cluster, out, byte_offset, file.size);
536  fs_fat32_read_clusters_to_memory_precise(Disk, file.starting_cluster, out, byte_offset, length);
537  break;
538  }
539  }
540 
541  kfree(cluster_data);
542 }
543 
544 void fs_fat32_scan_directory(char Disk, size_t directory_cluster) {
545  fat_description_t* desc = dpm_metadata_read(Disk);
546 
547  size_t cluster_count = fs_fat32_get_cluster_count(Disk, directory_cluster);
548  char* cluster_data = kcalloc(desc->cluster_size, cluster_count);
549 
550  fs_fat32_read_clusters_to_memory(Disk, directory_cluster, cluster_data);
551 
552  size_t offset = 0;
553 
554  // TODO: Actually scan directory
555  while(1) {
556  fat_file_info_t file = fs_fat32_read_file_info(cluster_data + offset);
557 
558  if(file.advanced_info.short_file_name[0] == 0)
559  break;
560 
561  size_t len = strlen(file.filename);
562  size_t skip_lfns_count = (len / 13);
563  size_t skip_lfns_remiander = (len % 13);
564 
565  if(skip_lfns_remiander > 0)
566  skip_lfns_count++;
567 
568  if(file.is_lfn)
569  offset += sizeof(LFN_t) * skip_lfns_count;
570 
571  offset += sizeof(fat_object_info_t);
572 
573  qemu_note("%s %d", file.filename, file.size);
574  }
575 
576 // while(1);
577 
578  kfree(cluster_data);
579 }
580 
581 // Return cluster number
582 size_t fs_fat32_evaluate(char Disk, const char* path, bool error_on_file) {
583  size_t current_cluster = 2; // 2 is a root directory
584  size_t old_cluster = 2;
585 
586  if(strlen(path) == 0) {
587  return current_cluster;
588  }
589 
590  string_t* strpath = string_from_charptr(path);
591  vector_t* pieces = string_split(strpath, "/");
592 
593  fat_file_info_t temp_info = {0};
594 
595  for(int i = 0; i < pieces->size; i++) {
596  char* value = ADDR2STRING(pieces->data[i])->data;
597  qemu_note("%s", value);
598 
599  if(strlen(value) == 0)
600  continue;
601 
602  if(strcmp(value, ".") == 0)
603  continue;
604 
605  if(strcmp(value, "..") == 0) {
606  current_cluster = old_cluster;
607  continue;
608  }
609 
610  temp_info = fs_fat32_get_object_info(Disk, value, current_cluster);
611 
612  if(temp_info.filename[0] == 0) {
613  string_split_free(pieces);
614  string_destroy(strpath);
615 
616  return 0;
617  }
618 
619  if(~temp_info.advanced_info.attributes & ATTR_DIRECTORY) {
620  if(error_on_file) {
621  qemu_err("That's not a directory, can't go on...");
622 
623  string_split_free(pieces);
624  string_destroy(strpath);
625 
626  return current_cluster;
627  } else {
628  string_split_free(pieces);
629  string_destroy(strpath);
630 
631  return temp_info.starting_cluster;
632  }
633  }
634 
635  old_cluster = current_cluster;
636  current_cluster = temp_info.starting_cluster;
637  }
638 
639  string_split_free(pieces);
640  string_destroy(strpath);
641 
642  return current_cluster;
643 }
644 
645 int fs_fat32_detect(char Disk) {
646 // If we initialize fat32 again, bug will appear (could not read root directory)
647 // if(dpm_metadata_read(Disk)) {
648 // qemu_err("WHAT?");
649 // while(1);
650 // }
651 
652  fat_description_t* fat_system = kcalloc(1, sizeof(fat_description_t));
653 
654  dpm_read(Disk, 0, 0, sizeof(fat_info_t), &fat_system->info);
655 
656  qemu_warn("Trying FAT32...");
657 
658  bool is_fat_bootcode = (unsigned char)fat_system->info.bootcode[0] == 0xEB
659  && (unsigned char)fat_system->info.bootcode[1] == 0x58
660  && (unsigned char)fat_system->info.bootcode[2] == 0x90;
661 
662  bool is_fat_fsname = memcmp(fat_system->info.fs_type, "FAT32", 0) == 0;
663 
664  if(is_fat_bootcode && is_fat_fsname) {
665  qemu_note("FAT filesystem found!");
666  qemu_note("Disk label: %.11s", fat_system->info.volume_label);
667 
668  // Calculate needed values
669  fat_system->cluster_size = fat_system->info.bytes_per_sector * fat_system->info.sectors_per_cluster;
670  fat_system->fat_offset = fat_system->info.reserved_sectors * fat_system->info.bytes_per_sector;
671  fat_system->fat_size = fat_system->info.fat_size_in_sectors * fat_system->info.bytes_per_sector;
672  fat_system->reserved_fat_offset = (fat_system->info.reserved_sectors + fat_system->info.fat_size_in_sectors) * fat_system->info.bytes_per_sector;
673  fat_system->root_directory_offset = ((fat_system->info.reserved_sectors + (fat_system->info.fat_size_in_sectors * 2)) + ((fat_system->info.root_directory_offset_in_clusters - 2) * fat_system->info.sectors_per_cluster)) * fat_system->info.bytes_per_sector;
674 
675  qemu_note("Cluster size: %d", fat_system->cluster_size);
676  qemu_note("FAT offset: %d", fat_system->fat_offset);
677  qemu_note("FAT size: %d", fat_system->fat_size);
678  qemu_note("Reserved FAT offset: %d", fat_system->reserved_fat_offset);
679  qemu_note("Root directory offset: %d", fat_system->root_directory_offset);
680 
681  // Assign FAT32 filesystem in-place
682  dpm_metadata_write(Disk, (uint32_t) fat_system);
683 
684  qemu_log("Reading FAT32 FAT table to memory, it may take a while...");
685  fs_fat32_read_entire_fat(Disk);
686 
687  vector_t* root_directory = fs_fat32_get_clusters(Disk, 2);
688 
689  qemu_note("[%d] Root occupies folllwing clusters:", root_directory->size);
690  for(int i = 0; i < root_directory->size; i++) {
691  qemu_note("Cluster: %d", vector_get(root_directory, i).element);
692  }
693 
694  vector_destroy(root_directory);
695 
696  qemu_warn("SCANNING ROOT DIRECTORY");
697  fs_fat32_scan_directory(Disk, 2);
698  qemu_warn("END SCANNING ROOT DIRECTORY");
699 
700 // FSM_FILE inf = fs_fat32_info('C', "fight.tga");
701 //
702 // char* temp = kcalloc(1, inf.Size);
703 // char* pix = kcalloc(1, 6 * MB);
704 // char* pix2 = kcalloc(1, 4 * MB);
705 //
706 // fs_fat32_read(Disk, "fight.tga", 0, inf.Size, temp);
707 //
708 // tga_extract_pixels_from_data(temp, pix);
709 //
710 // size_t origw = 800, origh = 1245;
711 // size_t targw = 400, targh = 600;
712 //
713 // scale_rgb_image(pix, origw, origh, targw, targh, 1, pix2);
714 //
715 // draw_rgb_image(pix2, targw, targh, 32, 0, 0);
716 //
717 // kfree(temp);
718 // kfree(pix);
719 // kfree(pix2);
720 //
721 // while(1);
722 
723  return 1;
724  }
725 
726  return 0;
727 }
Основные определения ядра
size_t dpm_read(char Letter, uint64_t high_offset, uint64_t low_offset, size_t Size, void *Buffer)
[DPM] Считывание данных с диска
Definition: dpm.c:82
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
int strcmp(const char *s1, const char *s2)
Сравнение строк
Definition: string.c:253
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
int32_t memcmp(const char *s1, const char *s2, size_t n)
Сравнение массивов
Definition: string.c:305
void * memmove(void *dest, void *src, size_t count)
Копирование массивов (в том числе пересекающихся)
Definition: string.c:220
void qemu_printf(const char *text,...)
Вывод QEMU через COM1 информации
Definition: ports.c:149
Definition: string.h:10
Definition: vector.h:7