>>> Hi Berco
>>> > For %%d in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do IF
>>> > errorlevel H%%d set rdrv=%%d
>>> I dont quite undestand that syntax. Linewapping doesn' help :-(
>>I suspect that that peculiar line is intended to exploit a known
>>defect in COMMAND.COM. No sanity checking is done on the number
>>following IF ERRORLEVEL, so it's possible to pass it non-numerics.
>>Which pretty well demonstrates the whole difference of mindsets,
>> 4DOS user: "I found a bug. How quickly can we get it fixed?"
>> COMMAND.COM user: "I found a bug. How can I exploit it?"
>But what does the above *do*?
>(I suppose that makes this OT in com4...)
Imagine that you had to write a parser in assembly language which
would read a string of ASCII digits from a text file, and convert
to an 8-bit integer value. That's one of the tasks IF ERRORLEVEL
has to perform.
In order to convert your ASCII string into an integer, you would
start by zeroing an accumulator to hold the result. DOS exit
codes only go up to 255, so a single byte would suffice. Either
an 8-bit register or a location in memory would be fine.
Next, you'd write a loop to read characters (digits, presumably)
from the file and modify your accumulator accordingly. As you
read in each character, you'd check that it was in fact a digit,
and then you'd subtract 48 (decimal) from each one to convert
it from ASCII to its value. (The character "0" has an ASCII
value of 48.) Then you'd multiply the current contents of your
accumulator by 10 and add in the value of the digit you've just
read. Perhaps you would check for overflows at this point.
Finally, you'd loop back for the next digit. When you run out
of digits, you are done parsing the integer and your accumulator
contains the value that IF ERRORLEVEL is to compare the most
recent exit code against.
Now, let's imagine that you forgot to write the check for actual
ASCII digits, 48 through 57, and so your routine accepts other
characters as 'digits'. How would it deal with a strange string
like, say, the "HC" in "IF ERRORLEVEL HC"?
Well: your accumulator starts at zero. The first 'digit', "H",
is ASCII character 72. Subtract 48, and it gets a value of 24.
Multiply the accumulator by ten, add 24, and your working value
is 0*10+24 = 24. The second 'digit', "C", is ASCII 67. Subtract
48, and its value is 19. Multiply the accumulator by ten and add
19, you get 24*10+19 = 259. But wait, it's only eight bits and
has just overflowed! Well, this is Microsoft, we don't check for
overflows; 259 mod 256 is 3. The next character is a space, no
more digits, we're done parsing the integer. IF ERRORLEVEL HC
works out to the same thing as IF ERRORLEVEL 3.
4DOS has its own quirks. Rather than writing a special eight-bit
integer parser just for IF ERRORLEVEL, Rex chose to call some
existing, vastly more sophisticated numeric parser. So instead
of writing IF ERRORLEVEL 3, you can say IF ERRORLEVEL 1048579 or
IF ERRORLEVEL 3.14159265358979323846 or even IF ERRORLEVEL -253.
Negative error codes, whooo -- shades of Macintosh!