Re: Microsoft; an example ...

greenspun.com : LUSENET : Poole's Roost II : One Thread

When Microsoft released Windows 95 OSR2 with FAT32 large drive support, if you attempted to use an older DOS-based utility that did direct disk access (from anti-virus software to a disk repair program), at best, the program wouldn't work; at worst, Windows would display an ominous error message and hang the system:

Windows has disabled direct disk access to protect your long filenames. To override this protection, see the LOCK /? command for more information.

The system has been halted.

Needless to say (and speaking from experience!), this caused no small amount of consternation on the part of utilities and anti-virus vendors (I was working for the latter at the time). So, we tried that LOCK thingie and got ...

WARNING: The LOCK command enables direct disk access by programs that can CORRUPT file names and/or DESTROY disk data, resulting in the loss of files on your disk.

Are you sure (Y/N)?

Wow! "CORRUPT?" "DESTROY?" Imagine the effect that this has on Joe Sixpack; he's going to toss your nasty little utility program and go buy something else! He doesn't even want to SEE something like that, not even if you've reassured him a dozen times!


Let me say this up front: the issue is not necessarily what Windows did to these older utilities; remember what I said in that other thread about McDonalds and ketchup? Things change, times change and the marketplace changes; that's just part of the risk of doing bid'ness.

I'm certainly not defending the old, clunky INT 25h interface, or even its successor, the INT 21h/AX=440Dh/CL=61h "Read Logical Track" function, either. While these are all we had to work with (so you can't blame us for using them -- especially the latter!), there's no doubt that improvement was needed.

The real issue here, though, is how Microsoft chose to handle this. As it turns out, this is another classic case of "don't do as we do, do as we say."

You see, when Microsoft first began receiving complaints about this, they responded that the new FAT32 file system could easily be corrupted by these older utilities.

"You should use the new INT 21h/AX=7305h function." intonded Redmon. "The new FAT32 file system and your long file names could be damaged if you use the older method."


So, off everyone scooted on a mad race to rewrite software, burning up countless man hours and untold expense. Many of us lost customers while we were poking through the code looking for stray "Read Track" calls.

And as it turns out, Microsoft directly misled us about the reason behind the change. Again, look at the wording above: "we're protecting your long filenames. You could suffer corruption -- your data could even be DESTROYED!"

Here's your first clue: disk read and write are handled at the hardware level by a device driver. All of these have a generic interface that simply receives a request from DOS: "gimme some data." The device driver, and not the programmer (or even the INT 21h interface in DOS!), decides where to fetch the desired data.

(An aside: that's the whole purpose of device drivers. If I invent a new gadget, I'll also write a device driver that will let you use it as soon as I put it on the market. Windows or DOS will simply call my custom-written device driver to access it. They don't care how it works.)


So, from the programmer's point of view, we couldn't care less if the data is stored sequentially, in neat little rows or scattered at random around the hard drive. We just call DOS, DOS calls the driver and we gets data.

Now, it's true that DOS maintains the directories and system structures that tell it where various files are, how many clusters each file uses, and so on. But the implication here is that these older programs could somehow inherently damage your data just by doing direct disk access.

(And read access at that. Don't miss that part! How is a read going to corrupt data?)

Besides, these low-level structures are themselves just "files" of a sort, albeit more primitive. If I'm writing a disk repair utility, I don't care what's in sector 3 on track 5; I save it and then restore it. If it happens to be a table filled with long file names, I'll restore it the same as if it's a .GIF of a dancing chicken. My program doesn't care.


So, that leaves only a few select disk write utilities, those which might have been released before long filenames were added to Window and which thus might screw things up when you try to restore a blitzed hard drive with them. But two points:

  1. There are better ways to handle this. Software incompatibility is an old problem; simply warn people that they use the older stuff at their own risk, and
  2. Unless you're using a product like my buddy Ralph's DOS32, you're out of luck anyway, because the long filename support is provided by VxDs -- which means that Windows would have to be running anyway!

(Honestly, I don't know whether to laugh or cry. Microsoft says that they're trying to protect my long filenames and their own XCOPY program won't do long filenames unless Windows is running!!! So much for restoring my long filenames with XCOPY from an emergency DOS boot!!!)

(Whimper, whimper.)


(Ahem; anyway.) OK, so, given that about device drivers, I was a little puzzled to start with. But it gets even more interesting. Here's where your eyes will glaze over unless you're a programmer who can understand 80x86 assembler.

(And this is a classic example of what I said in the previous thread: how DO you explain stuff like this to the laycreature without his/her eyes clouding up? And is this even proof of wrongdoing? I honestly can't say. But here goes ...)

The pertinent code from the INT 25h handler under the DOS that ships with Windows 98 (which I have) looks like this:

Address   Instruction
4434      SS:
4435      MOV [0ADB],AH
4439      OR  AH,AH           ; <- note: check for AH = 0
443B      JNZ 4447            ;If it's not zero, skip ahead
443D      SS:
443E      INC BYTE PTR [0321] ;Raise the InDOS flag
;  .
;  .        do some other stuff here ...
;  .
4459      OR AH,AH            ; <- here's the critical check!
445B      JNZ 445E
445D      STC                 ; <- if AH=0, fail the call!
445E      POP DS
445F      JB 448E
;  .
;  .
;  .
448E      SS:
448F      MOV WORD PTR [0DBF],0207  ;Set the error code for return
4495      SS:
4496      MOV WORD PTR [0324],0032
449C      RET

;Here's the actual INT 25h entry point; you'd get here with INT 25h call
;in a DOS program.
449D      XOR AH,AH           ;<- Clear AH; force it to 0!
449F      XOR SI,SI
44A1      CLI                 ;<- *** see below ***
44A2      PUSH    AX          ;Protect AX; it's important!
;  .
;  .        do some other stuff ...
;  .
44AD      POP     AX          ;Restore AX
;  .
;  .        do some other stuff ...
;  .
44AF      OR AH,AH            ;<- Once again, check for AH=0
44B1      JNZ 44C3
44B3      MOV [061B],SS       ;If it's zero, we'll set up a DOS stack
44B7      MOV [061D],SP       ;(but only for a moment, we're bailing
44BB      CS:                 ; out shortly!)
44BC      MOV SS,[3F27]
44C0      MOV SP,0920
44C3
;  .
;  .        do some other stuff ...
;  .
44CC      CALL 4434        ;Jump back to the stuff we saw above; it
44CF      JB [bailout]     ; sees AH=0, sets the carry and we bail out!

Knowing how device drivers work at the DOS level is your first clue; here's the second. This is a pretty good indication that something is calling directly into this interface from within DOS, because he wants a secret way to get in without setting up the DOS stack again (which would destroy anything already PUSHed onto it) and without raising the InDOS flag a second time.

Ah, the little Decoder Ring, the secret key, is to set AH to something other than zero. When you or I call into this from a program, we're going to hit the stuff at 449D, above, which instantly clears AH to zero, so we can't do that. So who does?

Enter: Microsoft's own DOS utilities, which include FORMAT, SYS, CHKDSK and SCANDISK. All of the new versions are good little programs: they call the "new" INT 21h/AX=7305h function mentioned above. But what does that function do? Heh. He builds a register set for a standard INT 25h call, then he does this!

Address   Instruction
5491      MOV AH,01           ;Set AH=1!
;  .
;  .        do some other stuff ...
;  .
549E      CALL 44A1           ;Call the point that we marked with "***"
                              ; above, right AFTER the XOR AH,AH!

Heh, heh, heh. Ah, so ... I guess the original code doesn't corrupt data as badly as Microsoft led us to believe ...

How about that! :)


Now, when I first presented this information in the Dr. Dobb's forum on Compuserve a few years ago, the general response was, "so? Big deal."

But it is a big deal, Buh'wheat. Microsoft's choice of coding here broke dozens of old utility programs, leaving them to play emergency catch-up. And don't forget, in the software marketplace, being first usually means being the winner.

(Remember, the whole reason why the Netscape thing even came up, lawsuits and all, was because Netscape was first. Redmon had to play catch up and they didn't like it, not one bit.)

Was it deliberate? I honestly can't say. I've felt for years that many things like this don't necessarily emit from a conscious desire on Microsoft's part to hurt its competitors, but from simple arrogance and a marked lack of concern about whom they might hurt.

(But that's not a defense. It's one of the things you have to fear from monopolies in general ... which is another reason why we have anti-trust laws.)


Others wanted to nitpick. "Windows handles all of this in VxDs, anyway; it's a moot point."

Correct. But not only do some of these VxDs continue to call down to DOS (albeit in slicker ways so that it's not as easily detected), I grow weary sometimes of pointing out that DOS is critical to Windows. You can't just write it off!

To start with, DOS serves as Windows' boot loader. When your computer first boots, in spite of that fine-looking blue-sky-and-cloud screen, it's in DOS mode for quite some time.

More importantly, remember that I'm talking about utilities here, especially those that you'll need to recover from a virus or a drive failure. What are you going to do if your system does become corrupt, requiring data restoration and repair? That's right, you're going to do it with a DOS utility, because you won't be able to start Windows!

(I am endlessly amazed at the number of people who apparently never even think about this. They don't even have a StartUp Diskette for Windows!)

But even granting that, some people will want to argue. "Well, Microsoft's programs set Lock flags and do other stuff." Yup. That's not the point; the question is whether Microsoft really needed to break these older utilities.

I say they didn't. That's just my opinion, but there you go.

Again: I reserve the right to extend and clarify these remarks and this is just my opinion.

-- Anonymous, June 30, 2001

Answers

One other point (if your eyes haven't completely glazed by now). Other arguments that could be raised might include, "this isn't true when Windows is running/when you're on a FAT16 volume/whatever."

When I first researched this, I used a system-level debugger to set breakpoints in the code and carefully traced any number of direct disk read calls. Whether I was on a FAT32 drive or FAT16 drive, a hard disk or a floppy, my breakpoint at that "***" mark, above, clanged to a halt whenever I ran SCANDISK, FORMAT, SYS or CHKDSK. Every time.

(In fact, on SCANDISK, I had to remove the breakpoint just to get it out of the way; it was making so many "INT 25h-that-aren't-really INT 25" calls (wink wink) that it was taking forever to run.)

So there. :)

-- Anonymous, June 30, 2001


Moderation questions? read the FAQ