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= DX=00d2 SI=0586 DI=000c SP=ffe0 BP=0070
DS=00d2 ES=0889 FS= GS= FL=0246
CS:IP=:0002 SS:SP=0889:ffe0
: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:
...
:02f3 FE062003 inc byte ptr [0320]
:02f7 FE0E2103 dec byte ptr [0321]
:02fb 268E163000 mov ss,es:[0030]
:0300 268B262E00 mov sp,es:[002e]
:0305 CD24 int 0x24