1 /*
2
3 File: fat_adv.c
4
5 Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
6
7 This software is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write the Free Software Foundation, Inc., 51
19 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <ctype.h>
29 #ifdef HAVE_STRING_H
30 #include <string.h>
31 #endif
32 #ifdef HAVE_STDLIB_H
33 #include <stdlib.h>
34 #endif
35 #ifdef HAVE_TIME_H
36 #include <time.h>
37 #endif
38 #ifdef HAVE_SYS_STAT_H
39 #include <sys/stat.h>
40 #endif
41 #include "types.h"
42 #include "common.h"
43 #include "fat.h"
44 #include "fat_common.h"
45 #include "lang.h"
46 #include "fnctdsk.h"
47 #include "intrf.h"
48 #include "intrfn.h"
49 #include "dir.h"
50 #include "dirpart.h"
51 #include "fat_dir.h"
52 #include "io_redir.h"
53 #include "log.h"
54 #include "log_part.h"
55 #include "fat_adv.h"
56 #include "fat_cluster.h"
57 #ifdef HAVE_NCURSES
58 #include "fatn.h"
59 #endif
60
61 #define INTER_FAT_ASK_X 0
62 #define INTER_FAT_ASK_Y 23
63 #define INTER_FATBS_X 0
64 #define INTER_FATBS_Y 22
65
66 typedef struct info_offset_struct info_offset_t;
67
68 struct info_offset_struct
69 {
70 unsigned long int offset;
71 unsigned int nbr;
72 unsigned int fat_type;
73 };
74
75 static upart_type_t fat_find_info(disk_t *disk_car,unsigned int*reserved, unsigned int*fat_length, const partition_t *partition, const uint64_t max_offset, const int p_fat12, const int p_fat16, const int p_fat32, const int verbose, const int dump_ind, const unsigned int expert, unsigned int *fats);
76 static int fat_find_type(disk_t *disk_car, const partition_t *partition, const uint64_t max_offset, const int p_fat12, const int p_fat16, const int p_fat32, const int verbose, const int dump_ind, unsigned int *nbr_offset, info_offset_t *info_offset, const unsigned int max_nbr_offset);
77
78 static unsigned int fat_find_fat_start(const unsigned char *buffer,const int p_fat12, const int p_fat16, const int p_fat32,unsigned long int*fat_offset, const unsigned int sector_size);
79
80 static void create_fat_boot_sector(disk_t *disk_car, partition_t *partition, const unsigned int reserved, const int verbose, const unsigned int dir_entries, const unsigned long int root_cluster, const unsigned int sectors_per_cluster, const unsigned int fat_length, const upart_type_t upart_type, const unsigned int fats, char **current_cmd);
81 static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *partition,const unsigned int sectors_per_cluster, const unsigned long int no_of_cluster, const unsigned int reserved, const unsigned int fat_length, const int verbose, const unsigned int expert, const unsigned int first_free_cluster, const unsigned int fats);
82 static int write_FAT_boot_code_aux(unsigned char *buffer);
83 static int find_dir_entries(disk_t *disk_car,const partition_t *partition, const unsigned int offset,const int verbose);
84 static int analyse_dir_entries(disk_t *disk_car,const partition_t *partition, const unsigned int offset, const int verbose);
85 static int analyse_dir_entries2(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length,const int verbose, unsigned int root_size_max,const upart_type_t upart_type, const unsigned int fats);
86 static int calcul_sectors_per_cluster(const upart_type_t upart_type, const unsigned long int data_size, const unsigned int fat_length, const unsigned int sector_size);
87 static int check_FAT_dir_entry(const unsigned char *entry, const unsigned int entry_nr);
88 static unsigned long int get_subdirectory(disk_t *disk_car,const uint64_t hd_offset, const unsigned long int i);
89
90 #ifdef HAVE_NCURSES
91 static void fat_date_unix2dos(int unix_date,unsigned short *mstime, unsigned short *msdate);
92 static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length, const unsigned int root_cluster, const unsigned int sectors_per_cluster, const int verbose, file_info_t *rootdir_list, const unsigned int fats);
93 static upart_type_t select_fat_info(const info_offset_t *info_offset, const unsigned int nbr_offset,unsigned int*reserved, unsigned int*fat_length, const unsigned long int max_sector_offset, unsigned int *fats);
94 #endif
95
96 /*
97 * 0 entry is free
98 * 1 entry is used
99 * 2 not an entry
100 * */
check_FAT_dir_entry(const unsigned char * entry,const unsigned int entry_nr)101 static int check_FAT_dir_entry(const unsigned char *entry, const unsigned int entry_nr)
102 {
103 int i;
104 if((entry[0xB]&ATTR_EXT_MASK)==ATTR_EXT)
105 return 1;
106 /* log_trace("check_FAT_dir_entry %02x\n",*(entry+0)); */
107 if(entry[0]==0)
108 {
109 for(i=0;i<0x20;i++)
110 if(entry[i]!='\0')
111 return 2;
112 return 0;
113 }
114 if(entry[0]==0x20)
115 return 2;
116 if(entry[0]==0xE5)
117 return 1;
118 if(entry_nr<10 && (entry[0xB]&ATTR_VOLUME)==ATTR_VOLUME)
119 return 1;
120 for(i=0;i<8+3;i++)
121 {
122 const unsigned char car=entry[i];
123 if((car>=0x06 && car<=0x1f)||
124 (car>=0x3a && car<=0x3f)||
125 (car>='a' && car<='z'))
126 return 2;
127 switch(car)
128 {
129 case 0x1:
130 case 0x2:
131 case 0x3:
132 case 0x4:
133 case '"':
134 case '*':
135 case '+':
136 case ',':
137 case '.':
138 case '/':
139 case '[':
140 case '\\':
141 case ']':
142 case '|':
143 /*log_trace("check_FAT_dir_entry bad %c (%02x)\n",car,car); */
144 return 2;
145 default:
146 /*log_trace("check_FAT_dir_entry good %c (%02x)\n",car,car); */
147 break;
148 }
149 }
150 return 1;
151 }
152
153 /* */
154
155
get_subdirectory(disk_t * disk_car,const uint64_t hd_offset,const unsigned long int i)156 static unsigned long int get_subdirectory(disk_t *disk_car,const uint64_t hd_offset,const unsigned long int i)
157 {
158 unsigned char buffer[DEFAULT_SECTOR_SIZE];
159 const struct msdos_dir_entry *entry1=(const struct msdos_dir_entry *)&buffer[0];
160 const struct msdos_dir_entry *entry2=(const struct msdos_dir_entry *)&buffer[0x20];
161 if(disk_car->pread(disk_car, &buffer, sizeof(buffer), hd_offset) != sizeof(buffer))
162 {
163 log_error("fat_dir, get_subdirectory(), can't read directory\n");
164 return 1;
165 }
166 if(!is_fat_directory(buffer))
167 return 1;
168 if(fat_get_cluster_from_entry(entry1) != i)
169 return 1;
170 return fat_get_cluster_from_entry(entry2);
171 }
172
173 #ifdef HAVE_NCURSES
174 #define INTER_DIR 16
175
ask_root_directory(disk_t * disk_car,const partition_t * partition,const file_info_t * dir_list,const unsigned long int cluster)176 static int ask_root_directory(disk_t *disk_car, const partition_t *partition, const file_info_t*dir_list, const unsigned long int cluster)
177 {
178 /* Return value
179 * -1: quit
180 * 1: back
181 * other: new cluster
182 * */
183 int car;
184 int quit=0;
185 int offset=0;
186 int pos_num=0;
187 struct td_list_head *pos=dir_list->list.next;
188 WINDOW *window;
189 window=newwin(LINES, COLS, 0, 0); /* full screen */
190 aff_copy(window);
191 wmove(window,4,0);
192 aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
193 wmove(window,6,0);
194 wprintw(window,"Answer Y(es), N(o), Q(uit) or A(bort interactive mode). N or A if not sure.");
195 curs_set(1);
196 do
197 {
198 int i;
199 struct td_list_head *file_walker = NULL;
200 for(i=0, file_walker=dir_list->list.next;
201 file_walker!=&dir_list->list && i<offset;
202 file_walker=file_walker->next,i++);
203 for(i=offset;
204 file_walker!=&dir_list->list && (i-offset)<INTER_DIR;
205 file_walker=file_walker->next,i++)
206 {
207 const file_info_t *current_file=td_list_entry_const(file_walker, const file_info_t, list);
208 char str[11];
209 char datestr[80];
210 wmove(window,8+i-offset,0);
211 wclrtoeol(window); /* before addstr for BSD compatibility */
212 if(¤t_file->list==pos)
213 {
214 wattrset(window, A_REVERSE);
215 waddstr(window, ">");
216 }
217 else
218 waddstr(window, " ");
219 set_datestr((char *)&datestr, sizeof(datestr), current_file->td_mtime);
220 mode_string(current_file->st_mode, str);
221 wprintw(window, "%s %3u %3u ",
222 str, (unsigned int)current_file->st_uid, (unsigned int)current_file->st_gid);
223 wprintw(window, "%9llu", (long long unsigned int)current_file->st_size);
224 /* FIXME: screen overlaps due to long filename */
225 wprintw(window, " %s %s\n", datestr, current_file->name);
226 if(¤t_file->list==pos)
227 wattroff(window, A_REVERSE);
228 }
229 /* Clear the last line, useful if overlapping */
230 wmove(window,8+i-offset,0);
231 wclrtoeol(window); /* before addstr for BSD compatibility */
232 /* print the cluster in the loop, so */
233 /* the visible cursor will be at the end */
234 wmove(window,5,0);
235 wprintw(window,"Cluster %lu, Directory / found ? ", cluster);
236 wrefresh(window);
237 car=wgetch(window);
238 switch(car)
239 {
240 case 'a':
241 case 'A':
242 case 'y':
243 case 'Y':
244 case 'n':
245 case 'N':
246 case 'Q':
247 case 'q':
248 quit=1;
249 break;
250 }
251 if(!td_list_empty(&dir_list->list))
252 {
253 switch(car)
254 {
255 case KEY_UP:
256 if(pos->prev!=&dir_list->list)
257 {
258 pos=pos->prev;
259 pos_num--;
260 }
261 break;
262 case KEY_DOWN:
263 if(pos->next!=&dir_list->list)
264 {
265 pos=pos->next;
266 pos_num++;
267 }
268 break;
269 case KEY_PPAGE:
270 for(i=0; i<INTER_DIR-1 && pos->prev!=&dir_list->list; i++)
271 {
272 pos=pos->prev;
273 pos_num--;
274 }
275 break;
276 case KEY_NPAGE:
277 for(i=0; i<INTER_DIR-1 && pos->next!=&dir_list->list; i++)
278 {
279 pos=pos->next;
280 pos_num++;
281 }
282 break;
283 }
284 if(pos_num<offset)
285 offset=pos_num;
286 if(pos_num>=offset+INTER_DIR)
287 offset=pos_num-INTER_DIR+1;
288 }
289 } while(quit==0);
290 curs_set(0);
291 wprintw(window,"%c\n",car);
292 delwin(window);
293 (void) clearok(stdscr, TRUE);
294 #ifdef HAVE_TOUCHWIN
295 touchwin(stdscr);
296 #endif
297 return toupper(car);
298 }
299 #endif
300
is_root_cluster_candidat(const file_info_t * dir_list)301 static int is_root_cluster_candidat(const file_info_t *dir_list)
302 {
303 const file_info_t *file1=td_list_first_entry(&dir_list->list, const file_info_t, list);
304 const file_info_t *file2=td_list_next_entry(file1, list);
305 return (!td_list_empty(&dir_list->list) && (&file2->list==&dir_list->list || file1->st_ino!=file2->st_ino));
306 }
307
fat32_find_root_cluster(disk_t * disk_car,const partition_t * partition,const unsigned int sectors_per_cluster,const unsigned long int no_of_cluster,const unsigned int reserved,const unsigned int fat_length,const int verbose,const unsigned int expert,const unsigned int first_free_cluster,const unsigned int fats)308 static unsigned int fat32_find_root_cluster(disk_t *disk_car,const partition_t *partition,const unsigned int sectors_per_cluster, const unsigned long int no_of_cluster,const unsigned int reserved, const unsigned int fat_length, const int verbose, const unsigned int expert, const unsigned int first_free_cluster, const unsigned int fats)
309 {
310 unsigned long int root_cluster=0;
311 const uint64_t start_data=reserved+fats*fat_length;
312 const unsigned int cluster_size=sectors_per_cluster*disk_car->sector_size;
313 if(verbose>0)
314 log_trace("fat32_find_root_cluster(sectors_per_cluster=%u,no_of_cluster=%lu,reserved=%u,fat_length=%u,expert=%u,first_free_cluster=%u)\n",sectors_per_cluster,no_of_cluster,reserved,fat_length,expert,first_free_cluster);
315 if(sectors_per_cluster==0)
316 return 0;
317 {
318 unsigned int dir_nbr=0;
319 #ifdef HAVE_NCURSES
320 int interactive=1;
321 #endif
322 unsigned char *buffer;
323 int ind_stop=0;
324 file_info_t rootdir_list;
325 TD_INIT_LIST_HEAD(&rootdir_list.list);
326 buffer=(unsigned char *)MALLOC(cluster_size);
327 #ifdef HAVE_NCURSES
328 wmove(stdscr,22,0);
329 wattrset(stdscr, A_REVERSE);
330 waddstr(stdscr," Stop ");
331 wattroff(stdscr, A_REVERSE);
332 #endif
333 for(root_cluster=2;(root_cluster<2+no_of_cluster)&&(ind_stop==0);root_cluster++)
334 {
335 #ifdef HAVE_NCURSES
336 const unsigned long int percent=root_cluster*100/(2+no_of_cluster);
337 if((root_cluster&0xfff)==0)
338 {
339 wmove(stdscr,9,0);
340 wclrtoeol(stdscr);
341 wprintw(stdscr,"Search root cluster %10lu/%lu %lu%%",root_cluster,2+no_of_cluster,percent);
342 wrefresh(stdscr);
343 ind_stop|=check_enter_key_or_s(stdscr);
344 }
345 #endif
346 if((unsigned)disk_car->pread(disk_car, buffer, cluster_size,
347 partition->part_offset + (start_data + (uint64_t)(root_cluster - 2) * sectors_per_cluster) *
348 disk_car->sector_size) == cluster_size)
349 {
350 const struct msdos_dir_entry *entry1=(const struct msdos_dir_entry *)&buffer[0];
351 const struct msdos_dir_entry *entry2=(const struct msdos_dir_entry *)&buffer[0x20];
352 if(verbose>1)
353 {
354 log_verbose("fat32_find_root_cluster test cluster=%lu\n",root_cluster);
355 /*
356 dump_ncurses(buffer,cluster_size);
357 */
358 }
359 if(buffer[0]=='.' && is_fat_directory(buffer))
360 { /* Directory found */
361 if(fat_get_cluster_from_entry(entry2)==0 &&
362 buffer[0x40]!=0) /* First-level directory with files */
363 {
364 file_info_t dir_list;
365 TD_INIT_LIST_HEAD(&dir_list.list);
366 log_info("First-level directory found at cluster %lu\n",root_cluster);
367 dir_fat_aux(buffer, cluster_size, 0, &dir_list);
368 if(verbose>0)
369 {
370 dir_aff_log(NULL, &dir_list);
371 }
372 {
373 const file_info_t *first_entry=td_list_first_entry(&dir_list.list, const file_info_t, list);
374 file_info_t *new_file=(file_info_t *)MALLOC(sizeof(*new_file));
375 memcpy(new_file, first_entry, sizeof(*new_file));
376 new_file->name=(char*)MALLOC(32);
377 snprintf(new_file->name, 32,"DIR%05u",++dir_nbr);
378 td_list_add_tail(&new_file->list, &rootdir_list.list);
379 }
380 delete_list_file(&dir_list);
381 }
382 }
383 else if(memcmp(entry1, entry2, 0x20)!=0)
384 { /* Potential root directory */
385 unsigned int i,found=1;
386 int etat=0,nb_subdir=0,nb_subdir_ok=0;
387 for(i=0; found && i<cluster_size/0x20; i++)
388 {
389 int res=check_FAT_dir_entry(&buffer[i*0x20],i);
390 if(verbose>2)
391 log_verbose("fat32_find_root_cluster root_cluster=%lu i=%u etat=%d res=%d\n",root_cluster,i,etat,res);
392 switch(res)
393 {
394 case 0:
395 if(etat==0)
396 etat=1;
397 break;
398 case 1:
399 if(etat==1)
400 {
401 etat=2;
402 found=0;
403 }
404 break;
405 case 2:
406 found=0;
407 break;
408 }
409 if((buffer[i*0x20]!=DELETED_FLAG) && (buffer[i*0x20+0xB]!= ATTR_EXT && (buffer[i*0x20+0xB]&ATTR_DIR)!=0)) /* Test directory */
410 {
411 nb_subdir++;
412 }
413 }
414 for(i=0;found && (i<cluster_size/32);i++)
415 {
416 const struct msdos_dir_entry *entry=(const struct msdos_dir_entry *)&buffer[i*0x20];
417 if((buffer[i*0x20]!=DELETED_FLAG) && (buffer[i*0x20+0xB]!= ATTR_EXT && (buffer[i*0x20+0xB]&ATTR_DIR)!=0)) /* Test directory */
418 {
419 const unsigned int cluster=fat_get_cluster_from_entry(entry);
420 /* log_debug("cluster %u\n",cluster); */
421 if(cluster>2+no_of_cluster ||
422 get_subdirectory(disk_car,
423 partition->part_offset+(start_data+(uint64_t)(cluster-2)*sectors_per_cluster) * disk_car->sector_size,
424 cluster)!=0)
425 {
426 /* if(verbose) */
427 /* log_debug("failed with %s\n",&buffer[i*0x20]); */
428 }
429 else
430 nb_subdir_ok++;
431 }
432 }
433 if(found)
434 {
435 if((nb_subdir_ok>nb_subdir*0.90)&&(nb_subdir>=3))
436 {
437 unsigned long int new_root_cluster;
438 unsigned long int tmp=root_cluster;
439 int back; /* To avoid an endless loop... */
440 /* Il faut ajouter un parcours arriere de la FAT
441 * car on localise le dernier cluster du root_cluster */
442 if(verbose>0)
443 log_verbose("cluster %lu, etat=%d, found=%u,nb_subdir=%d,nb_subdir_ok=%d\n",
444 root_cluster, etat, found, nb_subdir, nb_subdir_ok);
445 for(back=0; back<10; back++)
446 {
447 new_root_cluster=tmp;
448 tmp=fat32_get_prev_cluster(disk_car,partition,reserved,new_root_cluster,no_of_cluster);
449 if(verbose>0)
450 log_verbose("prev cluster(%lu)=>%lu\n",new_root_cluster,tmp);
451 if(tmp==0)
452 {
453 free(buffer);
454 return new_root_cluster;
455 }
456 /* Check cluster number */
457 if((tmp<2) || (tmp>=2+no_of_cluster))
458 {
459 log_error("bad cluster number\n");
460 free(buffer);
461 return new_root_cluster;
462 }
463 /* Read the cluster */
464 if((unsigned)disk_car->pread(disk_car, buffer, cluster_size,
465 partition->part_offset + (start_data + (uint64_t)(tmp - 2) * sectors_per_cluster) * disk_car->sector_size) != cluster_size)
466 {
467 log_critical("cluster can't be read\n");
468 free(buffer);
469 return new_root_cluster;
470 }
471 /* Check if this cluster is a directory structure. FAT can be damaged */
472 for(i=0;i<cluster_size/32;i++)
473 {
474 if(check_FAT_dir_entry(&buffer[i*0x20],i)!=1)
475 {
476 log_error("cluster data is not a directory structure\n");
477 free(buffer);
478 return new_root_cluster;
479 }
480 }
481 }
482 free(buffer);
483 return new_root_cluster;
484 }
485 else
486 {
487 if(verbose>1)
488 {
489 log_verbose("cluster %lu, etat=%d, found=%u, nb_subdir=%d, nb_subdir_ok=%d\n",
490 root_cluster, etat, found, nb_subdir, nb_subdir_ok);
491 }
492 }
493 {
494 file_info_t dir_list;
495 TD_INIT_LIST_HEAD(&dir_list.list);
496 dir_fat_aux(buffer, cluster_size, 0, &dir_list);
497 if(is_root_cluster_candidat(&dir_list))
498 {
499 int test_date=1;
500 if(verbose>0)
501 {
502 log_verbose("Potential root_cluster %lu\n",root_cluster);
503 test_date=dir_aff_log(NULL, &dir_list);
504 }
505 #ifdef HAVE_NCURSES
506 if(interactive>0 && test_date>0)
507 {
508 switch(ask_root_directory(disk_car, partition, &dir_list, root_cluster))
509 {
510 case c_YES:
511 delete_list_file(&dir_list);
512 free(buffer);
513 return root_cluster;
514 case 'A':
515 interactive=0;
516 break;
517 case 'Q':
518 delete_list_file(&dir_list);
519 free(buffer);
520 return 0;
521 default:
522 break;
523 }
524 }
525 #endif
526 }
527 delete_list_file(&dir_list);
528 }
529 }
530 }
531
532 }
533 }
534 if(ind_stop!=0)
535 log_info("Search root cluster stopped: %10lu (2..%lu)\n",root_cluster,no_of_cluster+1);
536 else
537 log_error("Search root cluster failed\n");
538 root_cluster=0;
539 if(td_list_empty(&rootdir_list.list))
540 {
541 log_warning("No first-level directory found.\n");
542 }
543 else
544 {
545 dir_aff_log(NULL, &rootdir_list);
546 #ifdef HAVE_NCURSES
547 if(expert>0)
548 {
549 if(ask_confirmation("Create a new root cluster with %u first-level directories (Expert only) (Y/N)",dir_nbr)!=0 && ask_confirmation("Write root cluster, confirm ? (Y/N)")!=0)
550 {
551 root_cluster=first_free_cluster;
552 fat32_create_rootdir(disk_car, partition, reserved, fat_length, root_cluster, sectors_per_cluster, verbose, &rootdir_list, fats);
553 }
554 }
555 #endif
556 delete_list_file(&rootdir_list);
557 }
558 free(buffer);
559 }
560 return root_cluster;
561 }
562
563 #ifdef HAVE_NCURSES
564
fat_date_unix2dos(int unix_date,unsigned short * mstime,unsigned short * msdate)565 static void fat_date_unix2dos(int unix_date,unsigned short *mstime, unsigned short *msdate)
566 {
567 static const int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
568 /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
569 int day,year,nl_day,month;
570
571 /* unix_date -= sys_tz.tz_minuteswest*60; */
572
573 /* Jan 1 GMT 00:00:00 1980. But what about another time zone? */
574 if (unix_date < 315532800)
575 unix_date = 315532800;
576
577 *mstime = le16((unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
578 (((unix_date/3600) % 24) << 11));
579 day = unix_date/86400-3652;
580 year = day/365;
581 if ((year+3)/4+365*year > day)
582 year--;
583 day -= (year+3)/4+365*year;
584 if (day == 59 && !(year & 3)) {
585 nl_day = day;
586 month = 2;
587 }
588 else {
589 nl_day = (year & 3) || day <= 59 ? day : day-1;
590 for (month = 1; month < 12; month++)
591 if (day_n[month] > nl_day)
592 break;
593 }
594 *msdate = le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9));
595 }
596
file2entry(struct msdos_dir_entry * de,const file_info_t * current_file)597 static int file2entry(struct msdos_dir_entry *de, const file_info_t *current_file)
598 {
599 unsigned int i,j;
600 /* Name */
601 for(i=0;
602 i<8 && current_file->name[i]!='.' && current_file->name[i]!='\0';
603 i++)
604 {
605 de->name[i]=current_file->name[i];
606 }
607 for(j=i;j<8;j++)
608 {
609 de->name[j]=' ';
610 }
611 /* Extension */
612 for(;
613 current_file->name[i]!='.' && current_file->name[i]!='\0';
614 i++);
615 for(j=0;
616 j<3 && current_file->name[i]!='\0';
617 j++)
618 {
619 de->ext[j]=current_file->name[i];
620 }
621 for(;j<3;j++)
622 {
623 de->ext[j]=' ';
624 }
625 de->attr=(LINUX_S_ISDIR(current_file->st_mode)!=0?ATTR_DIR:ATTR_NONE);
626 fat_date_unix2dos(current_file->td_mtime,&de->time,&de->date);
627 de->start=le16(current_file->st_ino);
628 de->starthi=le16(current_file->st_ino>>16);
629 de->size=le32(current_file->st_size);
630 return 0;
631 }
632
fat32_create_rootdir(disk_t * disk_car,const partition_t * partition,const unsigned int reserved,const unsigned int fat_length,const unsigned int root_cluster,const unsigned int sectors_per_cluster,const int verbose,file_info_t * rootdir_list,const unsigned int fats)633 static int fat32_create_rootdir(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length, const unsigned int root_cluster, const unsigned int sectors_per_cluster, const int verbose, file_info_t *rootdir_list, const unsigned int fats)
634 {
635 const uint64_t start_data=reserved+fats*fat_length;
636 const unsigned int cluster_size=disk_car->sector_size*sectors_per_cluster;
637 unsigned int current_entry=0;
638 unsigned int cluster;
639 unsigned char *buffer;
640 struct td_list_head *file_walker = NULL;
641 if(verbose>0)
642 {
643 log_trace("fat32_create_rootdir(reserved=%u,fat_length=%u,root_cluster=%u,sectors_per_cluster=%u)\n",reserved,fat_length,root_cluster,sectors_per_cluster);
644 }
645 cluster=root_cluster;
646 buffer=(unsigned char *)MALLOC(cluster_size);
647 memset(buffer,0,cluster_size);
648 td_list_for_each(file_walker, &rootdir_list->list)
649 {
650 const file_info_t *current_file=td_list_entry_const(file_walker, const file_info_t, list);
651 file2entry((struct msdos_dir_entry*)buffer+current_entry,current_file);
652 if(++current_entry==(cluster_size/sizeof(struct msdos_dir_entry)))
653 {
654 unsigned int next_cluster;
655 if((unsigned)disk_car->pwrite(disk_car, buffer, cluster_size,
656 partition->part_offset + (start_data + (uint64_t)(cluster - 2) * sectors_per_cluster) * disk_car->sector_size) != cluster_size)
657 {
658 display_message("Write error: Can't create FAT32 root cluster.\n");
659 }
660 current_entry=0;
661 memset(buffer,0,cluster_size);
662 /* FIXME need to write fat32_get_next_free_cluster */
663 next_cluster=cluster++;
664 if(set_next_cluster(disk_car,partition,UP_FAT32,reserved,cluster,next_cluster))
665 {
666 display_message("Can't modify the FAT entries.\n");
667 }
668 if(set_next_cluster(disk_car,partition,UP_FAT32,reserved+fat_length,cluster,next_cluster))
669 {
670 display_message("Can't modify the FAT entries.\n");
671 }
672 cluster=next_cluster;
673 }
674 }
675 if((unsigned)disk_car->pwrite(disk_car, buffer, cluster_size, partition->part_offset + (start_data + (uint64_t)(cluster - 2) * sectors_per_cluster) * disk_car->sector_size) != cluster_size)
676 {
677 display_message("Write error: Can't create FAT32 root cluster.\n");
678 }
679 if(set_next_cluster(disk_car,partition,UP_FAT32,reserved,cluster,FAT32_EOC))
680 {
681 display_message("Can't modify the FAT entries.\n");
682 }
683 if(set_next_cluster(disk_car,partition,UP_FAT32,reserved+fat_length,cluster,FAT32_EOC))
684 {
685 display_message("Can't modify the FAT entries.\n");
686 }
687 #ifdef DEBUG
688 {
689 file_info_t dir_list;
690 TD_INIT_LIST_HEAD(&dir_list.list);
691 dir_fat_aux(buffer, cluster_size, 0, &dir_list);
692 dir_aff_log(NULL, dir_list);
693 delete_list_file(&dir_list);
694 }
695 #endif
696 free(buffer);
697 return 0;
698 }
699 #endif
700
find_dir_entries(disk_t * disk_car,const partition_t * partition,const unsigned int offset,const int verbose)701 static int find_dir_entries(disk_t *disk_car,const partition_t *partition, const unsigned int offset,const int verbose)
702 {
703 uint64_t hd_offset;
704 unsigned int i;
705 int dir_entry_found=0;
706 unsigned char *buffer=(unsigned char *)MALLOC(disk_car->sector_size);
707 for(i=0, hd_offset=partition->part_offset+(uint64_t)offset*disk_car->sector_size;
708 i<200 && i<offset;
709 i++, hd_offset-=disk_car->sector_size)
710 {
711 if((unsigned)disk_car->pread(disk_car, buffer, disk_car->sector_size, hd_offset) != disk_car->sector_size)
712 {
713 log_error("dir_entries: read error, dir_entries>=%u (%u sectors)\n",i*(disk_car->sector_size/32),i);
714 }
715 else
716 {
717 unsigned int j;
718 /* A directory entry is 32 bytes long *
719 * Entries has allocated by whole sector */
720 for(j=disk_car->sector_size/32-1;j>0;j--)
721 {
722 if(verbose>1)
723 {
724 log_verbose("find_dir_entries sector=%u entry=%u dir_entry_found=%d\n",
725 offset-i, j, dir_entry_found);
726 }
727 if(dir_entry_found==0)
728 { /* Should be between the last directory entries and the first cluster */
729 switch(check_FAT_dir_entry(&buffer[j*32],j))
730 {
731 case 0: /* Empty entry */
732 break;
733 case 1: /* Non empty entry */
734 dir_entry_found=1;
735 break;
736 case 2: /* Failed */
737 free(buffer);
738 return 0;
739 }
740 }
741 else
742 {
743 if(check_FAT_dir_entry(&buffer[j*32],j)!=1)
744 { /* Must be in the FAT table */
745 free(buffer);
746 return (i-1)*(disk_car->sector_size/32);
747 }
748 }
749 }
750 }
751 }
752 free(buffer);
753 return 0;
754 }
755
analyse_dir_entries(disk_t * disk_car,const partition_t * partition,const unsigned int offset,const int verbose)756 static int analyse_dir_entries(disk_t *disk_car,const partition_t *partition, const unsigned int offset,const int verbose)
757 {
758 unsigned int i,j;
759 int etat=0;
760 unsigned int sector_etat1=0;
761 uint64_t hd_offset;
762 unsigned char *buffer=(unsigned char *)MALLOC(disk_car->sector_size);
763 hd_offset=partition->part_offset+(uint64_t)offset*disk_car->sector_size;
764 for(i=0;i<200;i++)
765 {
766 if((unsigned)disk_car->pread(disk_car, buffer, disk_car->sector_size, hd_offset) != disk_car->sector_size)
767 {
768 log_error("dir_entries: read error, dir_entries>=%u (%u sectors)\n",i*(disk_car->sector_size/32),i);
769 }
770 else
771 {
772 for(j=0;j<(disk_car->sector_size/32);j++)
773 {
774 if(check_FAT_dir_entry(&buffer[j*0x20],j)==0)
775 { /* Empty entry */
776 if(etat==0)
777 {
778 if(i==0 && j==0)
779 { /* The first entry must not be empty, otherwise there is no file */
780 free(buffer);
781 return 0;
782 }
783 etat=1;
784 sector_etat1=i;
785 if(verbose>0)
786 log_verbose("dir_entries 0->1 %u\n", i*(disk_car->sector_size/32)+j);
787 }
788 }
789 else
790 { /* Not an entry or non empty entry */
791 if(etat==1)
792 {
793 free(buffer);
794 if(i==sector_etat1)
795 { /* In the same sector, empty entry must not be followed by non-empty entry */
796 return 0;
797 }
798 /* Data found */
799 if(verbose>0)
800 log_verbose("dir_entries 1->2 %u\n", i*(disk_car->sector_size/32)+j);
801 return i*(disk_car->sector_size/32);
802 }
803 }
804 }
805 }
806 hd_offset+=disk_car->sector_size;
807 }
808 free(buffer);
809 return 0;
810 }
811
analyse_dir_entries2(disk_t * disk_car,const partition_t * partition,const unsigned int reserved,const unsigned int fat_length,const int verbose,unsigned int root_size_max,const upart_type_t upart_type,const unsigned int fats)812 static int analyse_dir_entries2(disk_t *disk_car,const partition_t *partition, const unsigned int reserved, const unsigned int fat_length,const int verbose, unsigned int root_size_max,const upart_type_t upart_type, const unsigned int fats)
813 {
814 unsigned char *buffer_dir;
815 unsigned int root_dir_size;
816 file_info_t dir_list;
817 struct td_list_head *file_walker = NULL;
818 TD_INIT_LIST_HEAD(&dir_list.list);
819 if(root_size_max==0)
820 {
821 root_size_max=4096;
822 }
823 root_dir_size=(root_size_max*32+disk_car->sector_size-1)/disk_car->sector_size*disk_car->sector_size;
824 buffer_dir=(unsigned char *)MALLOC(root_dir_size);
825 if((unsigned)disk_car->pread(disk_car, buffer_dir, root_dir_size,
826 partition->part_offset + (uint64_t)(reserved + fats * fat_length) * disk_car->sector_size) != root_dir_size)
827 {
828 log_error("FAT 1x can't read root directory\n");
829 free(buffer_dir);
830 return 0;
831 }
832 dir_fat_aux(buffer_dir, root_dir_size,
833 (partition->upart_type==UP_FAT12?FLAG_LIST_MASK12:FLAG_LIST_MASK16), &dir_list);
834 if(verbose>1)
835 {
836 dir_aff_log(NULL, &dir_list);
837 }
838 td_list_for_each(file_walker, &dir_list.list)
839 {
840 const file_info_t *current_file=td_list_entry_const(file_walker, const file_info_t, list);
841 if(LINUX_S_ISDIR(current_file->st_mode) && (current_file->status&FILE_STATUS_DELETED)==0)
842 {
843 const unsigned long int new_inode=current_file->st_ino;
844 unsigned int dir_entries;
845 if(verbose>1)
846 {
847 log_verbose("Directory %s used inode=%lu\n",current_file->name,new_inode);
848 }
849 for(dir_entries=disk_car->sector_size/32;
850 dir_entries <= root_size_max;
851 dir_entries+=disk_car->sector_size/32)
852 {
853 const uint64_t start_data=reserved+fats*fat_length+(dir_entries+(disk_car->sector_size/32)-1)/(disk_car->sector_size/32);
854 const unsigned int sectors_per_cluster=calcul_sectors_per_cluster(upart_type,partition->part_size/disk_car->sector_size-start_data,fat_length,disk_car->sector_size);
855 if(verbose>1)
856 {
857 log_verbose("dir_entries %u, sectors_per_cluster %u\n",dir_entries,sectors_per_cluster);
858 }
859 if((unsigned)disk_car->pread(disk_car, buffer_dir, disk_car->sector_size,
860 partition->part_offset + (start_data + (uint64_t)(new_inode - 2) * sectors_per_cluster) * disk_car->sector_size) == disk_car->sector_size)
861 {
862 if(buffer_dir[0]=='.' && is_fat_directory(buffer_dir))
863 {
864 const unsigned long int cluster=fat_get_cluster_from_entry((const struct msdos_dir_entry *)&buffer_dir[0]);
865 const unsigned long int cluster_prev=fat_get_cluster_from_entry((const struct msdos_dir_entry *)&buffer_dir[0x20]);
866 if(verbose>1)
867 {
868 log_verbose("Cluster %lu, directory .. found link to %lu\n", cluster, cluster_prev);
869 }
870 if(cluster_prev==0 && cluster==new_inode)
871 {
872 free(buffer_dir);
873 delete_list_file(&dir_list);
874 return ((dir_entries+(disk_car->sector_size/32)-1)/(disk_car->sector_size/32))*(disk_car->sector_size/32);
875 }
876 }
877 }
878 }
879 }
880 }
881 log_warning("No directory found\n");
882 free(buffer_dir);
883 delete_list_file(&dir_list);
884 return root_size_max;
885 }
886
887 #ifdef HAVE_NCURSES
fat32_dump_ncurses(disk_t * disk_car,const partition_t * partition,const upart_type_t upart_type,const unsigned char * orgboot,const unsigned char * newboot)888 static void fat32_dump_ncurses(disk_t *disk_car, const partition_t *partition, const upart_type_t upart_type, const unsigned char *orgboot, const unsigned char *newboot)
889 {
890 WINDOW *window=newwin(LINES, COLS, 0, 0); /* full screen */
891 keypad(window, TRUE); /* Need it to get arrow key */
892 aff_copy(window);
893 wmove(window,4,0);
894 wprintw(window,"%s",disk_car->description(disk_car));
895 wmove(window,5,0);
896 aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
897 mvwaddstr(window,6,0, " Rebuild Boot sector Boot sector");
898 dump2(window, newboot,orgboot, (unsigned int)(upart_type==UP_FAT32?3*disk_car->sector_size:DEFAULT_SECTOR_SIZE));
899 delwin(window);
900 (void) clearok(stdscr, TRUE);
901 #ifdef HAVE_TOUCHWIN
902 touchwin(stdscr);
903 #endif
904 }
905 #endif
906
fat32_dump(disk_t * disk_car,const partition_t * partition,const upart_type_t upart_type,const unsigned char * orgboot,const unsigned char * newboot,char ** current_cmd)907 static void fat32_dump(disk_t *disk_car, const partition_t *partition, const upart_type_t upart_type, const unsigned char *orgboot, const unsigned char *newboot, char **current_cmd)
908 {
909 log_info(" Rebuild Boot sector Boot sector\n");
910 dump2_log(newboot,orgboot, (unsigned int)(upart_type==UP_FAT32?3*disk_car->sector_size:DEFAULT_SECTOR_SIZE));
911 if(*current_cmd==NULL)
912 {
913 #ifdef HAVE_NCURSES
914 fat32_dump_ncurses(disk_car, partition, upart_type, orgboot, newboot);
915 #endif
916 }
917 }
918
menu_write_fat_boot_sector(disk_t * disk_car,partition_t * partition,const int verbose,const upart_type_t upart_type,const unsigned char * orgboot,const unsigned char * newboot,const int error,char ** current_cmd)919 static void menu_write_fat_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const upart_type_t upart_type, const unsigned char *orgboot, const unsigned char*newboot, const int error, char **current_cmd)
920 {
921 const struct fat_boot_sector *fat_header=(const struct fat_boot_sector *)newboot;
922 #ifdef HAVE_NCURSES
923 const struct MenuItem menuSaveBoot[]=
924 {
925 { 'D', "Dump", "Dump sector" },
926 { 'L', "List", "List directories and files" },
927 { 'W', "Write","Write boot"},
928 { 'Q',"Quit","Quit this section"},
929 { 0, NULL, NULL }
930 };
931 #endif
932 const char *options="DLQ";
933 int do_write=0;
934 int do_exit=0;
935 int no_confirm=0;
936 do
937 {
938 int command;
939 do_exit=0;
940 #ifdef HAVE_NCURSES
941 aff_copy(stdscr);
942 wmove(stdscr,4,0);
943 wprintw(stdscr,"%s",disk_car->description(disk_car));
944 mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
945 wmove(stdscr,6,0);
946 aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
947 wmove(stdscr,8,0);
948 #endif
949 if(memcmp(newboot,orgboot,DEFAULT_SECTOR_SIZE)) /* Only compare the first sector */
950 {
951 #ifdef HAVE_NCURSES
952 const struct fat_boot_sector *org_fat_header=(const struct fat_boot_sector *)orgboot;
953 dump_2fat_info_ncurses(fat_header, org_fat_header, upart_type,disk_car->sector_size);
954 wprintw(stdscr,"Extrapolated boot sector and current boot sector are different.\n");
955 if(error)
956 wprintw(stdscr,"Warning: Extrapolated boot sector have incorrect values.\n");
957 #endif
958 if(error)
959 log_error("Warning: Extrapolated boot sector have incorrect values.\n");
960 options="DLWQ";
961 }
962 else
963 {
964 #ifdef HAVE_NCURSES
965 dump_fat_info_ncurses(fat_header, upart_type,disk_car->sector_size);
966 wprintw(stdscr,"Extrapolated boot sector and current boot sector are identical.\n");
967 #endif
968 }
969 if(*current_cmd!=NULL)
970 {
971 command='Q';
972 skip_comma_in_command(current_cmd);
973 if(check_command(current_cmd,"list",4)==0)
974 {
975 command='L';
976 }
977 else if(check_command(current_cmd,"dump",4)==0)
978 {
979 command='D';
980 }
981 else if(check_command(current_cmd,"noconfirm",9)==0)
982 {
983 command=0; /* do nothing */
984 no_confirm=1;
985 }
986 else if(check_command(current_cmd,"write",5)==0)
987 {
988 command='W';
989 }
990 }
991 else
992 {
993 #ifdef HAVE_NCURSES
994 command=wmenuSelect(stdscr, INTER_FATBS_Y+1, INTER_FATBS_Y, INTER_FATBS_X, menuSaveBoot,8,options,MENU_HORIZ|MENU_BUTTON, 1);
995 #else
996 command=0;
997 #endif
998 }
999 switch(command)
1000 {
1001 case 'w':
1002 case 'W':
1003 if(strchr(options,'W')!=NULL)
1004 do_write=1;
1005 break;
1006 case 'd':
1007 case 'D':
1008 if(strchr(options,'D')!=NULL)
1009 fat32_dump(disk_car, partition, upart_type, orgboot, newboot, current_cmd);
1010 break;
1011 case 'l':
1012 case 'L':
1013 {
1014 const upart_type_t old_upart_type=upart_type;
1015 partition->upart_type=upart_type;
1016 io_redir_add_redir(disk_car,partition->part_offset,3*disk_car->sector_size,0,newboot);
1017 dir_partition(disk_car, partition, verbose, 0, current_cmd);
1018 io_redir_del_redir(disk_car,partition->part_offset);
1019 partition->upart_type=old_upart_type;
1020 }
1021 break;
1022 case 'q':
1023 case 'Q':
1024 do_exit=1;
1025 break;
1026 }
1027 } while(do_write==0 && do_exit==0);
1028 if(do_write!=0 && (no_confirm!=0
1029 #ifdef HAVE_NCURSES
1030 || ask_confirmation("Write FAT boot sector, confirm ? (Y/N)")!=0
1031 #endif
1032 ))
1033 {
1034 int err=0;
1035 log_info("Write new boot!\n");
1036 /* Reset information about backup boot sector */
1037 partition->sb_offset=0;
1038 /* Write boot sector and backup boot sector */
1039 if(upart_type==UP_FAT32)
1040 {
1041 if((unsigned)disk_car->pwrite(disk_car, newboot, 3 * disk_car->sector_size, partition->part_offset) !=
1042 3 * disk_car->sector_size ||
1043 (unsigned)disk_car->pwrite(disk_car, newboot, 3 * disk_car->sector_size, partition->part_offset + (uint64_t)le16(fat_header->backup_boot) * disk_car->sector_size) !=
1044 3 * disk_car->sector_size)
1045 err=1;
1046 }
1047 else
1048 {
1049 if(disk_car->pwrite(disk_car, newboot, DEFAULT_SECTOR_SIZE, partition->part_offset) != DEFAULT_SECTOR_SIZE)
1050 err=1;
1051 }
1052 disk_car->sync(disk_car);
1053 if(err==1)
1054 {
1055 display_message("Write error: Can't write new FAT boot sector\n");
1056 }
1057 /* Note that TestDisk doesn't repair the filesystem itself, use another utility for that */
1058 }
1059 else
1060 log_info("Don't write new boot!\n");
1061 }
1062
create_fat_boot_sector(disk_t * disk_car,partition_t * partition,const unsigned int reserved,const int verbose,const unsigned int dir_entries,const unsigned long int root_cluster,const unsigned int sectors_per_cluster,const unsigned int fat_length,const upart_type_t upart_type,const unsigned int fats,char ** current_cmd)1063 static void create_fat_boot_sector(disk_t *disk_car, partition_t *partition, const unsigned int reserved, const int verbose, const unsigned int dir_entries, const unsigned long int root_cluster, const unsigned int sectors_per_cluster, const unsigned int fat_length, const upart_type_t upart_type, const unsigned int fats, char **current_cmd)
1064 {
1065 unsigned char *orgboot;
1066 unsigned char *newboot;
1067 const struct fat_boot_sector *org_fat_header;
1068 struct fat_boot_sector *fat_header;
1069 int error=0;
1070 unsigned long int part_size=0;
1071 orgboot=(unsigned char *)MALLOC(3*disk_car->sector_size);
1072 newboot=(unsigned char *)MALLOC(3*disk_car->sector_size);
1073 org_fat_header=(const struct fat_boot_sector *)orgboot;
1074 fat_header=(struct fat_boot_sector *)newboot;
1075 if((unsigned)disk_car->pread(disk_car, orgboot, 3 * disk_car->sector_size, partition->part_offset) != 3 * disk_car->sector_size)
1076 {
1077 log_error("create_fat_boot_sector: Can't read old boot sector\n");
1078 memset(orgboot,0,3*disk_car->sector_size);
1079 }
1080 memcpy(newboot,orgboot,3*disk_car->sector_size);
1081 if(3*disk_car->sector_size >= DEFAULT_SECTOR_SIZE &&
1082 (le16(fat_header->marker)!=0xAA55 ||
1083 !((fat_header->ignored[0]==0xeb && fat_header->ignored[2]==0x90)||fat_header->ignored[0]==0xe9)))
1084 {
1085 write_FAT_boot_code_aux(newboot);
1086 }
1087 fat_header->sector_size[0]=disk_car->sector_size & 0xFF;
1088 fat_header->sector_size[1]=disk_car->sector_size >>8;
1089 fat_header->fats=fats;
1090 fat_header->secs_track=le16(disk_car->geom.sectors_per_head);
1091 fat_header->heads=le16(disk_car->geom.heads_per_cylinder);
1092 fat_header->marker=le16(0xAA55);
1093 if(!((fat_header->ignored[0]==0xeb&&fat_header->ignored[2]==0x90)||fat_header->ignored[0]==0xe9))
1094 {
1095 fat_header->ignored[0]=0xeb;
1096 fat_header->ignored[2]=0x90;
1097 }
1098
1099 /* I have seen a FAT32 partition that Win98 2nd edition was unable to read
1100 * because this name was missing! */
1101 if(memcmp(fat_header->system_id,"MSDOS5.0",8) &&
1102 memcmp(fat_header->system_id,"MSWIN4.0",8) &&
1103 memcmp(fat_header->system_id,"MSWIN4.1",8))
1104 memcpy(fat_header->system_id,"MSWIN4.1",8);
1105 /* FIXME, need to know where the extended or logical partition start */
1106 #if 0
1107 if(partition->status==STATUS_LOG)
1108 fat_header->hidden=le32(disk_car->geom.sectors_per_head);
1109 else
1110 #endif
1111 fat_header->hidden=le32((partition->part_offset/disk_car->sector_size));
1112 fat_header->sectors_per_cluster=sectors_per_cluster;
1113 fat_header->reserved=le16(reserved);
1114 /* The filesystem size can be smaller than the partition size */
1115 switch(upart_type)
1116 {
1117 case UP_FAT12:
1118 part_size=le16(fat_header->reserved)+fats*fat_length+dir_entries*32/disk_car->sector_size+sectors_per_cluster*(fat_length*disk_car->sector_size*2/3-2);
1119 break;
1120 case UP_FAT16:
1121 part_size=le16(fat_header->reserved)+fats*fat_length+dir_entries*32/disk_car->sector_size+sectors_per_cluster*(fat_length*(disk_car->sector_size/2)-2);
1122 break;
1123 case UP_FAT32:
1124 part_size=le16(fat_header->reserved)+fats*fat_length+sectors_per_cluster*(fat_length*(disk_car->sector_size/4)-2);
1125 break;
1126 default:
1127 log_critical("create_fat_boot_sector: severe error\n");
1128 log_close();
1129 exit(1);
1130 }
1131 if(part_size>partition->part_size/disk_car->sector_size)
1132 part_size=partition->part_size/disk_car->sector_size;
1133 if(part_size>0xFFFF)
1134 {
1135 fat_header->sectors[0]=0;
1136 fat_header->sectors[1]=0;
1137 fat_header->total_sect=le32(part_size);
1138 }
1139 else
1140 {
1141 fat_header->sectors[1]=part_size>>8;
1142 fat_header->sectors[0]=part_size;
1143 fat_header->total_sect=le32(0);
1144 }
1145 switch(upart_type)
1146 {
1147 case UP_FAT12:
1148 fat_header->media=0xF0; /* Floppy */
1149 if((fat_length==0) || (dir_entries==0))
1150 error=1;
1151 if((newboot[36]<0x80)||(newboot[36]>0x88))
1152 newboot[36]=0x80; /* BS_DrvNum=0x80 */
1153 newboot[37]=0; /* BS_Reserved1=0 */
1154 newboot[38]=0x29; /* Boot sig=0x29 */
1155 if(memcmp(newboot+FAT_NAME2,"FAT32",5)==0)
1156 memcpy(newboot+FAT_NAME2, " ",8);
1157 memcpy(newboot+FAT_NAME1,"FAT12 ",8);
1158 fat_header->fat_length=le16(fat_length);
1159 fat_header->dir_entries[1]=dir_entries>>8;
1160 fat_header->dir_entries[0]=dir_entries;
1161 if(check_VFAT_volume_name((const char*)&newboot[FAT1X_PART_NAME],11))
1162 newboot[FAT1X_PART_NAME]='\0';
1163 break;
1164 case UP_FAT16:
1165 fat_header->media=0xF8; /* Hard Disk*/
1166 if((fat_length==0) || (dir_entries==0))
1167 error=1;
1168 if((newboot[36]<0x80)||(newboot[36]>0x88))
1169 newboot[36]=0x80; /* BS_DrvNum */
1170 newboot[37]=0; /* BS_Reserved1=0 */
1171 newboot[38]=0x29; /* Boot sig=0x29 */
1172 if(memcmp(newboot+FAT_NAME2,"FAT32",5)==0)
1173 memcpy(newboot+FAT_NAME2, " ",8);
1174 memcpy(newboot+FAT_NAME1,"FAT16 ",8);
1175 fat_header->fat_length=le16(fat_length);
1176 fat_header->dir_entries[1]=dir_entries>>8;
1177 fat_header->dir_entries[0]=dir_entries;
1178 if(check_VFAT_volume_name((const char*)&newboot[FAT1X_PART_NAME],11))
1179 newboot[FAT1X_PART_NAME]='\0';
1180 break;
1181 case UP_FAT32:
1182 fat_header->media=0xF8; /* Hard Disk*/
1183 if((fat_length==0) || (root_cluster==0))
1184 error=1;
1185 fat_header->fat_length=le16(0);
1186 fat_header->dir_entries[0]=0;
1187 fat_header->dir_entries[1]=0;
1188 fat_header->fat32_length=le32(fat_length);
1189 /*
1190 Bits 0-3 -- Zero-based number of active FAT. Only valid if mirroring
1191 is disabled.
1192 Bits 4-6 -- Reserved.
1193 Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs.
1194 -- 1 means only one FAT is active; it is the one referenced
1195 in bits 0-3.
1196 Bits 8-15 -- Reserved.
1197 */
1198 fat_header->flags=le16(0);
1199 fat_header->version[0]=0;
1200 fat_header->version[1]=0;
1201 fat_header->root_cluster=le32(root_cluster);
1202 /* Sector number of FSINFO structure in the reserved area of the FAT32 volume. */
1203 fat_header->info_sector=le16(1);
1204 fat_header->backup_boot=le16(6);
1205 memset(&fat_header->BPB_Reserved,0,sizeof(fat_header->BPB_Reserved));
1206 if((fat_header->BS_DrvNum<0x80)||(fat_header->BS_DrvNum>0x87))
1207 fat_header->BS_DrvNum=0x80;
1208 fat_header->BS_Reserved1=0;
1209 fat_header->BS_BootSig=0x29;
1210 if((memcmp(newboot+FAT_NAME1,"FAT12",5)==0) ||(memcmp(newboot+FAT_NAME1,"FAT16",5)==0))
1211 memcpy(newboot+FAT_NAME1," ",8);
1212 memcpy(fat_header->BS_FilSysType, "FAT32 ",8);
1213 newboot[0x1FC]=0x00; /* part of the signature */
1214 newboot[0x1FD]=0x00;
1215 memset(&newboot[disk_car->sector_size],0,2*disk_car->sector_size);
1216 newboot[disk_car->sector_size]='R'; /* Signature RRaA */
1217 newboot[disk_car->sector_size+1]='R';
1218 newboot[disk_car->sector_size+2]='a';
1219 newboot[disk_car->sector_size+3]='A';
1220 newboot[disk_car->sector_size+0x1E4]='r'; /* Signature rrAa */
1221 newboot[disk_car->sector_size+0x1E5]='r';
1222 newboot[disk_car->sector_size+0x1E6]='A';
1223 newboot[disk_car->sector_size+0x1E7]='a';
1224 /* Don't set the number of free cluster or the next free cluster */
1225 newboot[disk_car->sector_size+0x1E8]=0xFF; /* 488: Free clusters on disk */
1226 newboot[disk_car->sector_size+0x1E9]=0xFF;
1227 newboot[disk_car->sector_size+0x1EA]=0xFF;
1228 newboot[disk_car->sector_size+0x1EB]=0xFF;
1229 newboot[disk_car->sector_size+0x1EC]=0xFF; /* 492: Next available clusters */
1230 newboot[disk_car->sector_size+0x1ED]=0xFF;
1231 newboot[disk_car->sector_size+0x1EE]=0xFF;
1232 newboot[disk_car->sector_size+0x1EF]=0xFF;
1233 newboot[disk_car->sector_size+0x1FC]=0x00; /* End of Sector signature */
1234 newboot[disk_car->sector_size+0x1FD]=0x00;
1235 newboot[disk_car->sector_size+0x1FE]=0x55;
1236 newboot[disk_car->sector_size+0x1FF]=0xAA;
1237 newboot[2*disk_car->sector_size+0x1FC]=0x00; /* End of Sector signature */
1238 newboot[2*disk_car->sector_size+0x1FD]=0x00;
1239 newboot[2*disk_car->sector_size+0x1FE]=0x55;
1240 newboot[2*disk_car->sector_size+0x1FF]=0xAA;
1241 if(check_VFAT_volume_name((const char*)&newboot[FAT32_PART_NAME],11))
1242 newboot[FAT32_PART_NAME]='\0';
1243 break;
1244 default:
1245 log_critical("create_fat_boot_sector: severe error\n");
1246 log_close();
1247 exit(1);
1248 }
1249 if(memcmp(newboot,orgboot,1*DEFAULT_SECTOR_SIZE)) /* Only compare the first sector */
1250 {
1251 log_warning(" New / Current boot sector");
1252 log_fat2_info(fat_header,org_fat_header,upart_type,disk_car->sector_size);
1253 log_warning("Extrapolated boot sector and current boot sector are different.\n");
1254 }
1255 else
1256 {
1257 log_info("Extrapolated boot sector and current boot sector are identical.\n");
1258 }
1259 menu_write_fat_boot_sector(disk_car, partition, verbose, upart_type, orgboot, newboot, error, current_cmd);
1260 free(orgboot);
1261 free(newboot);
1262 }
1263
calcul_sectors_per_cluster(const upart_type_t upart_type,const unsigned long int data_size,const unsigned int fat_length,const unsigned int sector_size)1264 static int calcul_sectors_per_cluster(const upart_type_t upart_type, const unsigned long int data_size, const unsigned int fat_length, const unsigned int sector_size)
1265 {
1266 /* log_info("calcul_sectors_per_cluster data_size=%lu, fat_length=%u, sector_size=%u\n",data_size,fat_length,sector_size); */
1267 if(fat_length==0)
1268 return 0;
1269 switch(upart_type)
1270 {
1271 case UP_FAT12:
1272 return up2power(data_size/(fat_length*sector_size*2/3-1));
1273 case UP_FAT16:
1274 return up2power(data_size/(fat_length*sector_size/2-1));
1275 case UP_FAT32:
1276 return up2power(data_size/(fat_length*sector_size/4-1));
1277 default:
1278 log_critical("calcul_sectors_per_cluster: severe error\n");
1279 return 0;
1280 }
1281 }
1282
fat_find_fat_start(const unsigned char * buffer,const int p_fat12,const int p_fat16,const int p_fat32,unsigned long int * fat_offset,const unsigned int sector_size)1283 static unsigned int fat_find_fat_start(const unsigned char *buffer,const int p_fat12, const int p_fat16, const int p_fat32,unsigned long int*fat_offset, const unsigned int sector_size)
1284 {
1285 /* TODO: handle limited size of info_offset */
1286 info_offset_t *info_offset;
1287 unsigned int nbr_offset=0;
1288 int have_fat_signature=0;
1289 info_offset=(info_offset_t *)MALLOC(sector_size*sizeof(info_offset_t));
1290 if(p_fat12!=0)
1291 {
1292 unsigned int i;
1293 unsigned int low;
1294 unsigned int high;
1295 i=0;
1296 high=0;
1297 low=0;
1298 while(high<(sector_size-1))
1299 {
1300 unsigned long int cluster=0;
1301 if(low==0)
1302 cluster=((buffer[high+1] & 0x0F) <<8) | buffer[high];
1303 else
1304 cluster=(buffer[high+1] <<4) | ((buffer[high]&0xF0)>>4);
1305 if((cluster!=0) && ((cluster&0x0ff8)!=(unsigned)0x0ff8) && (((cluster-i-1)*3)%(2*sector_size)==0))
1306 {
1307 unsigned int j;
1308 for(j=0;(j<nbr_offset) &&
1309 (info_offset[j].offset!=(cluster-i-1)*3/(2*sector_size) || info_offset[j].fat_type!=12);j++);
1310 if(j<nbr_offset)
1311 info_offset[j].nbr++;
1312 else
1313 {
1314 info_offset[nbr_offset].offset=(cluster-i-1)*3/(2*sector_size);
1315 info_offset[nbr_offset].nbr=1;
1316 info_offset[nbr_offset].fat_type=12;
1317 nbr_offset++;
1318 }
1319 }
1320 if(low==0)
1321 low=1;
1322 else
1323 {
1324 high++;
1325 low=0;
1326 }
1327 high++;
1328 i++;
1329 }
1330 i=1;
1331 high=1;
1332 low=0;
1333 while(high<(sector_size-1))
1334 {
1335 unsigned long int cluster=0;
1336 if(low==0)
1337 cluster=((buffer[high+1] & 0x0F) <<8) | buffer[high];
1338 else
1339 cluster=(buffer[high+1] <<4) | ((buffer[high]&0xF0)>>4);
1340 if((cluster!=0) && ((cluster&0x0ff8)!=(unsigned)0x0ff8) && (((cluster-i-1)*3+1)%(2*sector_size)==0))
1341 {
1342 unsigned int j;
1343 for(j=0;(j<nbr_offset) &&
1344 (info_offset[j].offset!=((cluster-i-1)*3+1)/(2*sector_size) || info_offset[j].fat_type!=12);j++);
1345 if(j<nbr_offset)
1346 info_offset[j].nbr++;
1347 else
1348 {
1349 info_offset[nbr_offset].offset=((cluster-i-1)*3+1)/(2*sector_size);
1350 info_offset[nbr_offset].nbr=1;
1351 info_offset[nbr_offset].fat_type=12;
1352 nbr_offset++;
1353 }
1354 }
1355 if(low==0)
1356 low=1;
1357 else
1358 {
1359 high++;
1360 low=0;
1361 }
1362 high++;
1363 i++;
1364 }
1365 i=1;
1366 high=0;
1367 low=1;
1368 while(high<(sector_size-1))
1369 {
1370 unsigned long int cluster=0;
1371 if(low==0)
1372 cluster=((buffer[high+1] & 0x0F) <<8) | buffer[high];
1373 else
1374 cluster=(buffer[high+1] <<4) | ((buffer[high]&0xF0)>>4);
1375 if((cluster!=0) && ((cluster&0x0ff8)!=(unsigned)0x0ff8) && (((cluster-i-1)*3+2)%(2*sector_size)==0))
1376 {
1377 unsigned int j;
1378 for(j=0;(j<nbr_offset) &&
1379 (info_offset[j].offset!=((cluster-i-1)*3+2)/(2*sector_size) || info_offset[j].fat_type!=12);j++);
1380 if(j<nbr_offset)
1381 info_offset[j].nbr++;
1382 else
1383 {
1384 info_offset[nbr_offset].offset=((cluster-i-1)*3+2)/(2*sector_size);
1385 info_offset[nbr_offset].nbr=1;
1386 info_offset[nbr_offset].fat_type=12;
1387 nbr_offset++;
1388 }
1389 }
1390 if(low==0)
1391 low=1;
1392 else
1393 {
1394 high++;
1395 low=0;
1396 }
1397 high++;
1398 i++;
1399 }
1400 if((buffer[0]==0xF0 || buffer[0]>=0xF8) && buffer[1]==0xFF)
1401 {
1402 unsigned int j;
1403 for(j=0;(j<nbr_offset) &&
1404 (info_offset[j].offset!=0 || info_offset[j].fat_type!=12);j++);
1405 if(j<nbr_offset)
1406 info_offset[j].nbr++;
1407 else
1408 {
1409 info_offset[nbr_offset].offset=0;
1410 info_offset[nbr_offset].nbr=1;
1411 info_offset[nbr_offset].fat_type=12;
1412 nbr_offset++;
1413 }
1414 have_fat_signature=1;
1415 }
1416 }
1417 if(p_fat16!=0)
1418 {
1419 unsigned int i,j;
1420 const uint16_t *p16=(const uint16_t*)buffer;
1421 unsigned int err=0;
1422 for(i=0; (i<sector_size/2)&&(err==0); i++)
1423 {
1424 unsigned long int cluster=le16(p16[i]);
1425 if(cluster==1)
1426 {
1427 err=1;
1428 }
1429 if((cluster!=0) && ((cluster&0x0fff8)!=(unsigned)0x0fff8))
1430 {
1431 for(j=i+1; (j<sector_size/2)&&(err==0); j++)
1432 {
1433 if(cluster==le16(p16[j]))
1434 {
1435 err=1;
1436 }
1437 }
1438 }
1439 }
1440 if(err==0)
1441 {
1442 for(i=0; i<sector_size/2; i++)
1443 {
1444 unsigned long int cluster=le16(p16[i]);
1445 if((cluster!=0) && ((cluster&0x0fff8)!=(unsigned)0x0fff8)&&((cluster-i-1)%(sector_size/2)==0))
1446 {
1447 for(j=0;(j<nbr_offset) &&
1448 (info_offset[j].offset!=(cluster-i-1)/(sector_size/2) || info_offset[j].fat_type!=16);j++);
1449 if(j<nbr_offset)
1450 info_offset[j].nbr++;
1451 else
1452 {
1453 info_offset[nbr_offset].offset=(cluster-i-1)/(sector_size/2);
1454 info_offset[nbr_offset].nbr=1;
1455 info_offset[nbr_offset].fat_type=16;
1456 nbr_offset++;
1457 }
1458 }
1459 }
1460 }
1461 if((buffer[0]==0xF0 || buffer[0]>=0xF8) && buffer[1]==0xFF
1462 && buffer[2]==0xFF && ((buffer[3] & 0xF7)==0xF7))
1463 {
1464 for(j=0;(j<nbr_offset)&& (info_offset[j].offset!=0 || info_offset[j].fat_type!=16);j++);
1465 if(j<nbr_offset)
1466 info_offset[j].nbr++;
1467 else
1468 {
1469 info_offset[nbr_offset].offset=0;
1470 info_offset[nbr_offset].nbr=1;
1471 info_offset[nbr_offset].fat_type=16;
1472 nbr_offset++;
1473 }
1474 have_fat_signature=1;
1475 }
1476 }
1477 if(p_fat32!=0)
1478 {
1479 unsigned int i,j;
1480 const uint32_t *p32=(const uint32_t*)buffer;
1481 unsigned int err=0;
1482 for(i=0; (i<sector_size/4)&&(err==0); i++)
1483 {
1484 unsigned long int cluster=le32(p32[i])&0x0FFFFFFF;
1485 if(cluster==1)
1486 {
1487 err=1;
1488 }
1489 if((cluster!=0) && ((cluster&0x0ffffff8)!=(unsigned)0x0ffffff8))
1490 {
1491 for(j=i+1; (j<sector_size/4)&&(err==0); j++)
1492 {
1493 if(cluster==(le32(p32[j])&0x0FFFFFFF))
1494 {
1495 err=1;
1496 }
1497 }
1498 }
1499 }
1500 if(err==0)
1501 {
1502 for(i=0; i<sector_size/4; i++)
1503 {
1504 unsigned long int cluster=le32(p32[i])&0x0FFFFFFF;
1505 if((cluster!=0) && ((cluster&0x0ffffff8)!=(unsigned)0x0ffffff8)&&((cluster-i-1)%(sector_size/4)==0))
1506 {
1507 for(j=0;(j<nbr_offset) &&
1508 ((info_offset[j].offset!=(cluster-i-1)/(sector_size/4)) || (info_offset[j].fat_type!=32));j++);
1509 if(j<nbr_offset)
1510 info_offset[j].nbr++;
1511 else
1512 {
1513 info_offset[nbr_offset].offset=(cluster-i-1)/(sector_size/4);
1514 info_offset[nbr_offset].nbr=1;
1515 info_offset[nbr_offset].fat_type=32;
1516 nbr_offset++;
1517 }
1518 }
1519 }
1520 }
1521 if((buffer[0]==0xF0 || buffer[0]>=0xF8) && buffer[1]==0xFF &&
1522 buffer[2]==0xFF && ((buffer[3]==0x0F) ||(buffer[3]==0xFF)) &&
1523 buffer[4]==0xFF && buffer[5]==0xFF && buffer[6]==0xFF)
1524 {
1525 for(j=0;(j<nbr_offset)&&(info_offset[j].offset!=0 || info_offset[j].fat_type!=32);j++);
1526 if(j<nbr_offset)
1527 info_offset[j].nbr++;
1528 else
1529 {
1530 info_offset[nbr_offset].offset=0;
1531 info_offset[nbr_offset].nbr=1;
1532 info_offset[nbr_offset].fat_type=32;
1533 nbr_offset++;
1534 }
1535 have_fat_signature=1;
1536 }
1537 }
1538 if(nbr_offset>0)
1539 {
1540 unsigned int j;
1541 unsigned int best_j=0;
1542 for(j=0;j<nbr_offset;j++)
1543 {
1544 if(info_offset[j].nbr>info_offset[best_j].nbr)
1545 best_j=j;
1546 }
1547 if(info_offset[best_j].nbr>10 || have_fat_signature>0)
1548 {
1549 unsigned int res;
1550 *fat_offset=info_offset[best_j].offset;
1551 res=info_offset[best_j].fat_type;
1552 free(info_offset);
1553 return res;
1554 }
1555 }
1556 free(info_offset);
1557 return 0;
1558 }
1559
fat_find_type(disk_t * disk_car,const partition_t * partition,const uint64_t max_offset,const int p_fat12,const int p_fat16,const int p_fat32,const int verbose,const int dump_ind,unsigned int * nbr_offset,info_offset_t * info_offset,const unsigned int max_nbr_offset)1560 static int fat_find_type(disk_t *disk_car, const partition_t *partition, const uint64_t max_offset, const int p_fat12, const int p_fat16, const int p_fat32, const int verbose, const int dump_ind, unsigned int *nbr_offset, info_offset_t *info_offset, const unsigned int max_nbr_offset)
1561 {
1562 uint64_t offset;
1563 #ifdef HAVE_NCURSES
1564 unsigned long int old_percent=0;
1565 #endif
1566 int ind_stop=0;
1567 unsigned char *buffer=(unsigned char *)MALLOC(disk_car->sector_size);
1568 if(verbose>0)
1569 {
1570 log_trace("fat_find_type(max_offset=%lu, p_fat12=%d, p_fat16=%d, p_fat32=%d, debug=%d, dump_ind=%d)\n",
1571 (long unsigned)(max_offset/disk_car->sector_size), p_fat12, p_fat16, p_fat32, verbose, dump_ind);
1572 }
1573 #ifdef HAVE_NCURSES
1574 wmove(stdscr,8,0);
1575 wprintw(stdscr,"FAT : %s%s%s?\n",p_fat12?"12 ":"", p_fat16?"16 ":"", p_fat32?"32 ":"");
1576 wmove(stdscr,22,0);
1577 wattrset(stdscr, A_REVERSE);
1578 waddstr(stdscr," Stop ");
1579 wattroff(stdscr, A_REVERSE);
1580 #endif
1581 for(offset=disk_car->sector_size;
1582 offset<max_offset && !ind_stop;
1583 offset+=disk_car->sector_size)
1584 {
1585 #ifdef HAVE_NCURSES
1586 const unsigned long int percent=offset*100/max_offset;
1587 if(percent!=old_percent)
1588 {
1589 wmove(stdscr,8,30);
1590 wclrtoeol(stdscr); /* before addstr for BSD compatibility */
1591 wprintw(stdscr,"Searching for FAT table %lu%%",percent);
1592 old_percent=percent;
1593 wrefresh(stdscr);
1594 ind_stop|=check_enter_key_or_s(stdscr);
1595 }
1596 #endif
1597 if((unsigned)disk_car->pread(disk_car, buffer, disk_car->sector_size, partition->part_offset + offset) == disk_car->sector_size)
1598 {
1599 unsigned long int fat_offset=0;
1600 const unsigned int fat_type=fat_find_fat_start(buffer,p_fat12,p_fat16,p_fat32,&fat_offset,disk_car->sector_size);
1601 if(fat_type!=0 && fat_offset<=(offset/disk_car->sector_size))
1602 {
1603 unsigned int j;
1604 if(verbose>1)
1605 {
1606 log_info("fat_find_fat_start FAT%u at %lu:%lu\n", fat_type,
1607 (long unsigned)(offset/disk_car->sector_size-fat_offset),
1608 (long unsigned)(offset/disk_car->sector_size));
1609 }
1610 for(j=0; j<*nbr_offset && !(info_offset[j].offset==offset/disk_car->sector_size-fat_offset &&
1611 info_offset[j].fat_type==fat_type); j++);
1612 if(j<*nbr_offset)
1613 info_offset[j].nbr++;
1614 else
1615 {
1616 unsigned int new_info=0;
1617 if(*nbr_offset<max_nbr_offset)
1618 {
1619 new_info=*nbr_offset;
1620 (*nbr_offset)++;
1621 }
1622 else
1623 { /* Overwrite the last information field with the lower nbr */
1624 for(j=0;j<max_nbr_offset;j++)
1625 {
1626 if(info_offset[j].nbr <= info_offset[new_info].nbr)
1627 new_info=j;
1628 }
1629 }
1630 info_offset[new_info].offset=offset/disk_car->sector_size-fat_offset;
1631 info_offset[new_info].nbr=1;
1632 info_offset[new_info].fat_type=fat_type;
1633 }
1634 }
1635 }
1636 }
1637 #ifdef HAVE_NCURSES
1638 wmove(stdscr,22,0);
1639 wclrtoeol(stdscr);
1640 wrefresh(stdscr);
1641 #endif
1642 free(buffer);
1643 return 0;
1644 }
1645
fat_find_info(disk_t * disk_car,unsigned int * reserved,unsigned int * fat_length,const partition_t * partition,const uint64_t max_offset,const int p_fat12,const int p_fat16,const int p_fat32,const int verbose,const int dump_ind,const unsigned int expert,unsigned int * fats)1646 static upart_type_t fat_find_info(disk_t *disk_car,unsigned int*reserved, unsigned int*fat_length, const partition_t *partition, const uint64_t max_offset, const int p_fat12, const int p_fat16, const int p_fat32, const int verbose, const int dump_ind, const unsigned int expert, unsigned int *fats)
1647 {
1648 unsigned int nbr_offset=0;
1649 unsigned int i;
1650 info_offset_t info_offset[0x400];
1651 upart_type_t upart_type=UP_UNK;
1652 fat_find_type(disk_car, partition, max_offset, p_fat12, p_fat16, p_fat32, verbose, dump_ind, &nbr_offset, &info_offset[0], 0x400);
1653 for(i=0;i<nbr_offset;i++)
1654 {
1655 const uint64_t end=partition->part_offset+(uint64_t)info_offset[i].offset*disk_car->sector_size;
1656 log_info("FAT%u at %lu(%u/%u/%u), nbr=%u\n",info_offset[i].fat_type,info_offset[i].offset,
1657 offset2cylinder(disk_car, end),
1658 offset2head(disk_car,end),
1659 offset2sector(disk_car,end),
1660 info_offset[i].nbr);
1661 #ifdef HAVE_NCURSES
1662 if(dump_ind>0)
1663 {
1664 unsigned char *buffer=(unsigned char *)MALLOC(disk_car->sector_size);
1665 if((unsigned)disk_car->pread(disk_car, &buffer, disk_car->sector_size, end) == disk_car->sector_size)
1666 {
1667 dump_ncurses(buffer,disk_car->sector_size);
1668 }
1669 free(buffer);
1670 }
1671 #endif
1672 }
1673 if(nbr_offset==0)
1674 {
1675 *fat_length=0;
1676 }
1677 else
1678 {
1679 unsigned int offset_for_max_nbr=0;
1680 unsigned int fat_found=0;
1681 unsigned int first_fat=0;
1682 unsigned int second_fat=0;
1683 for(i=0; i<nbr_offset; i++)
1684 {
1685 /* select the good type in the 3 first possibilities */
1686 if(i<3 || info_offset[i].offset<=33)
1687 {
1688 if(info_offset[i].nbr>info_offset[offset_for_max_nbr].nbr)
1689 offset_for_max_nbr=i;
1690 }
1691 }
1692 switch(info_offset[offset_for_max_nbr].fat_type)
1693 {
1694 case 12:
1695 upart_type=UP_FAT12;
1696 break;
1697 case 16:
1698 upart_type=UP_FAT16;
1699 break;
1700 case 32:
1701 upart_type=UP_FAT32;
1702 break;
1703 }
1704 for(i=0; i<nbr_offset; i++)
1705 {
1706 if(info_offset[i].fat_type==info_offset[offset_for_max_nbr].fat_type)
1707 {
1708 if(fat_found==0 && info_offset[i].nbr>=(info_offset[offset_for_max_nbr].nbr+2-1)/2)
1709 {
1710 first_fat=i;
1711 fat_found++;
1712 }
1713 else if(fat_found==1 && info_offset[i].nbr>=(info_offset[first_fat].nbr+2-1)/2)
1714 {
1715 second_fat=i;
1716 fat_found++;
1717 }
1718 }
1719 }
1720 if(fat_found==1)
1721 {
1722 for(i=first_fat+1;i<nbr_offset;i++)
1723 {
1724 if(info_offset[i].fat_type==info_offset[offset_for_max_nbr].fat_type)
1725 {
1726 if(fat_found==1)
1727 {
1728 second_fat=i;
1729 fat_found++;
1730 }
1731 }
1732 }
1733 }
1734 if(fat_found==1)
1735 {
1736 switch(upart_type)
1737 {
1738 case UP_FAT12:
1739 case UP_FAT16:
1740 *reserved=1;
1741 if(info_offset[first_fat].offset>*reserved)
1742 *fat_length=info_offset[first_fat].offset-*reserved;
1743 else
1744 *fat_length=0;
1745 break;
1746 case UP_FAT32:
1747 if(info_offset[first_fat].offset==32 || info_offset[first_fat].offset==33)
1748 *reserved=info_offset[first_fat].offset;
1749 *fat_length=0;
1750 break;
1751 default:
1752 log_critical("fat_find_info: severe error\n");
1753 return UP_UNK;
1754 }
1755 }
1756 else
1757 {
1758 switch(upart_type)
1759 {
1760 case UP_FAT12:
1761 case UP_FAT16:
1762 *reserved=info_offset[first_fat].offset; /* Should be 1 */
1763 *fat_length=info_offset[second_fat].offset-*reserved;
1764 break;
1765 case UP_FAT32:
1766 *reserved=info_offset[first_fat].offset;
1767 *fat_length=info_offset[second_fat].offset-*reserved;
1768 if(*reserved==32 || *reserved==33 || comp_FAT(disk_car,partition,*fat_length,*reserved)==0)
1769 {
1770 } else {
1771 *reserved=0;
1772 *fat_length=0;
1773 }
1774 break;
1775 default:
1776 log_critical("fat_find_info: severe error\n");
1777 return UP_UNK;
1778 }
1779 }
1780 if(verbose>0)
1781 {
1782 log_info("first_fat %lu, second_fat %lu\n",info_offset[first_fat].offset, info_offset[second_fat].offset);
1783 }
1784 }
1785 if(expert>0)
1786 {
1787 #ifdef HAVE_NCURSES
1788 return select_fat_info(info_offset,nbr_offset,reserved,fat_length,max_offset/disk_car->sector_size,fats);
1789 #endif
1790 }
1791 return upart_type;
1792 }
1793
1794 #ifdef HAVE_NCURSES
select_fat_info(const info_offset_t * info_offset,const unsigned int nbr_offset,unsigned int * reserved,unsigned int * fat_length,const unsigned long int max_sector_offset,unsigned int * fats)1795 static upart_type_t select_fat_info(const info_offset_t *info_offset, const unsigned int nbr_offset,unsigned int*reserved, unsigned int*fat_length, const unsigned long int max_sector_offset, unsigned int *fats)
1796 {
1797 unsigned int i;
1798 unsigned long int fat2_location=*reserved+*fat_length;
1799 const struct MenuItem menuSelectFAT[]=
1800 {
1801 { 'P', "Previous",""},
1802 { 'N', "Next","" },
1803 { 'Q', "Proceed","Set FAT table location"},
1804 { 0, NULL, NULL }
1805 };
1806 screen_buffer_reset();
1807 screen_buffer_add("Potential FAT location\n");
1808 screen_buffer_add("FAT - sector - score\n");
1809 for(i=0;i<nbr_offset;i++)
1810 {
1811 if(nbr_offset<30 || info_offset[i].nbr>1)
1812 screen_buffer_add(" %02u %8lu %u\n", info_offset[i].fat_type, info_offset[i].offset, info_offset[i].nbr);
1813 }
1814 aff_copy(stdscr);
1815 wmove(stdscr,4,0);
1816 screen_buffer_to_log();
1817 log_flush();
1818 screen_buffer_display(stdscr,"",menuSelectFAT);
1819 wmove(stdscr,INTER_FAT_ASK_Y, INTER_FAT_ASK_X);
1820 *reserved=ask_number(*reserved,0,max_sector_offset,"FAT1 location (Number of reserved sector) ");
1821 if(*reserved>0)
1822 {
1823 wmove(stdscr,INTER_FAT_ASK_Y, INTER_FAT_ASK_X);
1824 fat2_location=ask_number(fat2_location,0,max_sector_offset,"FAT2 location ");
1825 if(fat2_location == *reserved)
1826 {
1827 *fats=1;
1828 *fat_length=0;
1829 }
1830 else if(fat2_location > *reserved)
1831 {
1832 *fat_length=fat2_location-*reserved;
1833 wmove(stdscr,INTER_FAT_ASK_Y, INTER_FAT_ASK_X);
1834 *fats=ask_number(*fats,1,2,"Number of FATS (Usually 2) ");
1835 }
1836 else
1837 {
1838 *fat_length=0;
1839 }
1840 }
1841 else
1842 {
1843 *fat_length=0;
1844 }
1845 for(i=0;i<nbr_offset;i++)
1846 {
1847 if(info_offset[i].offset==fat2_location)
1848 {
1849 switch(info_offset[i].fat_type)
1850 {
1851 case 12: return UP_FAT12;
1852 case 16: return UP_FAT16;
1853 case 32: return UP_FAT32;
1854 }
1855 }
1856 }
1857 for(i=0;i<nbr_offset;i++)
1858 {
1859 if(info_offset[i].offset==*reserved)
1860 {
1861 switch(info_offset[i].fat_type)
1862 {
1863 case 12: return UP_FAT12;
1864 case 16: return UP_FAT16;
1865 case 32: return UP_FAT32;
1866 }
1867 }
1868 }
1869 *reserved=0;
1870 *fat_length=0;
1871 return UP_UNK;
1872 }
1873 #endif
1874
rebuild_FAT_BS(disk_t * disk_car,partition_t * partition,const int verbose,const int dump_ind,const unsigned int expert,char ** current_cmd)1875 int rebuild_FAT_BS(disk_t *disk_car, partition_t *partition, const int verbose, const int dump_ind, const unsigned int expert, char**current_cmd)
1876 {
1877 unsigned long int max_offset;
1878 unsigned int fat_length=0;
1879 unsigned int sectors_per_cluster=0;
1880 unsigned int reserved=0;
1881 unsigned int dir_entries=0;
1882 unsigned int fats=2;
1883 int p_fat12,p_fat16,p_fat32;
1884 upart_type_t upart_type;
1885 /*
1886 * Using partition size, check if partition can be FAT12, FAT16 or FAT32
1887 * */
1888 if(partition->part_size>(uint64_t)(2*1024+1)*1024*1024)
1889 {
1890 p_fat32=1;
1891 p_fat16=0;
1892 p_fat12=0;
1893 }
1894 else
1895 /* 1<<12 clusters * 8 secteurs/clusters= 32768 secteurs
1896 fat_length=((1<<12+1)*1.5/DEFAULT_SECTOR_SIZE)+1=13; */
1897 if(partition->part_size>=(uint64_t)(1+2*13+32768+63)*512)
1898 {
1899 p_fat32=1;
1900 p_fat16=1;
1901 p_fat12=0;
1902 }
1903 else
1904 {
1905 p_fat32=0;
1906 p_fat16=1;
1907 p_fat12=1;
1908 }
1909 #ifdef TESTING
1910 p_fat32=1; p_fat16=1; p_fat12=1;
1911 #endif
1912 if(verbose)
1913 {
1914 log_info("\n");
1915 log_partition(disk_car,partition);
1916 log_info("rebuild_FAT_BS p_fat12 %d, p_fat16 %d, p_fat32 %d\n", p_fat12,p_fat16,p_fat32);
1917 }
1918 {
1919 /* Set fat_length_max */
1920 unsigned long int fat_length_max;
1921 unsigned int sectors_per_cluster_min=disk_car->sector_size;
1922 if(p_fat32)
1923 { /* Cluster 512 bytes */
1924 fat_length_max=partition->part_size/sectors_per_cluster_min*4;
1925 }
1926 else if(p_fat16)
1927 {
1928 while(partition->part_size/sectors_per_cluster_min > (1<<16))
1929 sectors_per_cluster_min*=2;
1930 fat_length_max=partition->part_size/sectors_per_cluster_min*2;
1931 }
1932 else
1933 {
1934 /* dead code */
1935 while(partition->part_size/sectors_per_cluster_min > (1<<12))
1936 sectors_per_cluster_min*=2;
1937 fat_length_max=partition->part_size/sectors_per_cluster_min*3/2;
1938 }
1939 fat_length_max=fat_length_max/disk_car->sector_size*disk_car->sector_size;
1940 if(verbose>1)
1941 {
1942 log_verbose("sectors_per_cluster_min %u sectors\n", sectors_per_cluster_min/disk_car->sector_size);
1943 log_verbose("fat_length_max %lu sectors\n", fat_length_max/disk_car->sector_size);
1944 }
1945 max_offset=fat_length_max+64*disk_car->sector_size;
1946 }
1947 /*
1948 if(verbose>1)
1949 log_debug("search_fat16(partition,max_offset=%d,p_fat12=%d,p_fat16=%d,p_fat32=%d,debug=%d,dump_ind=%d)\n",max_offset,p_fat12,p_fat16,p_fat32,verbose,dump_ind);
1950 */
1951 #ifdef HAVE_NCURSES
1952 aff_copy(stdscr);
1953 wmove(stdscr,4,0);
1954 wprintw(stdscr,"%s",disk_car->description(disk_car));
1955 mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
1956 wmove(stdscr,6,0);
1957 aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
1958 wrefresh(stdscr);
1959 #endif
1960 upart_type=fat_find_info(disk_car, &reserved, &fat_length, partition, max_offset, p_fat12, p_fat16, p_fat32, verbose, dump_ind, expert, &fats);
1961 #ifdef HAVE_NCURSES
1962 aff_copy(stdscr);
1963 wmove(stdscr,4,0);
1964 wprintw(stdscr,"%s",disk_car->description(disk_car));
1965 mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
1966 wmove(stdscr,6,0);
1967 aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
1968 wmove(stdscr,8,0);
1969 wclrtoeol(stdscr);
1970 switch(upart_type)
1971 {
1972 case UP_FAT12:
1973 waddstr(stdscr,"FAT : 12");
1974 break;
1975 case UP_FAT16:
1976 waddstr(stdscr,"FAT : 16");
1977 break;
1978 case UP_FAT32:
1979 waddstr(stdscr,"FAT : 32");
1980 break;
1981 default:
1982 waddstr(stdscr,"No FAT found");
1983 break;
1984 }
1985 #endif
1986 if(verbose>0)
1987 {
1988 switch(upart_type)
1989 {
1990 case UP_FAT12:
1991 log_info("FAT : 12");
1992 break;
1993 case UP_FAT16:
1994 log_info("FAT : 16");
1995 break;
1996 case UP_FAT32:
1997 log_info("FAT : 32");
1998 break;
1999 default:
2000 log_info("No FAT found");
2001 break;
2002 }
2003 log_info(", reserved=%u, fat_length=%u\n",reserved,fat_length);
2004 }
2005 if((upart_type!=UP_FAT12 && upart_type!=UP_FAT16 && upart_type!=UP_FAT32)||
2006 (fat_length==0)||(reserved==0))
2007 {
2008 uint64_t start_data=0;
2009 if(find_sectors_per_cluster(disk_car, partition, verbose, dump_ind, §ors_per_cluster, &start_data, upart_type)==0)
2010 {
2011 display_message("Can't find cluster size\n");
2012 return 0;
2013 }
2014 if((sectors_per_cluster<=0) || (partition->part_size/disk_car->sector_size<=start_data))
2015 {
2016 display_message("Can't find cluster size\n");
2017 return 0;
2018 }
2019 upart_type=no_of_cluster2part_type((partition->part_size/disk_car->sector_size-start_data)/sectors_per_cluster);
2020 switch(upart_type)
2021 {
2022 case UP_FAT12:
2023 log_info("FAT : 12\n");
2024 break;
2025 case UP_FAT16:
2026 log_info("FAT : 16\n");
2027 break;
2028 case UP_FAT32:
2029 log_info("FAT : 32\n");
2030 break;
2031 default: /* No compiler warning */
2032 break;
2033 }
2034 switch(upart_type)
2035 {
2036 case UP_FAT12:
2037 case UP_FAT16:
2038 reserved=1; /* must be 1 */
2039 dir_entries=find_dir_entries(disk_car,partition,start_data-1,verbose);
2040 switch(dir_entries)
2041 {
2042 case 0:
2043 log_warning("dir_entries not found, should be 512\n");
2044 dir_entries=512;
2045 break;
2046 case 512:
2047 if(verbose)
2048 log_info("dir_entries: %u\n", dir_entries);
2049 break;
2050 default:
2051 log_warning("dir_entries: %u (unusual value)\n", dir_entries);
2052 break;
2053 }
2054 fat_length=(start_data-reserved-((dir_entries-1)/16+1))/fats;
2055 break;
2056 case UP_FAT32:
2057 if(reserved==0)
2058 {
2059 reserved=32;
2060 if((start_data&1)!=0)
2061 reserved+=1;
2062 }
2063 fat_length=(start_data-reserved)/fats;
2064 break;
2065 default: /* No compiler warning */
2066 break;
2067 }
2068 if(verbose>0)
2069 log_info("fat_length %u\n",fat_length);
2070 }
2071 #ifdef HAVE_NCURSES
2072 if(fat_length==0)
2073 waddstr(stdscr," Can't find FAT length\n");
2074 wrefresh(stdscr);
2075 #endif
2076 if(upart_type && (fat_length>1))
2077 {
2078 unsigned long int data_size;
2079 /* Initialized by fat32_free_info */
2080 unsigned int free_cluster_count=0;
2081 unsigned int first_free_cluster=0;
2082 /* Initialized by fat32_find_root_cluster */
2083 unsigned long int root_cluster=0;
2084 uint64_t start_data=reserved+fats*fat_length;
2085 /* FAT1x: Find size of root directory */
2086 if((upart_type==UP_FAT12) || (upart_type==UP_FAT16))
2087 {
2088 int old_dir_entries=dir_entries;
2089 dir_entries=analyse_dir_entries(disk_car,partition,start_data,verbose);
2090 log_info("dir_entries %u\n",dir_entries);
2091 dir_entries=analyse_dir_entries2(disk_car,partition,reserved,fat_length,verbose,dir_entries,upart_type,fats);
2092 log_info("dir_entries %u\n",dir_entries);
2093 if(dir_entries==0)
2094 {
2095 if(old_dir_entries>0)
2096 fat_length=0;
2097 /*
2098 else
2099 {
2100 dir_entries=512;
2101 log_debug("analyse_dir_entries: use default dir_entries %u\n",dir_entries);
2102 }
2103 */
2104 }
2105 start_data+=(dir_entries+(disk_car->sector_size/32)-1)/(disk_car->sector_size/32);
2106 }
2107 if(partition->part_size/disk_car->sector_size<=start_data)
2108 {
2109 log_error("Error part_size=%lu <= start_data=%lu\n",
2110 (unsigned long)(partition->part_size/disk_car->sector_size), (unsigned long)start_data);
2111 return 0;
2112 }
2113 data_size=partition->part_size/disk_car->sector_size-start_data;
2114 /* Get Cluster Size */
2115 {
2116 int old_sectors_per_cluster=sectors_per_cluster;
2117 sectors_per_cluster=calcul_sectors_per_cluster(upart_type,data_size,fat_length,disk_car->sector_size);
2118 if(verbose>0)
2119 log_info("sectors_per_cluster %u\n",sectors_per_cluster);
2120 if((sectors_per_cluster<=0)||(sectors_per_cluster>128))
2121 {
2122 if(old_sectors_per_cluster>0)
2123 {
2124 sectors_per_cluster=old_sectors_per_cluster;
2125 log_info("Assumes previous cluster size was good\n");
2126 }
2127 else
2128 {
2129 sectors_per_cluster=0;
2130 }
2131 }
2132 if(expert>0)
2133 {
2134 #ifdef HAVE_NCURSES
2135 wmove(stdscr, INTER_FAT_ASK_Y, INTER_FAT_ASK_X);
2136 sectors_per_cluster=ask_number(sectors_per_cluster,0,128,"cluster size ");
2137 #endif
2138 switch(sectors_per_cluster)
2139 {
2140 case 1:
2141 case 2:
2142 case 4:
2143 case 8:
2144 case 16:
2145 case 32:
2146 case 64:
2147 case 128:
2148 break;
2149 default:
2150 sectors_per_cluster=0;
2151 break;
2152 }
2153 }
2154 if(sectors_per_cluster==0)
2155 {
2156 display_message("Can't get cluster size\n");
2157 return 0;
2158 }
2159 }
2160 if(upart_type==UP_FAT32)
2161 {
2162 /* Use first fat */
2163 fat32_free_info(disk_car,partition,reserved,data_size/sectors_per_cluster,&first_free_cluster,&free_cluster_count);
2164 /* FAT32 : Find root cluster */
2165 root_cluster=fat32_find_root_cluster(disk_car, partition, sectors_per_cluster, data_size/sectors_per_cluster, reserved, fat_length, verbose, expert, first_free_cluster, fats);
2166 if(expert>0)
2167 {
2168 #ifdef HAVE_NCURSES
2169 int i;
2170 for(i=5; i<INTER_FAT_ASK_Y; i++)
2171 {
2172 wmove(stdscr, i, 0);
2173 wclrtoeol(stdscr);
2174 }
2175 wmove(stdscr, INTER_FAT_ASK_Y, INTER_FAT_ASK_X);
2176 root_cluster=ask_number(root_cluster,2,data_size/sectors_per_cluster+1,"root cluster ");
2177 #endif
2178 if(verbose>1)
2179 {
2180 log_verbose("root_cluster=%lu (new)\n",root_cluster);
2181 }
2182 }
2183 }
2184 #ifdef HAVE_NCURSES
2185 wmove(stdscr,9,0);
2186 wclrtoeol(stdscr);
2187 wrefresh(stdscr);
2188 #endif
2189 create_fat_boot_sector(disk_car, partition, reserved, verbose, dir_entries, root_cluster, sectors_per_cluster, fat_length, upart_type, fats, current_cmd);
2190 if(verbose)
2191 {
2192 log_info("\n");
2193 log_partition(disk_car,partition);
2194 }
2195 }
2196 return 0;
2197 }
2198
FAT_init_rootdir(disk_t * disk_car,partition_t * partition,const int verbose,char ** current_cmd)2199 int FAT_init_rootdir(disk_t *disk_car, partition_t *partition, const int verbose, char **current_cmd)
2200 {
2201 unsigned long int fat_length,sector;
2202 uint64_t start_rootdir,start_data;
2203 unsigned int error=0;
2204 struct fat_boot_sector *fat_header;
2205 unsigned char *buffer;
2206 if(partition->upart_type!=UP_FAT12 && partition->upart_type!=UP_FAT16)
2207 return 1;
2208 if(check_FAT(disk_car,partition,verbose)!=0)
2209 {
2210 display_message("Boot sector not valid, can't check FAT.\n");
2211 return 1;
2212 }
2213 buffer=(unsigned char *)MALLOC(disk_car->sector_size);
2214 fat_header=(struct fat_boot_sector *)buffer;
2215 if((unsigned)disk_car->pread(disk_car, buffer, disk_car->sector_size, partition->part_offset) != disk_car->sector_size)
2216 {
2217 display_message("FAT_init_rootdir: Can't read boot sector\n");
2218 free(buffer);
2219 return 1;
2220 }
2221 fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length);
2222 start_rootdir=le16(fat_header->reserved)+ fat_header->fats*fat_length;
2223 start_data=start_rootdir+(get_dir_entries(fat_header)*32+disk_car->sector_size-1)/disk_car->sector_size;
2224 for(sector=start_rootdir;error==0 && sector<start_data;sector++)
2225 {
2226 if((unsigned)disk_car->pread(disk_car, buffer, disk_car->sector_size,
2227 partition->part_offset + (uint64_t)sector * disk_car->sector_size) != disk_car->sector_size)
2228 {
2229 log_error("FAT_init_rootdir: read error at sector %lu\n", sector);
2230 }
2231 else
2232 {
2233 unsigned int i;
2234 for(i=0;error==0 && (i<disk_car->sector_size/0x20);i++)
2235 {
2236 if(check_FAT_dir_entry(&buffer[i*0x20],i)==2)
2237 {
2238 error=1;
2239 }
2240 }
2241 }
2242 }
2243 if(error==0)
2244 {
2245 if(*current_cmd!=NULL)
2246 log_info("TestDisk doesn't seem needed to reset the root directory.\n");
2247 else
2248 display_message("TestDisk doesn't seem needed to reset the root directory.\n");
2249 free(buffer);
2250 return 0;
2251 }
2252 #ifdef HAVE_NCURSES
2253 if(ask_confirmation("Initialize FAT root directory, confirm ? (Y/N)")!=0)
2254 {
2255 int err=0;
2256 log_info("Initialize FAT root directory\n");
2257 memset(buffer,0,disk_car->sector_size);
2258 for(sector=start_rootdir;sector<start_data;sector++)
2259 {
2260 if((unsigned)disk_car->pwrite(disk_car, buffer, disk_car->sector_size,
2261 partition->part_offset + (uint64_t)sector * disk_car->sector_size) != disk_car->sector_size)
2262 {
2263 err=1;
2264 }
2265 }
2266 if(err>0)
2267 {
2268 display_message("FAT_init_rootdir: write failed.\n");
2269 free(buffer);
2270 return 1;
2271 }
2272 }
2273 #endif
2274 free(buffer);
2275 return 0;
2276 }
2277
2278 typedef enum { FAT_UNREADABLE=0, FAT_CORRUPTED=1, FAT_OK=2 } fat_status_t;
2279 typedef enum { FAT_REPAIR_ASK=0, FAT_REPAIR_YES=1, FAT_REPAIR_NO=2 } fat_repair_t;
2280
repair_FAT_table(disk_t * disk_car,partition_t * partition,const int verbose,char ** current_cmd)2281 int repair_FAT_table(disk_t *disk_car, partition_t *partition, const int verbose, char **current_cmd)
2282 {
2283 if(check_FAT(disk_car,partition,verbose)!=0)
2284 {
2285 display_message("Boot sector not valid, can't check FAT.\n");
2286 return 1;
2287 }
2288 {
2289 unsigned long int start_fat1,no_of_cluster,fat_length;
2290 unsigned int fats;
2291 unsigned int fat32_root_cluster=0;
2292 int fat_damaged=0;
2293 #ifdef HAVE_NCURSES
2294 WINDOW *window=newwin(LINES, COLS, 0, 0); /* full screen */
2295 aff_copy(window);
2296 #endif
2297 {
2298 struct fat_boot_sector *fat_header;
2299 uint64_t part_size,start_data;
2300 unsigned char *buffer;
2301 buffer=(unsigned char *)MALLOC(disk_car->sector_size);
2302 fat_header=(struct fat_boot_sector *)buffer;
2303 if((unsigned)disk_car->pread(disk_car, buffer, disk_car->sector_size, partition->part_offset) != disk_car->sector_size)
2304 {
2305 display_message("repair_FAT_table: Can't read boot sector\n");
2306 free(buffer);
2307 #ifdef HAVE_NCURSES
2308 delwin(window);
2309 (void) clearok(stdscr, TRUE);
2310 #ifdef HAVE_TOUCHWIN
2311 touchwin(stdscr);
2312 #endif
2313 #endif
2314 return 1;
2315 }
2316 fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length);
2317 part_size=(fat_sectors(fat_header)>0?fat_sectors(fat_header):le32(fat_header->total_sect));
2318 start_fat1=le16(fat_header->reserved);
2319 fats=fat_header->fats;
2320 start_data=start_fat1+fats*fat_length+(get_dir_entries(fat_header)*32+disk_car->sector_size-1)/disk_car->sector_size;
2321 no_of_cluster=(part_size-start_data)/fat_header->sectors_per_cluster;
2322 fat32_root_cluster=le32(fat_header->root_cluster);
2323 log_info("repair_FAT_table cluster=2..%lu\n",no_of_cluster+1);
2324 free(buffer);
2325 }
2326 if(fats==0 || fats>2)
2327 {
2328 #ifdef HAVE_NCURSES
2329 delwin(window);
2330 (void) clearok(stdscr, TRUE);
2331 #ifdef HAVE_TOUCHWIN
2332 touchwin(stdscr);
2333 #endif
2334 #endif
2335 return 1;
2336 }
2337 {
2338 const unsigned int buffer_size=(partition->upart_type==UP_FAT12?2*disk_car->sector_size:disk_car->sector_size);
2339 fat_status_t fat_status[2];
2340 fat_repair_t allow_write[2];
2341 unsigned int fat_history[2][3];
2342 unsigned int old_offset_s=1234;
2343 unsigned int fat_mismatch=0;
2344 unsigned int fat_nbr;
2345 unsigned long int cluster;
2346 #ifdef HAVE_NCURSES
2347 unsigned long int old_percent=0;
2348 #endif
2349 unsigned char *buffer_fat[2];
2350 unsigned int rw_size=buffer_size;
2351 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2352 buffer_fat[fat_nbr]=(unsigned char *)MALLOC(fats*buffer_size);
2353 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2354 {
2355 fat_history[fat_nbr][FAT_UNREADABLE]=0;
2356 fat_history[fat_nbr][FAT_CORRUPTED]=0;
2357 fat_history[fat_nbr][FAT_OK]=0;
2358 allow_write[fat_nbr]=FAT_REPAIR_ASK;
2359 fat_status[fat_nbr]=FAT_OK;
2360 }
2361 for(cluster=2;cluster<=no_of_cluster+1;cluster++)
2362 {
2363 unsigned long int next_cluster;
2364 unsigned int offset_s,offset_o;
2365 if(partition->upart_type==UP_FAT32)
2366 {
2367 offset_s=cluster/(disk_car->sector_size/4);
2368 offset_o=cluster%(disk_car->sector_size/4);
2369 }
2370 else if(partition->upart_type==UP_FAT16)
2371 {
2372 offset_s=cluster/(disk_car->sector_size/2);
2373 offset_o=cluster%(disk_car->sector_size/2);
2374 }
2375 else
2376 {
2377 offset_s=(cluster+cluster/2)/disk_car->sector_size;
2378 offset_o=(cluster+cluster/2)%disk_car->sector_size;
2379 if(offset_s==fat_length-1)
2380 rw_size=disk_car->sector_size;
2381 }
2382 if(offset_s!=old_offset_s)
2383 {
2384 #ifdef HAVE_NCURSES
2385 const unsigned long int percent=cluster*100/(no_of_cluster+1);
2386 if(percent!=old_percent)
2387 {
2388 wmove(window,4,0);
2389 wprintw(window,"Checking FAT %lu%%",percent);
2390 wrefresh(window);
2391 old_percent=percent;
2392 }
2393 #endif
2394 /* Write if necessary */
2395 {
2396 unsigned int nbr_fat_unreadable=0;
2397 unsigned int nbr_fat_corrupted=0;
2398 unsigned int nbr_fat_ok=0;
2399 unsigned int good_fat_nbr=0;
2400 /* Some stats about FAT table */
2401 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2402 {
2403 switch(fat_status[fat_nbr])
2404 {
2405 case FAT_UNREADABLE:
2406 nbr_fat_unreadable++;
2407 fat_history[fat_nbr][FAT_UNREADABLE]++;
2408 break;
2409 case FAT_CORRUPTED:
2410 nbr_fat_corrupted++;
2411 fat_history[fat_nbr][FAT_CORRUPTED]++;
2412 break;
2413 case FAT_OK:
2414 nbr_fat_ok++;
2415 good_fat_nbr=fat_nbr;
2416 fat_history[fat_nbr][FAT_OK]++;
2417 break;
2418 }
2419 }
2420 if(fat_mismatch!=0)
2421 {
2422 if(nbr_fat_ok>1)
2423 {
2424 good_fat_nbr=0;
2425 for(fat_nbr=1;fat_nbr<fats;fat_nbr++)
2426 {
2427 if(fat_history[fat_nbr][FAT_OK]>fat_history[good_fat_nbr][FAT_OK])
2428 {
2429 good_fat_nbr=fat_nbr;
2430 }
2431 else if(fat_history[fat_nbr][FAT_OK] == fat_history[good_fat_nbr][FAT_OK])
2432 {
2433 unsigned long int fat_offset=0;
2434 if(fat_find_fat_start(buffer_fat[fat_nbr], (partition->upart_type==UP_FAT12),
2435 (partition->upart_type==UP_FAT16), (partition->upart_type==UP_FAT32),
2436 &fat_offset,disk_car->sector_size)!=0)
2437 good_fat_nbr=fat_nbr;
2438 }
2439 }
2440 }
2441 }
2442 if(verbose>1 || nbr_fat_ok!=fats || fat_mismatch>0)
2443 {
2444 log_verbose("nbr_fat_unreadable %u, nbr_fat_corrupted %u, nbr_fat_ok %u, good_fat_nbr %u, fat_mismatch %u\n",
2445 nbr_fat_unreadable, nbr_fat_corrupted, nbr_fat_ok, good_fat_nbr, fat_mismatch);
2446 }
2447 /* Write FAT if necessary */
2448 if(fat_mismatch!=0)
2449 {
2450 fat_damaged=1;
2451 if(nbr_fat_ok>=1)
2452 {
2453 /* Use the good/best FAT to repair the bad one */
2454 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2455 {
2456 if(fat_nbr!=good_fat_nbr)
2457 {
2458 if(verbose>2)
2459 {
2460 dump_log(buffer_fat[fat_nbr], rw_size);
2461 }
2462 if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
2463 {
2464 #ifdef HAVE_NCURSES
2465 if(ask_confirmation("Use FAT%u to repair FAT%u table, confirm ? (Y/N)",good_fat_nbr+1,fat_nbr+1)!=0)
2466 {
2467 allow_write[fat_nbr]=FAT_REPAIR_YES;
2468 }
2469 else
2470 #endif
2471 {
2472 allow_write[fat_nbr]=FAT_REPAIR_NO;
2473 log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu) using FAT%u\n",fat_nbr+1,
2474 start_fat1+fat_length*fat_nbr+old_offset_s, good_fat_nbr+1);
2475 }
2476 }
2477 if(allow_write[fat_nbr]==FAT_REPAIR_YES)
2478 {
2479 log_info("repair_FAT_table: correcting FAT%u (sector %lu) using FAT%u\n",fat_nbr+1,
2480 start_fat1+fat_length*fat_nbr+old_offset_s, good_fat_nbr+1);
2481 if((unsigned)disk_car->pwrite(disk_car, buffer_fat[good_fat_nbr], rw_size,
2482 partition->part_offset + (uint64_t)(start_fat1 + fat_length * fat_nbr + old_offset_s) * disk_car->sector_size) != rw_size)
2483 {
2484 display_message("repair_FAT_table: write failed.\n");
2485 }
2486 }
2487 }
2488 }
2489 }
2490 else
2491 {
2492 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2493 {
2494 if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
2495 {
2496 #ifdef HAVE_NCURSES
2497 if(ask_confirmation("Remove invalid cluster from FAT%u table, confirm ? (Y/N)",fat_nbr+1)!=0)
2498 {
2499 allow_write[fat_nbr]=FAT_REPAIR_YES;
2500 }
2501 else
2502 #endif
2503 {
2504 allow_write[fat_nbr]=FAT_REPAIR_NO;
2505 log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu)\n",fat_nbr+1,
2506 start_fat1+fat_length*fat_nbr+old_offset_s);
2507 }
2508 }
2509 if(allow_write[fat_nbr]==FAT_REPAIR_YES)
2510 {
2511 log_info("repair_FAT_table: correcting FAT%u (sector %lu)\n",fat_nbr+1,
2512 start_fat1+fat_length*fat_nbr+old_offset_s);
2513 if((unsigned)disk_car->pwrite(disk_car, buffer_fat[fat_nbr], rw_size,
2514 partition->part_offset + (uint64_t)(start_fat1 + fat_length * fat_nbr + old_offset_s) * disk_car->sector_size) != rw_size)
2515 {
2516 display_message("repair_FAT_table: write failed.\n");
2517 }
2518 }
2519 }
2520 }
2521 }
2522 else
2523 {
2524 /* only one fat or fat match */
2525 if(nbr_fat_ok==0)
2526 { /* fat_corrupted */
2527 fat_damaged=1;
2528 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2529 {
2530 if(verbose>2)
2531 {
2532 dump_log(buffer_fat[fat_nbr], rw_size);
2533 }
2534 if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
2535 {
2536 #ifdef HAVE_NCURSES
2537 if(ask_confirmation("Remove invalid cluster from FAT%u table, confirm ? (Y/N)",fat_nbr+1)!=0)
2538 {
2539 allow_write[fat_nbr]=FAT_REPAIR_YES;
2540 log_info("repair_FAT_table: correcting FAT%u (sector %lu)\n",fat_nbr+1,
2541 start_fat1+fat_length*fat_nbr+old_offset_s);
2542 }
2543 else
2544 #endif
2545 {
2546 allow_write[fat_nbr]=FAT_REPAIR_NO;
2547 log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu)\n",fat_nbr+1,
2548 start_fat1+fat_length*fat_nbr+old_offset_s);
2549 }
2550 }
2551 if(allow_write[fat_nbr]==FAT_REPAIR_YES)
2552 {
2553 if((unsigned)disk_car->pwrite(disk_car, buffer_fat[fat_nbr], rw_size,
2554 partition->part_offset + (uint64_t)(start_fat1 + fat_length * fat_nbr + old_offset_s) * disk_car->sector_size) != rw_size )
2555 {
2556 display_message("repair_FAT_table: write failed.\n");
2557 }
2558 }
2559 }
2560 }
2561 }
2562 }
2563 /* Read FAT */
2564 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2565 {
2566 fat_status[fat_nbr]=FAT_OK;
2567 if(verbose>1)
2568 {
2569 log_info("repair_FAT_table: read sector %lu (FAT%u)\n",(start_fat1+fat_length*fat_nbr+offset_s),fat_nbr+1);
2570 }
2571 if((unsigned)disk_car->pread(disk_car, buffer_fat[fat_nbr], rw_size,
2572 partition->part_offset + (uint64_t)(start_fat1 + fat_length * fat_nbr + offset_s) * disk_car->sector_size) != rw_size)
2573 {
2574 log_error("repair_FAT_table: read error sector %lu\n",(start_fat1+fat_length*fat_nbr+offset_s));
2575 memset(buffer_fat[fat_nbr],0, rw_size);
2576 fat_status[fat_nbr]=FAT_UNREADABLE;
2577 }
2578 if(verbose>1)
2579 {
2580 dump_log(buffer_fat[fat_nbr], rw_size);
2581 }
2582 }
2583 /* Compare FAT */
2584 fat_mismatch=0;
2585 for(fat_nbr=1;fat_nbr<fats && fat_mismatch==0;fat_nbr++)
2586 {
2587 if(memcmp(buffer_fat[0], buffer_fat[fat_nbr], rw_size)!=0)
2588 fat_mismatch=1;
2589 }
2590 }
2591 /* Repair FAT if necessary */
2592 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2593 {
2594 if(partition->upart_type==UP_FAT32)
2595 {
2596 uint32_t *p32=(uint32_t*)buffer_fat[fat_nbr];
2597 next_cluster=(le32(p32[offset_o]) & 0xFFFFFFF);
2598 if((next_cluster<0x0FFFFFF7 && (next_cluster==1 || next_cluster>no_of_cluster+1)) ||
2599 (cluster==fat32_root_cluster && next_cluster==0))
2600 {
2601 #ifdef DEBUG
2602 log_trace("FAT%u cluster %lu(%lx)->%lu(%lx)\n",fat_nbr+1,cluster,cluster,next_cluster,next_cluster);
2603 #endif
2604 p32[offset_o]=le32(FAT32_EOC);
2605 fat_status[fat_nbr]=FAT_CORRUPTED;
2606 }
2607 }
2608 else if(partition->upart_type==UP_FAT16)
2609 {
2610 uint16_t *p16=(uint16_t*)buffer_fat[fat_nbr];
2611 next_cluster=le16(p16[offset_o]);
2612 if(next_cluster<0xFFF7 && (next_cluster==1 || next_cluster>no_of_cluster+1))
2613 {
2614 p16[offset_o]=le16(FAT16_EOC);
2615 fat_status[fat_nbr]=FAT_CORRUPTED;
2616 }
2617 }
2618 else
2619 {
2620 if((cluster&1)!=0)
2621 next_cluster=le16((*((uint16_t*)&buffer_fat[fat_nbr][offset_o])))>>4;
2622 else
2623 next_cluster=le16(*((uint16_t*)&buffer_fat[fat_nbr][offset_o]))&0x0FFF;
2624 if(next_cluster<0x0FF7 && (next_cluster==1 || next_cluster>no_of_cluster+1))
2625 {
2626 if((cluster&1)!=0)
2627 *((uint16_t*)&buffer_fat[fat_nbr][offset_o])=le16((FAT12_EOC<<4)|(le16((*((uint16_t*)&buffer_fat[fat_nbr][offset_o])))&0x0F));
2628 else
2629 *((uint16_t*)&buffer_fat[fat_nbr][offset_o])=le16(FAT12_EOC |(le16((*((uint16_t*)&buffer_fat[fat_nbr][offset_o])))&0xF000));
2630 fat_status[fat_nbr]=FAT_CORRUPTED;
2631 }
2632 }
2633 }
2634 old_offset_s=offset_s;
2635 }
2636 /* Write if necessary the last cluster */
2637 {
2638 unsigned int nbr_fat_unreadable=0;
2639 unsigned int nbr_fat_corrupted=0;
2640 unsigned int nbr_fat_ok=0;
2641 unsigned int good_fat_nbr=0;
2642 /* Some stats about FAT table */
2643 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2644 {
2645 switch(fat_status[fat_nbr])
2646 {
2647 case FAT_UNREADABLE:
2648 nbr_fat_unreadable++;
2649 fat_history[fat_nbr][FAT_UNREADABLE]++;
2650 break;
2651 case FAT_CORRUPTED:
2652 nbr_fat_corrupted++;
2653 fat_history[fat_nbr][FAT_CORRUPTED]++;
2654 break;
2655 case FAT_OK:
2656 nbr_fat_ok++;
2657 good_fat_nbr=fat_nbr;
2658 fat_history[fat_nbr][FAT_OK]++;
2659 break;
2660 }
2661 }
2662 if(fat_mismatch!=0)
2663 {
2664 if(nbr_fat_ok>1)
2665 {
2666 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2667 {
2668 if(fat_nbr!=good_fat_nbr)
2669 {
2670 if(fat_history[fat_nbr][FAT_OK]>fat_history[good_fat_nbr][FAT_OK])
2671 {
2672 good_fat_nbr=fat_nbr;
2673 }
2674 else if(fat_history[fat_nbr][FAT_OK] == fat_history[good_fat_nbr][FAT_OK])
2675 {
2676 unsigned long int fat_offset=0;
2677 if(fat_find_fat_start(buffer_fat[fat_nbr], (partition->upart_type==UP_FAT12),
2678 (partition->upart_type==UP_FAT16), (partition->upart_type==UP_FAT32),
2679 &fat_offset,disk_car->sector_size)!=0)
2680 good_fat_nbr=fat_nbr;
2681 }
2682 }
2683 }
2684 }
2685 }
2686 if(verbose>1 || nbr_fat_ok!=fats || fat_mismatch>0)
2687 {
2688 log_info("nbr_fat_unreadable %u, nbr_fat_corrupted %u, nbr_fat_ok %u, good_fat_nbr %u, fat_mismatch %u\n",
2689 nbr_fat_unreadable, nbr_fat_corrupted, nbr_fat_ok, good_fat_nbr, fat_mismatch);
2690 }
2691 /* Write FAT if necessary */
2692 if(fat_mismatch!=0)
2693 {
2694 fat_damaged=1;
2695 if(nbr_fat_ok>=1)
2696 {
2697 /* Use the good/best FAT to repair the bad one */
2698 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2699 {
2700 if(fat_nbr!=good_fat_nbr)
2701 {
2702 if(verbose>2)
2703 {
2704 dump_log(buffer_fat[fat_nbr], rw_size);
2705 }
2706 if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
2707 {
2708 #ifdef HAVE_NCURSES
2709 if(ask_confirmation("Use FAT%u to repair FAT%u table, confirm ? (Y/N)",good_fat_nbr+1,fat_nbr+1)!=0)
2710 {
2711 allow_write[fat_nbr]=FAT_REPAIR_YES;
2712 log_info("repair_FAT_table: correcting FAT%u (sector %lu) using FAT%u\n",fat_nbr+1,
2713 start_fat1+fat_length*fat_nbr+old_offset_s, good_fat_nbr+1);
2714 }
2715 else
2716 #endif
2717 {
2718 allow_write[fat_nbr]=FAT_REPAIR_NO;
2719 log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu) using FAT%u\n",fat_nbr+1,
2720 start_fat1+fat_length*fat_nbr+old_offset_s, good_fat_nbr+1);
2721 }
2722 }
2723 if(allow_write[fat_nbr]==FAT_REPAIR_YES)
2724 {
2725 if((unsigned)disk_car->pwrite(disk_car, buffer_fat[good_fat_nbr], rw_size,
2726 partition->part_offset + (uint64_t)(start_fat1 + fat_length * fat_nbr + old_offset_s) * disk_car->sector_size) != rw_size)
2727 {
2728 display_message("repair_FAT_table: write failed.\n");
2729 }
2730 }
2731 }
2732 }
2733 }
2734 else
2735 {
2736 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2737 {
2738 if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
2739 {
2740 #ifdef HAVE_NCURSES
2741 if(ask_confirmation("Remove invalid cluster from FAT%u table, confirm ? (Y/N)",fat_nbr+1)!=0)
2742 {
2743 allow_write[fat_nbr]=FAT_REPAIR_YES;
2744 log_info("repair_FAT_table: correcting FAT%u (sector %lu)\n",fat_nbr+1,
2745 start_fat1+fat_length*fat_nbr+old_offset_s);
2746 }
2747 else
2748 #endif
2749 {
2750 allow_write[fat_nbr]=FAT_REPAIR_NO;
2751 log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu)\n",fat_nbr+1,
2752 start_fat1+fat_length*fat_nbr+old_offset_s);
2753 }
2754 }
2755 if(allow_write[fat_nbr]==FAT_REPAIR_YES)
2756 {
2757 if((unsigned)disk_car->pwrite(disk_car, buffer_fat[fat_nbr], rw_size,
2758 partition->part_offset + (uint64_t)(start_fat1 + fat_length * fat_nbr + old_offset_s) * disk_car->sector_size) != rw_size)
2759 {
2760 display_message("repair_FAT_table: write failed.\n");
2761 }
2762 }
2763 }
2764 }
2765 }
2766 else
2767 {
2768 /* only one fat or fat match */
2769 if(nbr_fat_ok==0)
2770 { /* fat_corrupted */
2771 fat_damaged=1;
2772 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2773 {
2774 if(verbose>2)
2775 {
2776 dump_log(buffer_fat[fat_nbr], rw_size);
2777 }
2778 if(allow_write[fat_nbr]==FAT_REPAIR_ASK)
2779 {
2780 #ifdef HAVE_NCURSES
2781 if(ask_confirmation("Remove invalid cluster from FAT%u table, confirm ? (Y/N)",fat_nbr+1)!=0)
2782 {
2783 allow_write[fat_nbr]=FAT_REPAIR_YES;
2784 log_info("repair_FAT_table: correcting FAT%u (sector %lu)\n",fat_nbr+1,
2785 start_fat1+fat_length*fat_nbr+old_offset_s);
2786 }
2787 else
2788 #endif
2789 {
2790 allow_write[fat_nbr]=FAT_REPAIR_NO;
2791 log_info("repair_FAT_table: doesn't correct FAT%u (sector %lu)\n",fat_nbr+1,
2792 start_fat1+fat_length*fat_nbr+old_offset_s);
2793 }
2794 }
2795 if(allow_write[fat_nbr]==FAT_REPAIR_YES)
2796 {
2797 if((unsigned)disk_car->pwrite(disk_car, buffer_fat[fat_nbr], rw_size,
2798 partition->part_offset + (uint64_t)(start_fat1 + fat_length * fat_nbr + old_offset_s) * disk_car->sector_size) != rw_size)
2799 {
2800 display_message("repair_FAT_table: write failed.\n");
2801 }
2802 }
2803 }
2804 }
2805 }
2806 }
2807 for(fat_nbr=0;fat_nbr<fats;fat_nbr++)
2808 free(buffer_fat[fat_nbr]);
2809 }
2810 if(fat_damaged==0)
2811 {
2812 if(current_cmd!=NULL)
2813 log_info("FATs seems Ok, nothing to do.\n");
2814 else
2815 display_message("FATs seems Ok, nothing to do.\n");
2816 }
2817 else
2818 {
2819 disk_car->sync(disk_car);
2820 }
2821 #ifdef HAVE_NCURSES
2822 delwin(window);
2823 (void) clearok(stdscr, TRUE);
2824 #ifdef HAVE_TOUCHWIN
2825 touchwin(stdscr);
2826 #endif
2827 #endif
2828 }
2829 return 0;
2830 }
2831
write_FAT_boot_code_aux(unsigned char * buffer)2832 static int write_FAT_boot_code_aux(unsigned char *buffer)
2833 {
2834 const unsigned char boot_code[DEFAULT_SECTOR_SIZE]= {
2835 0xeb, 0x3c, 0x90, 0x6d, 0x6b, 0x64, 0x6f, 0x73, 0x66, 0x73, 0x00, 0x00, 0x02, 0x08, 0x01, 0x00,
2836 0x02, 0x00, 0x02, 0x00, 0x00, 0xf8, 0xcc, 0x00, 0x3f, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
2837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xf8, 0x3f, 0x7c, 0x3e, 'T', 'E', 'S', 'T', 'D',
2838 'I', 'S', 'K', 0x20, 0x20, 0x20, 0x46, 0x41, 0x54, 0x31, 0x36, 0x20, 0x20, 0x20, 0x0e, 0x1f,
2839 0xbe, 0x5b, 0x7c, 0xac, 0x22, 0xc0, 0x74, 0x0b, 0x56, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10,
2840 0x5e, 0xeb, 0xf0, 0x32, 0xe4, 0xcd, 0x16, 0xcd, 0x19, 0xeb, 0xfe, 'T', 'h', 'i', 's', ' ',
2841 'i', 's', ' ', 'n', 'o', 't', ' ', 'a', ' ', 'b', 'o', 'o', 't', 'a', 'b', 'l',
2842 'e', ' ', 'd', 'i', 's', 'k', '.', ' ', ' ', 'P', 'l', 'e', 'a', 's', 'e', ' ',
2843 'i', 'n', 's', 'e', 'r', 't', ' ', 'a', ' ', 'b', 'o', 'o', 't', 'a', 'b', 'l',
2844 'e', ' ', 'f', 'l', 'o', 'p', 'p', 'y', ' ', 'a', 'n', 'd', 0x0d, 0x0a, 'p', 'r',
2845 'e', 's', 's', ' ', 'a', 'n', 'y', ' ', 'k', 'e', 'y', ' ', 't', 'o', ' ', 't',
2846 'r', 'y', ' ', 'a', 'g', 'a', 'i', 'n', ' ', '.', '.', '.', ' ', 0x0d, 0x0a, 0x00,
2847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2849 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2850 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2851 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2852 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2854 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2855 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2856 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2861 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2862 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2863 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2864 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2865 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
2867 };
2868 memcpy(buffer,&boot_code,DEFAULT_SECTOR_SIZE);
2869 return 0;
2870 }
2871