Initial (probably final) checkin.
[fat-rescue] / salvage.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <fcntl.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #define FAT_SIZE 65536
8 #define FAT_START 0x27400
9 #define DATA_START 0x42800
10 #define CLUSTER_SIZE 16384
11 unsigned short fat[FAT_SIZE];
12
13 int main(int argc, char **argv)
14 {
15         int fd = open("/home/sesse/minnekort.img", O_RDONLY);
16         int ofd;
17         int offset;
18         int cluster;
19         int left;
20         unsigned char de[32];
21         char filename[8 + 1 + 3 + 1];
22         char data[CLUSTER_SIZE];
23         
24         if (fd == -1) {
25                 perror("/home/sesse/minnekort.img");
26                 exit(1);
27         }
28
29         // read the FAT
30         lseek(fd, FAT_START, SEEK_SET);
31         read(fd, fat, FAT_SIZE * sizeof(unsigned short));
32
33         // read the directory structure in question
34         sscanf(argv[1], "%i", &offset);
35         lseek(fd, offset, SEEK_SET);
36         read(fd, de, 32);
37
38         memcpy(filename, de, 8);
39         filename[8] = '.';
40         memcpy(filename + 9, de + 8, 3);
41         filename[12] = '\0';
42         
43         printf("Filename = %s\n", filename);
44         ofd = open(filename, O_WRONLY | O_CREAT, 0644);
45
46         left = *((unsigned int *)(de + 0x1c));
47         printf("Size = %u\n", left);
48         
49         printf("Recovering:");
50         cluster = *((unsigned short *)(de + 0x1a));
51 //      printf(" %u(0x%x)", cluster, cluster * CLUSTER_SIZE + DATA_START);
52 //      fflush(stdout);
53
54         for ( ;; ) {
55                 int towrite = (CLUSTER_SIZE < left) ? CLUSTER_SIZE : left;
56
57                 lseek(fd, cluster * CLUSTER_SIZE + DATA_START, SEEK_SET);
58                 read(fd, data, CLUSTER_SIZE);   
59                 write(ofd, data, towrite);
60
61                 // read the next entry in the FAT
62                 cluster = fat[cluster];
63                 
64         /*      if (towrite < CLUSTER_SIZE)
65                         printf("(trunc)");
66                 printf(" %u", cluster);
67                 fflush(stdout);*/
68
69                 if (cluster < 0x0002) {
70                         printf(" (ERROR)");
71                         break;
72                 }
73                 if (cluster >= 0xfff0 && cluster < 0xfff8) {
74                         printf(" (ERROR)");
75                         break;
76                 }
77                 if (cluster >= 0xfff8) {
78                         printf(" (EOF)");
79                         break;
80                 }
81                 if (towrite < CLUSTER_SIZE) {
82                         printf(" (EXPECTED EOF)\n");
83                 }
84                 
85         //      printf("(0x%x)", cluster * CLUSTER_SIZE + DATA_START);
86
87                 left -= towrite;
88         }
89         printf("\n");
90         close(fd);
91         close(ofd);
92
93         return 0;
94 }