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 }
common.h
Основные определения ядра
dpm_read
size_t dpm_read(char Letter, uint64_t high_offset, uint64_t low_offset, size_t Size, void *Buffer)
[DPM] Считывание данных с диска
Definition: dpm.c:82
strlen
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
strcmp
int strcmp(const char *s1, const char *s2)
Сравнение строк
Definition: string.c:253
memset
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
memcpy
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
memcmp
int32_t memcmp(const char *s1, const char *s2, size_t n)
Сравнение массивов
Definition: string.c:305
memmove
void * memmove(void *dest, void *src, size_t count)
Копирование массивов (в том числе пересекающихся)
Definition: string.c:220
qemu_printf
void qemu_printf(const char *text,...)
Вывод QEMU через COM1 информации
Definition: ports.c:149
fat_description_t
Definition: fat32.h:76
fat_file_info_t
Definition: fat32.h:97
string
Definition: string.h:10
vector
Definition: vector.h:7