Home -> OEM IDs

On OEM IDs (v1.3, 2006-04-17)

Introduction

In 1999, a message was posted to the OpenDOS mailing list at delorie.com. In brief, it describes a problem with using MS-DOS (or Windows 95/98/ME) on partitions created with DR-DOS FDISK, which can result in serious data corruption. The problem seems to arise because of two factors; if either is changed, it goes away. The factors are:

So, why should this combination of circumstances cause trouble?

Background

In this document, I am concerned only with the behaviour of hard drives formatted with the FAT12 or FAT16 filesystems. I don't cover floppies, FAT32, or other filesystems such as HPFS and NTFS.

For practical purposes, all[2] FAT12/FAT16 partitions start with a standard boot sector. This is laid out as follows:

Offset from start Meaning
0 3 byte jump to boot code.
3 OEM ID (or OEM label). 8 bytes ASCII.
11 BIOS Parameter block (BPB), describing number of tracks, number of sectors, cluster size, root directory size, FAT size and so on. BPBs written by earlier versions of MS-DOS are 25 bytes long; later ones are 51 bytes.
36 or 62 Boot code

The OEM ID is pretty poorly documented. Microsoft's knowledge base simply describes it as a string of characters. The Windows 2000 resource kit says that Windows 2000 sets it to be "MSDOS5.0" 'to preserve compatibility with MS-DOS'. Microsoft's paper FAT: General Overview of On Disk Format says "Microsoft operating systems don't pay any attention to this field". This is incorrect, as is quite easy to prove.

Reproducing the problem

You will need:

Proceed as follows:

  1. Create a new virtual machine.
  2. Boot from the DR-DOS 7.03 floppy, and type FDISK. Create a primary DOS partition that's 126 megabytes in size.
  3. Reboot when prompted. At the A> prompt, type CHKDSK C: and verify that the cluster size is 4096 bytes.
  4. Create a subdirectory on the newly formatted C: drive and copy some text files into it.
  5. Now reboot from the MS-DOS disc,  and try to read the text files. If the problem is manifesting itself (which it should be), you will find that either the contents of the subdirectory cannot be seen, or (if it can) that the text files are scrambled.
  6. Using your sector editor, go to the boot sector of drive C:. The OEM ID should read "DRDOS  7"; change it to "IBM  3.3".
  7. Reboot from the MS-DOS disc and try to read the text files again. This time it ought to work.

More tests

Having set up the test system, I tried various different OEM IDs to see which ones work and which ones don't. After establishing that behaviour was the same whether the first 5 letters read "DRDOS" or "MSDOS", I tended to leave them reading "MSDOS".

OEM ID Result
DRDOS  7 Fails
DRDOS7.0 Works
IBM    3 Fails
IBM  3.3 Works
IBM 3.3  Works
IBM3.3   Fails
MSDOS  5 Fails
MSDOS .  Fails
MSDOS... Fails
MSDOS1.0 Fails
MSDOS2.1 Fails
MSDOS3.0 Fails
MSDOS3.1 Works
MSDOS3/0 Works
MSDOS300 Works
MSDOS5 0 Fails
MSDOS5-0 Fails
MSDOS5.0 Works
MSDOS5/0 Works
MSDOSA.B Works
OPENDOS7 Works

What's going on? According to this USENET posting, MS-DOS is trying to work around bugs in early versions of MS-DOS or OS/2. One of these workarounds involves calculating the cluster size from first principles and using that in preference to the cluster size in the BPB. DR-DOS FDISK chose to use 4k clusters but the calculation comes up with 2k. The result is that for each file on the drive, MS-DOS and DR-DOS have different ideas about which sectors it occupies.

The USENET article also suggests that MS-DOS requires the OEM ID to be formed "xxxxxY.Y" (where x is any character and Y must be a digit) but this doesn't quite match the results above, where "xxxxxY/Y" and "OPENDOS7" worked.

So, having exhausted other avenues, I cast caution to the winds and broke out the Bochs debugger.

What MS-DOS Actually Checks

MS-DOS does various tests on the OEM ID, but the one that seems to causes all the trouble is this:

C:\>debug io.sys
-u2672
0CC5:2672 2E            CS:
0CC5:2673 817F08332E    CMP     WORD PTR [BX+08],2E33
0CC5:2678 72DD          JB      2657
0CC5:267A 7507          JNZ     2683
0CC5:267C 2E            CS:
0CC5:267D 807F0A31      CMP     BYTE PTR [BX+0A],31
0CC5:2681 72D4          JB      2657

What it is trying to do is check if the version number in the last 3 bytes of the OEM ID is less than "3.1" (which explains why "MSDOS3.1" works and "MSDOS3.0" doesn't). The check is in two parts:

  1. Check if the first two bytes of the number are less than "3.". If so, do the workarounds.
  2. If the first two bytes were "3.", check if the last byte is less than "1". If so, do the workarounds.

Unfortunately it tries to do the first step using a word comparison. Since it's on a little-endian computer, what actually happens is is this:

  1. Check if the middle byte of the number is less than ".". If so, do the workarounds.
  2. If the middle byte of the number is greater than ".", don't do the workarounds.
  3. If the middle byte is exactly equal to ".":
    • Compare the first byte to "3". If it's less, do the workarounds.
    • If the first byte is equal to "3", check if the last byte is less than "1". If so, do the workarounds.

The end result is that if the middle byte of the number (the last-but-one byte of the OEM ID) is not ".", the comparison doesn't do what it's supposed to. If this byte is less than ".", the result can be very damaging to your data.

How to change the OEM ID in DRDOS utilities

Since MS-DOS objects to the "DRDOS  7" OEM ID, one solution is to change the DR-DOS utilities (FDISK, FORMAT and SYS) so that they don't write this ID. The utilities in question are compressed with PKLITE (which can be downloaded here) so proceed as follows:

  1. Decompress the utility: PKLITE -x filename.COM
  2. Open the decompressed utility in a binary editor (again, Norton's Diskedit is suitable for this purpose).
  3. Search for the "DRDOS  7" string. Replace it with something that MS-DOS doesn't object to, such as "IBM  3.3".
  4. If you want, compress the utility again: PKLITE filename.COM

How long has it been like this?

The code fragment above appears to be present in all versions of MS-DOS from 4.01 up to 7.10 (Windows 98). I couldn't find it in the Windows ME version of IO.SYS, but if you boot it from a floppy the same problem occurs; possibly the WinME IO.SYS is compressed so my simple binary search didn't work.

In MS-DOS 3.3 the check is simpler:

C:\>debug io3.sys
-u3dfd
0CC5:3DFD 26            ES:
0CC5:3DFE 813E0800332E  CMP     WORD PTR [0008],2E33
0CC5:3E04 75F4          JNZ     3DFA
0CC5:3E06 26            ES:
0CC5:3E07 803E0A0031    CMP     BYTE PTR [000A],31
0CC5:3E0C 72EC          JB      3DFA

This version of the check does the workarounds if the first two bytes of the number are not "3.", or the last byte is less than "1". So it would do them for OEM IDs "MSDOS4.0", "MSDOS5.0" and so on. Since MS-DOS 3.3 doesn't support partitions bigger than 32Mb I was not able to test this behaviour on my 126Mb test partition.

Conclusion

If the last-but-one byte of the OEM ID is less than ".", the OEM ID check in MS-DOS will not believe the BPB, but instead use calculated default values for some fields. This can cause filesystem corruption if other operating systems that access the drive do believe the BPB.

It's probably safest to stick to "xxxxxY.Y" (or "xxxxY0.Y") as the format of your OEM ID. Additionally, some versions of IBM PC-DOS (not MS-DOS) apparently require the label to start "IBM  " so it looks like the best label to use is "IBM  m.n" where m.n is either 3.3 or 5.0.

Other Enlightening Web Links

Revision History

Footnotes

1. DRDOS FDISK formats the drive in the process of creating the partition. MSDOS FDISK does not, and so FORMAT.COM has to be used to finish the job.

2. A very few FAT12 implementations don't use the standard boot sector. The custom version of MS-DOS for early Apricot PCs, and DOS Plus for the BBC Master 512, are the only ones I know of.


John Elliott 20 June 2004