/* Non-DOS formats count as formats as well! (Eric) */ char Check_For_Format(void) { union REGS regs; regs.h.ah = 0x0d; /* this is in Check_For_Format */ intdos(®s,®s); /* flush buffers, reset disk system */ if (debug_prog==TRUE) printf("[DEBUG] Test-reading boot sector.\n"); /* as int 21.32 does not work for FAT32, we ALWAYS read the boot sector */ param.fat_type = FAT16; /* Check_For_Format: guess "not FAT32" first */ regs.x.ax = Drive_IO(READ, 0, -1); if ((regs.x.ax != 0) && (param.drive_type != FLOPPY)) { /* * if (debug_prog==TRUE) printf("[DEBUG] Trying again in FAT32 mode.\n"); */ if (debug_prog==TRUE) printf(" maybe FAT32?\n"); param.fat_type = FAT32; /* Check_ForFormat: try FAT32 Drive_IO next */ regs.x.ax = Drive_IO(READ, 0, -1); if (regs.x.ax != 0) param.fat_type = FAT16; /* Check_For_Format: revert to FAT1x Drive_IO */ } if (regs.x.ax != 0) /* could not even read boot sector */ { if (debug_prog==TRUE) printf("[DEBUG] Error code: 0x%x\n", regs.x.ax); /* bits: 80 timeout 40 seek 20 controller fail 10 CRC error */ /* 8 DMA error 4 sector not found 2 bad address mark 1 bad command */ /* (int 26 would have special extra code 3, write protect error) */ printf(" Boot sector unreadable, disk not yet formatted\n"); return FALSE; } /* test if sectors per track are 1..63, if the 55 aa magic is, */ /* present and if the bytes per sector word has the value 512 */ /* added 0.91v as MS DOS criterrs on int 21.32 if no FAT file- */ /* system is present on disk. problem found by Alain Mouette. */ if ((sector_buffer[0x18]>63) || (sector_buffer[0x18]==0) || (sector_buffer[0x1fe]!=0x55) || (sector_buffer[0x1ff]!=0xaa) || (sector_buffer[0x0b]!=0) || (sector_buffer[0x0c]!=2)) { printf(" Boot sector contents implausible, disk not yet FAT formatted\n"); return FALSE; } if (param.fat_type == FAT32) { /* if (debug_prog==TRUE) printf("[DEBUG] Checking xBPB (FAT32)\n"); */ regs.x.ax = 0x7302; /* this is in Check_For_Format */ /* read xBPB */ regs.h.dl = param.drive_number + 1; /* 0 default 1 A: 2 B: ... */ regs.x.di = FP_OFF(§or_buffer[0]); sregs.es = FP_SEG(§or_buffer[0]); regs.x.cx = 0x3f; /* amount of to-be-used buffer size */ regs.x.si = 0; /* (can be a magic value to get more data) */ regs.x.cflag = 0; intdosx(®s,®s,&sregs); /* read xBPB for that drive */ if (regs.x.cflag == 0) regs.x.ax = 0; /* call worked */ } else { /* if (debug_prog==TRUE) printf("[DEBUG] Checking DPB/BPB (FAT1x)\n"); */ regs.h.ah = 0x32; /* this is in Check_For_Format */ /* read BPB/DPB */ regs.h.dl = param.drive_number + 1; /* 0 default 1 A: 2 B: ... */ intdosx(®s,®s,&sregs); /* re-read info for that drive */ /* this can cause a critical error if boot sector not readable! */ regs.h.ah = 0; } if (regs.x.ax == 0) { /* could analyze returned DPB - pointer is DS:BX if FAT16/FAT12 */ /* could analyze returned xBPB - it is in sector_buffer if FAT32 */ if (debug_prog==TRUE) printf("[DEBUG] Existing format detected.\n"); return TRUE; } else { printf("Invalid %sBPB (code 0x%x). NOT yet formatted.\n", ((param.fat_type == FAT32) ? "x" : ""), regs.x.ax); return FALSE; /* is this is a network drive or something? */ } } /* Check_For_Format */
/* Non-DOS formats count as formats as well! (Eric) */ static char Check_For_Format(void) { regs.h.ah = 0x0d; /* this is in Check_For_Format */ __dpmi_int(0x21, ®s);; /* flush buffers, reset disk system */ #ifdef __FORMAT_DEBUG__ puts("[DEBUG] Test-reading boot sector."); #endif /* as int 21.32 does not work for FAT32, we ALWAYS read the boot sector */ param.fat_type = FAT16; /* Check_For_Format: guess "not FAT32" first */ regs.x.ax = Drive_IO(READ, 0, -1); if ((regs.x.ax != 0) && (param.drive_type != FLOPPY)) { #ifdef __FORMAT_DEBUG__ printf(" maybe FAT32?\n"); #endif param.fat_type = FAT32; /* Check_ForFormat: try FAT32 Drive_IO next */ regs.x.ax = Drive_IO(READ, 0, -1); if (regs.x.ax != 0) param.fat_type = FAT16; /* Check_For_Format: revert to FAT1x Drive_IO */ } if (regs.x.ax != 0) { /* could not even read boot sector */ #ifdef __FORMAT_DEBUG__ printf("[DEBUG] Error code: 0x%x\n", regs.x.ax); #endif /* bits: 80 timeout 40 seek 20 controller fail 10 CRC error */ /* 8 DMA error 4 sector not found 2 bad address mark 1 bad command */ /* (int 26 would have special extra code 3, write protect error) */ printf(" Boot sector unreadable, disk not yet formatted\n"); return FALSE; } if (param.fat_type == FAT32) { /* if (debug_prog==TRUE) printf("[DEBUG] Checking xBPB (FAT32)\n"); */ regs.x.ax = 0x7302; /* this is in Check_For_Format */ /* read xBPB */ regs.h.dl = param.drive_number + 1; /* 0 default 1 A: 2 B: ... */ regs.x.es = FP_SEG(sector_buffer); regs.x.di = FP_OFF(sector_buffer); regs.x.cx = 0x3f; /* amount of to-be-used buffer size */ regs.x.si = 0; /* (can be a magic value to get more data) */ regs.x.flags &= ~CARRY_FLAG; __dpmi_int(0x21, ®s);; /* read xBPB for that drive */ if (!(regs.x.flags&CARRY_FLAG)) regs.x.ax = 0; /* call worked */ } else { regs.h.ah = 0x32; /* this is in Check_For_Format */ /* read BPB/DPB */ regs.h.dl = param.drive_number + 1; /* 0 default 1 A: 2 B: ... */ __dpmi_int(0x21, ®s);; /* re-read info for that drive */ /* this can cause a critical error if boot sector not readable! */ regs.h.ah = 0; } if (regs.x.ax == 0) { /* could analyze returned DPB - pointer is DS:BX if FAT16/FAT12 */ /* could analyze returned xBPB - it is in sector_buffer if FAT32 */ #ifdef __FORMAT_DEBUG__ printf("[DEBUG] Existing format detected.\n"); #endif return TRUE; } else { printf("Invalid %sBPB (code 0x%x). NOT yet formatted. Or network / CD-ROM?\n", ((param.fat_type == FAT32) ? "x" : ""), regs.x.ax); return FALSE; /* this is a network drive or something */ } }