Hi, I have updated (5+ hours) FORMAT to version 0.91r: http://www.coli.uni-sb.de/~eric/stuff/soft/by-others/ format-0.91r.zip Version 0.91r (18 Jul 2004) Changes by Eric Auer: - unless you use the /D option, we now use boring MS compat errorlevels: 0 ok, 3 user abort, 4 fatal, 5 not confirmed (WITH /D option: see help.txt for new errorlevels...!) - attempt to lock non-existing drives is recognized as such (in FAT16 DOS, attempt to get parameters of non-existing drive, *after* format confirmation, is recognized... This is a kludge as FreeDOS 2035 int 21.36/21.1c return wrong errors for unformatted *existing* drives. Happy fixing!?) - now unlocking drives in case of an abort (not for ^C yet) - prompts for label if no /V:... given, unless /Y used - Mirror aborts if it would overwrite used data, SafeFormat gives a warning if mirror data damaged unformateable data - shortended debug messages even more (e.g. in createfs) So Aitor should now be happy with the features. I also noticed that atoi() parses /f:1440k and /f:1440 and /f:1440unitscalledkilobytes all the same, so for full MS syntax only /f:1.44... stuff is missing (so what?). Summary of the highlights: - MS compatible errorlevels in normal mode - more informative errorlevels in /D mode - unlocks drive if an error happens - prompts for a volume label (if none given at command line and if not in /y noninteractive mode). For sequential floppy mode, FORMAT always asks for labels for subsequent disks. - MIRROR refuses to damage the contents of used clusters. Only SafeFormat is allowed to damage data in order to make UnFormat possible in any case. The binary size is still slightly below 32768 bytes ;-)). Happy testing! When trying to make FORMAT properly distinguish between - SafeFormatable drives - not yet formatted drives and - non-existing drives I found that FreeDOS kernel is really buggy in several aspects here. The FAT32 version of the kernel is best: LOCK will fail for non-existing drives. For existing drives, I can distinguish between formatted and not yet formatted drives by reading the boot sector. The FAT16 version compatible calls are worse: int 21.440d.0860 is okay for detecting non-existing drives, BUT I have to wait with this call until AFTER the "do you really want to..." confirmation and LOCK call. It would be better if int 21.36 and int 21.1c would work properly. But: When I call int 21.36 for a not yet formatted drive (it properly detects non-existing drives, at least), I trigger an INTERACTIVE critical error. This confuses people, so I cannot use it in FORMAT. All four choices, abort, ignore, retry, fail, work, but of course RETRY will be infinite and IGNORE is dangerous here, so the whole interactivity is a BUG in our kernel. Correct reaction would be to return error 7, unknown media type (in terms of critical error, that is category "fail"). For non-existing drives, a special (non-error) return value is already defined and working. Things got even worse when I tried int 21.1c as an alternative: This is less recommended because Win9x reportedly has bugs in this function (it might help to check sector size as extra test). For non-existing drives, the correct non-error special return value is returned, but for not yet formatted drives, the whole kernel CRASHES! DS = 0xcf ES=SS = from caller CS = wrong SP = 0xc33d AX = 0x3504 BX = 0x574 CX = 0x6FE DX = 4 SI = 0x574 DI = 0x0E BP = 0x70 ... but that probably does not help much because CS already went mad. Even happens in 2035a: debug w somenonsense 4 0 1 (zap boot sector of E:, don't try at home) q reboot debug acs:100 mov ah,1c mov dl,5 int 21 nop int 20 gcs:106 (drive is 1-based in int 21.1c, so we again check E:) --> DOSEmu tells: AX=3804 BX=1a92 CX=0000 DX=00d2 SI=0586 DI=000c SP=ffe0 BP=0070 DS=00d2 ES=0889 FS=0000 GS=0000 FL=0246 CS:IP=0000:0002 SS:SP=0889:ffe0 0000:0002 6303 arpl [bp+di],ax SP was FFFE and segments were 889 when I did "gcs:106", so: DS points to kernel, AH is "something", AL pretends that the disk would actually be formatted, BX pretends that the whole disk would be free, CX is either not set yet or tells "sector size 0", DX is the kernel segment, SI is "something", DI is "something" (maybe we are in a messed up critical error state "general failure" here?), BP is yet another kernel segment. Stack: 0889:ffe0 07 03 FF FF 46 00 00 1C 00 00 00 00 05 00 00 00 ..F........... 0889:fff0 00 00 00 00 89 08 89 08 06 01 89 08 02 02 00 00 ................ And yes, looks INTish: ... ffff:02f3 FE062003 inc byte ptr [0320] ffff:02f7 FE0E2103 dec byte ptr [0321] ffff:02fb 268E163000 mov ss,es:[0030] ffff:0300 268B262E00 mov sp,es:[002e] ffff:0305 CD24 int 0x24 ffff:0307 FC cld ffff:0308 FA cli ffff:0309 2E8B2E3100 mov bp,cs:[0031] ... The call seems to start at ffff:2b8, code is: push bp / mov bp,sp / push si / push di / ah=[bp+4] / al=[bp+6] / di = [bp+8] / si = [bp+a] / bp = [bp+c] / cli / es=[330] / push [es:30] / push [es:2e] / push [33e] / push [586] / push [584] / push [586] / push [584] / mov [588],sp / inc byte [320] / dec byte [321] / ss=[es:30] / sp=[es:2e] / int 24 / cld / cli / bp=[cs:31] / ds=bp / ss=bp / sp=[588] / pop [584] / pop [586] / pop [584] / pop [586] / pop [33e] / es=[330] / pop [es:2e] / pop [es:30] / bp=sp / ah=[bp+8] / sti / [320] = 0 / inc byte [321] / if AL != 0 352 / if AL & 20 352 / al=3 / 352: if al != 1 35d / if AH & 10 35d / al=3 / 35d: if al != 3 368 / if AH & 8 368 / al=2 / 368: if al == 2 372 / ah=0 / pop di / pop si / pop bp / ret 372: es=ax=[330] / cmp ax,[es:16] / al=3 / jz 36c (that "ah=0 / pop di / ...") / cli / ss=bp=[586] / sp=bp=[584] / [320]=1 / ax=4c00 / [bp]=ax / sti / jmp 1a3 (1a3 seems to be the main int 21 dispatcher, first checking for those functions which do not need a stack. It starts by setting ds=dx=[cs:31], so the entry from "userland" is a bit earlier, probably 18e, where registers are pushed...) The above is, as said, for an 2035a kernel: 15 Jul 2004 Arkady/Lucho 386 FAT32 Borland kernel. Looks like something messes up the int 24 vector at the wrong moment - when it is just about to be called. So probably int 21.1c is attempting to do the same WRONG interactive critical error handling for unformatted disks as int 21.36 does. Only difference: int 21.36 does not crash for some reason. Happy debugging :-|. Eric PS: Fixing int 21.36 would be useful not only for FORMAT but also for WHICHFAT and other things. All three cases - FAT, not formatted and no drive letter - should be distinguishable. I also noticed that the DEFAULT BPB as reported by DOS seems to be quite exotic if you have a FAT16 filesystem on a FAT32 partition (people do have such things: MS FDISK even displays the filesystem FAT type if it differs from partition FAT type, which is kind of illogical... Free FDISK displays partition FAT type, e.g. in /INFO /TECH mode, but I must tell that it was hard to guess "FDISK 3 /INFO /TECH" as the right syntax to check drive 0x83 and get a partition ID dump (decimal, by the way) ...). [Somebody had reported "kernel does not see my drives" - he had a FAT16 FreeDOS and FAT32 partition types: MS DOS 7, because it can do FAT32, found all drives but everything including MS FDISK pretended that the drives would be 100% native FAT16, while in fact partition type was FAT32 and the file- systems were actually FAT16. You cannot blame FreeDOS FAT16 kernel for not detecting the drives, but still a suprising MS / FreeDOS difference... 8-)] (I told him to use a FAT32 kernel or fix the partition types to FAT16 or convert the filesystems to real FAT32 or ... to solve his problem ;-)).