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(&current_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(&current_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, &sectors_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