Download OSR2CFIX.ZIP now
What Is OSR2CFIX?
Removing the Patch
A Technical Explanation of What's Going On
This program may be copied freely but not modified. If you
discover a problem with the program or the patch it applies,
please email me the details at
so I can make
any appropriate updates available to everyone.
What is OSR2CFIX?
OSR2CFIX is a program designed to make a small alteration to the
COMMAND.COM file which comes with Windows 98 or Windows 95 OSR2 (sometimes also
called version B of Windows 95) which makes it possible to run
certain DOS programs which refuse to run otherwise.
As reported by Sean Erwin on his OSR2 Frequently Asked Questions page, some programs compiled with a 16-bit Borland C compiler cause a general protection fault (GPF) when run under Windows 95 OSR2, though they run properly under OSR1 (the original public release of Windows 95). The same problem also shows up under Windows 98. The programs affected are those which run COMMAND.COM themselves, perhaps in order to run a batch file or DOS command. The problem is caused by a minor change made to COMMAND.COM when Windows 95 OSR2 was released. OSR2CFIX makes another minor change to the COMMAND.COM file which makes it load successfully when called by a 16-bit Borland C program. Details concerning the problem and the solution can be found in the Technical Explanation section near the end of this document.
This program should be run only on systems running Windows 95 OSR2 or Windows 98. To identify if your system is running Windows 95 OSR2, type VER at a DOS prompt. If it says
Windows 95. [Version 4.00.1111]you are running OSR2; if the version number is different (e.g., something other than "1111" appears after the second decimal point), you should not run this utility.
This utility takes considerable
precautions to identify correctly each COMMAND.COM it examines and
will refuse to modify any version it does not recognize as an OSR2
or Windows 98
version. However, I can not guarantee that it will recognize all
versions correctly--most particularly versions not yet released by
Microsoft, such as the one that will ship with Windows Millennium. If you
patch a COMMAND.COM file with OSR2CFIX and then discover that this
has created another problem, you can always run OSR2CFIX again and
remove the patch. Of course, I would like to be notified of such
problems in case other users might be affected.
Just type OSR2CFIX for a summary of possible usage. The following
display will appear:
Usage: OSR2CFIX [-a] [-s] [-v] [fileName]Except in very unusual circumstances, the most preferred way to use this program is to type-a: Autoscan; scans MSDOS.SYS for files to check. -s: Report the states of files only; do not change anything. -v: Verbose output. fileName: Name of a COMMAND.COM file to check.The -a and fileName options are mutually exclusive.
OSR2CFIX -aand press <Enter>. This will cause OSR2CFIX to check all COMMAND.COM files referenced by MSDOS.SYS on the Windows 95 or 98 boot drive. You will be asked to indicate which drive is used to boot Windows.
As an alternative to using -a, you can specify the full path to a COMMAND.COM file when invoking OSR2CFIX, in which case only that file will be checked:
OSR2CFIX C:\WINDOWS\COMMAND.COMwill only work with the COMMAND.COM in C:\WINDOWS. Note: This usage is not recommended, because it can result in differences among active copies of COMMAND.COM.
There are two other command-line options understood by OSR2CFIX: -s (status) specifies that nothing is to be changed; the program will report the statuses of COMMAND.COM files but will not offer to alter them. -v (verbose) causes extra output to be generated while COMMAND.COM files are being scanned. For each copy of COMMAND.COM examined, the location and first two bytes of each pattern match are shown. For OSR2 COMMAND.COM files, this output should look like this:
04260h: 7Ah,17h 04360h: 06h,17hThese numbers will be different for other versions of COMMAND.COM, including those patched by this program. The -v option is primarily intended as a debugging aid but may also be interesting to the curious.
WARNING: If OSR2CFIX finds COMMAND.COM files which it believes
are not patchable, you should take extreme care before proceeding
further. If MSDOS.SYS was used to find files (the -a option was
used), and one or more of these is shown not to be patchable, you
are probably dealing with either a Windows 95 OSR1 installation
or a damaged OSR2 installation. This program should not be run
against OSR1 installations. If yours is definitely an OSR2 or
installation, and OSR2CFIX reports unpatchable COMMAND.COM files, I
strongly recommend that you immediately run SCANDISK and possibly a
virus scanner to determine the cause of the problem.
Removing the Patch
This program can restore COMMAND.COM files to their original
states if this becomes necessary. The program does not create
backups of each COMMAND.COM file it modifies; rather, it contains
enough know-how to recreate the original files if asked to do so.
If you run OSR2CFIX after having already patched your COMMAND.COM
files, you will notice that the first choice will be to "restore"
rather than to "patch." If you elect to restore files to their
original versions, your COMMAND.COM files will be rewritten as
they were before you ran OSR2CFIX the first time.
A note to users of my first patch instructions (as posted in Sean
Erwin's OSR2 FAQ and on Usenet): If you patched COMMAND.COM as
instructed by my June, 1997 Usenet article and OSR2 FAQ quote, you
should "repatch" it with this program. The old patch fails to
work on some systems (see the
section below), whereas the patch applied by OSR2CFIX appears to work
under all conditions. This program will recognize and inform you
of such already-patched versions of COMMAND.COM by saying that
they are "patched the old way." This program can apply the new
patch to these files, and it can restore them to their original
(totally unpatched) states; it can not, however, reapply the old
patch once having removed it. In other words, if you use OSR2CFIX
to update a COMMAND.COM patched the old way, you can be sure that
the old, less reliable patch is gone.
A Technical Explanation of What's Going On
The following explanation is drawn loosely from what I sent
on 08/11/97 for inclusion in his
web page. Since then, I have significantly revised this
discussion to include further information made available to me at
a later time. To those who
understand 80x86 assembly language, this will explain what the
problem is and how the patch manages to fix it, as well as the
problem encountered with the older patch. For those who don't
know what I mean by 80x86 assembly language, this section may
serve as effective, if unusual, bedtime reading material. :-)
From the user's perspective, the problem is that some programs, when run under Windows 95 OSR2 or Windows 98, crash with no apparent reason, even though they run fine under the OSR1 version of Windows 95. It turns out that all of the programs which do this (at least all those reported to date) share two characteristics: (1) they were compiled with a 16-bit Borland C/C++ compiler, and (2) they attempt, in the course of execution, to run COMMAND.COM via an exec..() function call (or a spawn..() call with a mode of P_OVERLAY). I suspect that this problem may affect programs compiled with some other compilers, but this has yet to be demonstrated.
Due to a change in the format of COMMAND.COM at the release of Windows 95 and to the unusual way Borland 16-bit C compilers run COMMAND.COM (load-then-call), programs compiled with Borland 16-bit C compilers wind up starting Windows 95+ COMMAND.COM at a different point than they used for earlier versions of COMMAND.COM. At the release of Windows 95, the format of COMMAND.COM quietly changed from .COM to .EXE, though the name of the file did not reflect this change in format. For most programs, this doesn't matter, because most programs which call COMMAND.COM do so by making a call to the operating system to run COMMAND.COM; the operating system then handles the difference in file format. However, Borland 16-bit C compilers use INT 21h, function 4Bh, subfunction 03h (load as overlay) to load COMMAND.COM into memory, then jump to offset 100h (using the CS value indicated on the above call's return) to begin executing COMMAND.COM. While this strategy worked with the older .COM format of COMMAND.COM, it fails to work as planned for the .EXE format: Even though IP is set to 100h, CS is set by the INT 21 call such that offset 100h points to a different part of the file. COMMAND.COM is thus started at a different entry point.
The bytes at the new (incorrect) entry point look like valid code, but are not. I actually suspect that most of the bytes at that location are copied for some reason from the "real" entry point (they look almost identical in all COMMAND.COM files I have examined). However, it turns out that the first byte at this offset is used by Windows 95+ as the binary version number for the COMMAND.COM file: 0x70 representing version 7.0 for the original Windows 95, and 0x7A representing version 7.10 for Windows 95 OSR2 (these are the version numbers you see if you issue the "VER" command in DOS).
Even though executing a version number as code is certainly not guaranteed (or likely) to work, it does under the original release of Windows 95; but it does not work under Windows 95 OSR2 or Windows 98. 0x70 (original Windows 95) is a JO (branch on Overflow set) instruction if interpreted as code, whereas 0x7A (OSR2 and later) is JPE (jump on Parity even). The flags set at the time the load-as-overlay call described above returns are Interrupt-enable, Zero, and Parity Even. Thus, the branch is ignored in the original Windows 95 release but taken in later versions of Windows. Presumably because most of the bytes at this invalid entry point are copied from the valid entry point, ignoring the branch causes things to work properly; but taking the branch causes the execution of an invalid code stream, which finally produces the crash the user sees.
Here is the problem in the words of a Microsoft employee with whom
I corresponded regarding this issue in October, 1997:
The opcode for JO is "x70". The opcode for JPE is "x7A". You are
correct that we changed this in OSR-2, and are correct that IO.SYS
verifies this byte. The error, however, is that this is not a valid
entry point. This is a single byte "version" for the binary. Windows 95's
DOS version was 7.0. OSR-2 had MS-DOS 7.10. "10" in decimal is "A" in
hex. So, it appears that if the Borland compiler is jumping to offset
"0", then it is jumping to the version number and executing it. It is
just dumb luck in Win95 that this worked properly. The reason that
IO.SYS checks this byte is to make sure that the versions of io.sys and
command.com are in sync.
My first solution to the problem was to change the JPE back to a JO. At the time, I was not aware that the JPE was actually the version number of COMMAND.COM (7.10). It turns out that there is code in IO.SYS which tests this byte of COMMAND.COM to make sure it is the right version; if it is not, IO.SYS prints the message, "The following file is missing or corrupt: COMMAND.COM," and pauses to ask the user to type the name of the command interpreter to use. Oddly, this only happens if there is no "SHELL=..." line in CONFIG.SYS--which is how I managed not to notice, since my systems' CONFIG.SYS files contain such a line.
My current solution involves effectively disabling the JPE without
changing it by making the branch offset 0. This solution will
actually work for any version of COMMAND.COM in which the binary
version number happens to correspond to a branch instruction, at
least as long as the (apparently copied) block of bytes at that
"entry point" otherwise continue to function like the
code at the valid entry point. The strategy has already been
proven to work for Windows 98.
I hope this little utility proves helpful. Again, please notify me of any problems via email to firstname.lastname@example.org
Late-Breaking News (last update 08/01/1999)
Download OSR2CFIX.ZIP now