Disabling the program crash dialog


If you don't want your program to display the standard crash dialog, you can disable it by setting the SEM_NOGPFAULTERRORBOX flag in the process error mode.

The simple-minded way is just to do

SetErrorMode(SEM_NOGPFAULTERRORBOX);

but this overwrites the previous error mode rather than augmenting it. In other words, you inadvertently turned off the other error modes!

Unfortunately, there is no GetErrorMode function, so you have to do a double-shuffle.

DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);

This sets the new error mode (possibly disabling some other error modes that had been set) and saves the previous mode. Then it sets the error mode the right way, adding the SEM_NOGPFAULTERRORBOX flag to the existing error modes.

Merging with existing error modes is important. For example, the previous error mode may have included SEM_NOALIGNMENTFAULTEXCEPT. If you casually turned that off, then the program would not longer receive automatic alignment fault fixups and will start crashing.

(But if you read the documentation, you'll see that SEM_NOALIGNMENTFAULTEXCEPT is special: The system won't let you turn it off once it's been turned on. Why? Because too many people were already making this mistake. I remember before this special rule was introduced. Programs were crashing left and right because they didn't do the double-set shuffle above; as a result, they started crashing on alignment faults. So the special rule had to be added. Welcome to the world of compatibility, where it is the operating system's duty to cover for other people's mistakes. Mind you, the design of the SetErrorMode function makes this mistake a very easy one to commit.)

Note that the error mode is a process-wide setting, not a per-thread setting. This means that manipulating the process error mode is not something you should do lightly, since it may have unintended consequences for other threads (which you might not have control over). For safety's sake, a program should set its error mode when it starts up and not mess with it thereafter.

Of course, if you disable the crash dialog, then you also miss out on the opportunity to retrieve crash reports collected by Windows Error Reporting so you can see where your program is crashing in the real world.

Comments (48)
  1. Is there a way a process can save this flag and other flags (eg the floating point exception flags) before calling third party code (other than wrapping all calls, including some system calls)? In the past we have had lots of problems with printer drivers / TWAIN providers / plug-ins / anything else that runs in-process changing flags like this causing an unrelated area of the application to behave differently. Process wide flags like this in Windows mean a printer driver could (but hopefully wouldn’t) change the application’s behaviour when it crashed.

  2. DrPizza says:

    "(But if you read the documentation, you’ll see that SEM_NOALIGNMENTFAULTEXCEPT is special: The system won’t let you turn it off once it’s been turned on. Why? Because too many people were already making this mistake. I remember before this special rule was introduced."

    It was introduced because MS is insistent on working around faulty applications, thereby making Win32 more brittle and less capable. The OS should not try to second-guess applications in this way.

  3. Raymond Chen says:

    Ben: Try it and see.

    Jonathan: As I noted in the article, SetErrorMode returns the previous error mode. For floating point, you can ask the FPU directly.

  4. Mark Jackson says:

    Just tried it, you don’t get the crash dialog or any anything else! How come you haven’t added a GetErrorMode function?

  5. Raymond Chen says:

    DrPizza: With that attitude nobody would have bought Windows 95.

  6. Mike Dunn says:

    MFC’s DllMain calls SetErrorMode when it gets the DLL_PROCESS_ATTACH notification; is that really a wise thing to do, given that changing the error mode shouldn’t be done lightly?

    I also remember the docs used to give some sample code of the right way to set the mode, it was a bit different though:

    SetErrorMode(SetErrorMode(0)|SEM_NOGPFAULTERRORBOX);

    which seems sensible enough.

  7. Aarrgghh says:

    Raymond: It’s a documentation issue. Microsoft needs to educate their shareholders about the fact that moral superiority is more desirable than revenue. When they complain, just say "user misunderstanding; behavior is by design" and close the issue.

  8. Raymond Chen says:

    DrPizza (b): All non-x86 processors require this to compensate for lazy programmers who think that x86 is the only processor in the world. More on this subject on August 25th.

  9. Cooney says:

    DrPizza (b): All non-x86 processors require this to compensate for lazy programmers who think that x86 is the only processor in the world. More on this subject on August 25th.

    In defense of those ‘lazy’ programmers, I’m sure many of them are merely ignorant. While most CS programs require you to write to multiple unix platforms (for the formally educated), it’s quite possible that a significant portion of people graduate without being bitten by this bug.

    Incidentally, does the NT codebase still run on anything but x86? The only thing I can think of is the embedded stuff and maybe wince, but I don’t know if those targets have this problem with alignment.

  10. Ben Cooke says:

    Aarrgghh: the law says that "shareholder value" is more important than anything else to publically-traded company. I don’t think many of the shareholders would percieve moral superiority as being "better value" than an increased share price.

    Having said that, I’m not really sure what you’re replying to anyway… who said anything about morals?

  11. IA64 and AMD64 – each of which is different from x86

  12. Irf says:

    Out of curiosity, is there a technical reason something like GetErrorMode() hasn’t been added at some point? Or is this API not considered mainstream enough to warrant the change?

  13. Aarrgghh says:

    Ben Cooke: Of course the shareholders don’t value moral superiority — that’s why you have to educate them!

    I was trying to be funny. I may not have succeeded.

  14. Skywing says:

    You can also disable the harderror popup with job objects.

    Setting SEM_NOGPFAULTERRORBOX changes the default behavior for kernel32!UnhandledExceptionFilter to return EXCEPTION_CONTINUE_SEARCH instead of handling the exception by raising a hard error popup. The NT kernel (not kernel32.dll) default "exception handler" then terminates the thread (NOT the process) because nobody handled the exception. Note that other threads will continue to run, assuming there are other threads in the process at the time of the unhandled exception (!), so use this option with care. Kernel32 provides the functionality of terminating the process on an unhandled exception. This may not be the case on Win9x, but it defiitely is true on NT.

    You can also perform similar handling by calling SetUnhandledExceptionFilter and reacting to unhandled exceptions accordingly.

    As for GetErrorMode: It turns out that there really is such a function in kernel32, but it just isn’t exported (who knows why). If you have valid symbols for kernel32, you can find it and see how it works…:

    0:001> u kernel32!GetErrorMode

    kernel32!GetErrorMode:

    77e4270d 55 push ebp

    77e4270e 8bec mov ebp,esp

    77e42710 51 push ecx

    77e42711 6a00 push 0x0

    77e42713 6a04 push 0x4

    77e42715 8d45fc lea eax,[ebp-0x4]

    77e42718 50 push eax

    77e42719 6a0c push 0xc

    0:001> u

    kernel32!GetErrorMode+0xe:

    77e4271b 6aff push 0xff

    77e4271d ff15b810e477 call dword ptr [kernel32!_imp__NtQueryInformationProcess (77e410b8)]

    77e42723 85c0 test eax,eax

    77e42725 7cd7 jl kernel32!GetErrorMode+0x1a (77e426fe)

    77e42727 8b45fc mov eax,[ebp-0x4]

    77e4272a a801 test al,0x1

    77e4272c 7505 jnz kernel32!GetErrorMode+0x2b (77e42733)

    77e4272e 83c801 or eax,0x1

    0:001> u

    kernel32!GetErrorMode+0x33:

    77e42731 c9 leave

    77e42732 c3 ret

    77e42733 83e0fe and eax,0xfffffffe

    77e42736 c9 leave

    77e42737 c3 ret

    Given this, it would be trivial to write your own implementation of such a function. Of course, this is completely undocumented and unsupported, so use it at your own risk. Especially since you don’t really need it.

  15. Reinder says:

    Incidentally, does the NT codebase still run on anything but x86?

    XBox 2? <http://www.theinquirer.net/?article=14407&gt;

  16. Steve Sheppard says:

    Aarrgghh: No, you succeeded, he was just being obtuse.

  17. Steve Sheppard says:

    DrPizza: I don’t necessarily disagree with the idea that MS should not constantly add in compatibility hacks. Unfortunately, that horse not only left the barn a long time ago but has since died of old age.

  18. ATZ Man says:

    Did the MIPS/RISC port of NT ship? ISTR hearing about it before hearing of the Alpha port.

  19. Skywing says:

    Given that the NT 3.51 DDK supports it, probably.

    Directory of C:WINDDK1057BIN

    06/30/2004 11:37 PM <DIR> .

    06/30/2004 11:37 PM <DIR> ..

    06/30/2004 04:28 PM <DIR> ALPHA

    06/30/2004 11:19 PM <DIR> I386

    06/30/2004 04:28 PM <DIR> MIPS

    06/30/2004 04:28 PM <DIR> PPC

  20. Cooney says:

    Larry Ostermann:

    > IA64 and AMD64 – each of which is different from x86

    I imagine that AMD64 handles unaligned access gracefully. I’d forgotten about IA64, but then, hasn’t everybody?

  21. Cooney says:

    Did the MIPS/RISC port of NT ship?

    I could swear that I saw ads for MIPS/NT workstations in my college computer store around 1995. There’s also this:

    http://www.microsoft.com/ntserver/partners/findoffering/certapp/ISupport.asp

  22. John Topley says:

    The Windows NT 4.0 CD-ROM came with binaries for i386, Alpha AXP, PowerPC and MIPS (R4000 I believe).

  23. Ben Cooke says:

    Interesting. So what happens if the program *does* GPF? Does it just vanish inexplicably?

  24. DrPizza says:

    (a) No skin off my nose.

    (b) How can that possibly be true? What is a hack such as this providing backwards compatibility with? Why would *any* Win32 implementation need this kind of a "fix"? The only way your comment makes any sense is if NT had this defect since day one.

  25. DrPizza says:

    "Did the MIPS/RISC port of NT ship? ISTR hearing about it before hearing of the Alpha port. "

    Versions of NT have shipped for x86, MIPS (R4K), Alpha AXP, CHRP-based PowerPC, and IA64. x86-64 is forthcoming but still in beta.

    It seems feasible that it may also have been built for i860 (i.e. the platform that it was meant to run on, and if the world was a sane place, /would/ have run on… x86 be damned), and it is rumoured to have been built and run on SPARC, though of course this never saw the light of day.

  26. asdf says:

    How about this, is there any way to test if your app is doing unaligned access on an x86?

  27. Skywing says:

    Yes, but it requires both messing around with Cr0 in either a driver or the kernel debugger and the usage of an undocumented native system call or two.

  28. DrPizza says:

    "DrPizza (b): All non-x86 processors require this to compensate for lazy programmers who think that x86 is the only processor in the world. More on this subject on August 25th. "

    That’s an absurd rationale.

    Even back in NT4’s cross-platform heydey, the only company making much of an effort at supporting the different processor families was MS themselves, and even then, they only provided any significant amount of support for the Alpha. Most x86 applications were never built for Alpha, so it would never be noticed if they broke on the Alpha.

    The rationale becomes even less true when looking at migrating from 32- to 64-bit platforms. There are *so* many things that can break your code, so why make an exception for this thing?

    Let programs break and people will fix them. If they don’t fix them, let their uses use shims to work around the programs’ defects. Yes, it’ll require user education, so that people stop pointing the finger at MS when some undocumented behaviour changes and breaks an application, but in the long run that’ll help everyone. Apart from anything else, it’ll reduce the amount of work MS has to do attempting to maintain compatibility with all these broken applications.

    Encouraging lazy developers who write broken applications does the platform no favours (as it means it becomes associated with buggy programs; chances are that the kind of Mort who cocks this up will cock up all sorts of other things too) and it does MS no favours (as it means they’ve got to insert all sorts of hacks into their code and make sure that all the broken applications still work).

  29. Norman Diamond says:

    7/27/2004 7:41 AM Raymond Chen:

    > DrPizza: With that attitude nobody would

    > have bought Windows 95.

    And the world would have been a better place. Windows NT was far more reliable. It is a huge relief that the home edition of Windows XP has a mostly-working kernel and moderately reliable drivers. Although XP has a way to go before matching NT’s reliability, it’s orders of magnitude better than 95. I only saw one person lose the entire contents of his disk partitions under XP and that was due to a virus instead of being due to the OS itself. In 95 it’s the OS itself and 100% reproducible. Absolutely right, no one should have bought 95, and no one should have had it forced on them when they wanted to buy the hardware and buy NT.

  30. We actually built a version of NT with alignment exceptions turned on for x86 (you can do that as Skywing mentioned).

    We quickly turned it off, because of the number of apps that broke :)

  31. asdf says:

    There is no prepackaged solution for this?

    So I need to enter kernel mode, set the AM flag in CR0, call some undocumented function(s), then back in usermode I need to set the AC flag in EFLAGS.

    What are the extra undocumented functions for? And once I set the AM flag in CR0, does that mean it’s a system wide, per process, or per thread setting?

  32. Skywing says:

    I don’t know of any way to turn it on without third party software (e.g. a driver).

    Enabling AM in CR0 tells the CPU to look at AC in EFLAGS if CPL=3 for purposes of raising alignment check exceptions or automatically fixing them.

    Each process in the system has a default auto alignment fix mode: whenever a thread is created in a process, it inherits the auto alignment fix mode of the process.

    Each thread in the system also, thus, has an auto alignment fix mode. If this is not set a certain way, NT will try to hide any alignment faults that the hardware happens to raise in the context of a given thread (presumably this is for architectures where the hardware does not provide for optional alignment faults).

    The NtSetInformationThread call tells NT to not hide any alignment faults that do happen by silently turning off AC in EFLAGS and retrying the instruction.

    All three of these need to come to pass for user mode programs to ever see alignment faults. So, yes, setting AM in CR0 affects all code running on the processor, but there are still two "safeguards" in place that would stop alignment faults from showing up (unless you explicitly disable those "safeguards" as the demo app does).

    Remember that since NtSetInformationThread is not documented, it could theoretically change at some time in the future (though AFAIK the part of it the sample uses has never changed in any shipping builds).

    You can use SetErrorMode to modify your process’s default auto alignment fix mode, but as I stated above this won’t change anything for already running threads (you would need to start a new thread after that, and then the new thread could see alignment faults if EFLAGS were properly set).

  33. asdf says:

    I swear I posted that previous message before I saw you posted the demo. This is exactly what I was looking for and many thanks for posting it.

  34. asdf says:

    Ah, spoke too soon – CreateWindow eventually calls a function that does a rep movs on an unaligned dword ptr. So much for testing this on an x86.

  35. Josh S. says:

    I was always a fan of the way the MFC ModifyStyle(…) function was designed because it was cleaner to use and helped prevent the kind of flag-overwriting you discussed here.

  36. Skywing says:

    I went ahead and wrote up a little demo app (http://www.valhallalegends.com/skywing/files/alignflt/alignflt.zip — source included) that enables alignment fault exceptions for x86-based NT systems. It ought to work on Windows 2000 and later (and would work on Windows NT 4.0 if you bothered to modify it a bit), but full multiprocessor support requires Windows Server 2003 because the function to send an IPI wasn’t exported prior to that.

    The sample involves the use of a driver (sorry, no way around it without a special build of NT like Larry alluded to). It’s fairly simple, what’s involved is this:

    – Call the driver to set the AM flag in CR0 for all processors. This can only be done from kernel mode, hence the need for the driver.

    – Call an undocumented function (NtSetInformationThread) to disable automatic alignment fault fixups for the current thread.

    – Set the AC bit in EFLAGS for the current thread, enabling alignment checks.

    Some observations:

    – You should be able to use SetErrorMode to enable alignment faults on x86 for *new* threads after calling the driver. However, this won’t modify the alignment fault mode for *already existing* threads. With this in mind, you could drop the undocumented bit if you really wanted to.

    – By default, threads will continue to have alignment faults disabled, so this shouldn’t break already-running programs.

    – Alignment faults are only possible in user mode due to hardware limitations (for x86). Don’t expect this to change anything for drivers.

    As the example program shows, if you trip an alignment fault, you will get a STATUS_DATATYPE_MISALIGNMENT exception.

    I suppose this could be useful if you wanted to do some profiling of a program you wrote (since unaligned accesses still do have a performance penalty associated with them, even if they don’t cause a hard crash on x86 NT by default).

  37. Chris Becke says:

    The messyness of the dual SetErrorMode call is the potential for a race condition on a multithreaded app on non x86 ahrdware.

    An ia64 app changed its error mode setting after createing worker threads could leave the system in a transient fault-on-unaligned access state – if a worker thread got hold of some CPU time…

  38. Norman Diamond – XP *is* NT 5.1. Home Edition has the same kernel as Professional. If by "NT" you mean NT4, I don’t know what data you’re basing your assertion on that XP is less reliable than NT4.

    And although I rarely defend Win95, it served its market much better than NT could have at the time. Memory was still expensive then – Win95’s minimum RAM was 4MB, while NT 3.x (which didn’t even have the Explorer UI) needed at least 12MB, IIRC. And it obviously took a LOT of work to come up with a good way to hide the complexity of NT from home users. Much as I’ve always preferred working with NT, I’ve always been impressed with how much the Win95 team managed to accomplish – completely new UI, pre-emptive multithreading (to a point:-), built-in multimedia and networking, binary compatibility with most NT apps and almost *all* DOS and 16-bit Windows apps, AND fit it into 4MB. The backward compatibility is what made it so unstable, but which also helped make it the right product at that time.

  39. mschaef says:

    "Much as I’ve always preferred working with NT, I’ve always been impressed with how much the Win95 team managed to accomplish "

    Yeah, Windows 95 was a remarkable product. It caught a lot of flack for not being "pure" (whatever that means), but MS did a good job of bringing lots of capabilities to the masses.

    As a side note, Andrew Schulman wrote a book, "Unauthorized Windows 95" that talks a lot about how the internals of the system work. In it he has a detailed discussion of the complexities of disk access works that describes control flow through the system after a disk request is made. Given all the hoops they had to jump through to support things like real mode disk I/O drivers, it’s amazing to me they got it working at all…

  40. Petr Kadlec says:

    Hmmm, unaligned memory access…wasn’t there some performance-monitoring-counter event for those? That might even work in usermode? And for just performance checking, this might even suffice. Maybe, just thinking aloud.

  41. Skywing says:

    The system supports accounting those types of faults, but by default (for x86) the hardware provides zero indicataion to the operating system about any of them (they are silently fixed by the hardware itself), so without the driver the counter would always be zero.

  42. Raymond Chen says:

    I did work on those problems and my Windows 95 machine rarely if ever bluescreened. Which I’m sure means nothing to you.

    Windows 95 breathed life into 32-bit Windows programming. Windows NT had been out for two years but most companies ignored it and continued writing 16-bit programs because most consumers were running Windows 3.1. Windows 95 made it worthwhile to write 32-bit programs for the masses.

    You may argue that Windows 95 did a bad job of running 32-bit programs, but that’s not my point. The point is that Windows 95 made writing Win32 programs a worthwhile endeavour.

  43. Norman Diamond says:

    7/28/2004 12:22 AM Aaron Margosis

    > Norman Diamond – XP *is* NT 5.1.

    Yes, I used to spell out Windows NT4 as NT4, but have gradually gotten used to Microsoft’s practice of no longer using the NT name for more recent versions and just using the NT name for NT4.

    > Home Edition has the same kernel as

    > Professional.

    No kidding, I said how valuable this is.

    > If by "NT" you mean NT4, I don’t know what

    > data you’re basing your assertion on that XP

    > is less reliable than NT4.

    In my experience, NT4 SP3 blue-screened only on machines that had no I8042 chip and only if I forgot to disable the I8042 driver prior to installing SP3. The Atapi driver for SP4 (fortunately available as a separate download) is needed to manage disk drives less than 6 years old, but there is no need to suffer problems caused by the rest of SP4, 5, 6, and 6a. One of these later SPs had a second reason for blue-screening, if a CD was inserted with a bad block.

    Windows 2000 blue-screens due to Microsoft-provided video drivers, TCP-IP drivers (mostly fixed but not fixed in SP2 as was asserted), and other random unknown reasons. Windows XP blue-screens less often than 2000, sometimes for known reasons and sometimes for unknown reasons. But XP still has a way to go before catching up to NT4 SP3.

    > And although I rarely defend Win95, it served

    > its market much better than NT could have at

    > the time.

    That’s an outright lie. Windows NT’s disk administrator did not create overlapping partitions on SCSI disks. Windows 95 did not serve anyone by doing that. No one benefits from losing the entire contents of their disk partitions. No market is served by that.

    Windows 95 by itself didn’t blue screen 15 times a day, maybe only once a day. To get 15 times a day, one had to use Word 95 on top of Windows 95. No one is served by this either. Anyone who wanted to get any work done had to use NT.

    Just imagine if Mr. Chen (and I assume some colleagues) had worked on these problems instead of making broken apps work. Windows 95 might have worked.

    > Memory was still expensive then

    No kidding, but losing disk partitions and getting 15 blue screens per day was not cheaper than spending 20,000 yen for additional memory.

  44. Norman Diamond says:

    7/28/2004 6:14 PM Raymond Chen

    > I did work on those problems and my Windows

    > 95 machine rarely if ever bluescreened.

    > Which I’m sure means nothing to you.

    It means Microsoft did a lot less testing than Microsoft customers had to do (and still have to do). Whether this meaning is "nothing" or not, well, I’m not quite sure what you mean by that.

    You along with everyone in your company seem genuinely unaware of how much damage is caused by defects in your company’s products. Perhaps we should meet sometime so I can show you. At least one item that took months to track down can be duplicated in 10 minutes now.

    > Windows 95 breathed life into 32-bit Windows

    > programming.

    Windows 95 breathed both life and death into it. The amount of damage far outweighed the benefits. NT4 was harder to administer and harder to program for, but that wasn’t the reason for having fewer developers. Customers who wanted to buy hardware with NT4 had to pay twice for OSes, we didn’t get the option of not paying for 95. So the marketplace stayed with 95 instead of NT4. The marketplace was not served by this.

    > You may argue that Windows 95 did a bad job

    > of running 32-bit programs

    Mostly no (though we know ways in which that is true). Mostly I am arguing that Windows 95 did a bad job of running itself.

    By the way there were a couple of bugs in my memory in my previous posting here. Word 95 on top of Windows 95 didn’t cause 15 blue screens per day. Word 97 on top of Windows 95 did more than Word 95. But the biggest change around that time was that Internet Explorer became part of the OS, IE version 4 became usable for the length of time between booting and blue screening, and when in use it did cause quite a lot of blue screens. So the real cause of Windows 95 blue screening 15 times per day was more likely Internet Explorer with help from Word 97.

    Consider how frequently Windows 2000 closed down Internet Explorer due to IE trying to access invalid memory locations, both reads and writes. Think about the damage the same IE bugs did to the kernels in W95 and W98 with no memory protection.

  45. DrPizza says:

    "Consider how frequently Windows 2000 closed down Internet Explorer due to IE trying to access invalid memory locations, both reads and writes. "

    Infrequently, and normally due to plugins rather than IE itself.

    "Think about the damage the same IE bugs did to the kernels in W95 and W98 with no memory protection. "

    Er… what kernels are they?

    The Win9x kernels did have memory protection (albeit with a big chunk of shared memory).

  46. Mystique says:

    Okay, here’s a suggestion. Rigorously disable all compatibility hacks for native 64-bit apps. I’ll explain:

    Granted, Windows XP 64-bit edition needs binary compatibility with 32-bit apps, and these generally rely on bugs and hacks and workarounds that were present back since DOS 1.0, as Raymond elaborately explains and illustrates again and again.

    Now my idea: native 64-bit apps need to be recompiled from scratch anyway. There’s no chance that any end user will want to execute a 64-bit app that was exclusively compiled and tested against Windows 95. 64-bit apps can’t be executed on a 32-bit OS anyway. So, for 64-bit apps, disable all the compatibility hacks that Raymond has ever talked about.

    This is both safe (if a software vendor’s freshly sold 64-bit app breaks, only he will get the blame) and good (because compat. hacks are *evil*, albeit a necessary one).

    Mystique out.

  47. Norman Diamond says:

    7/30/2004 5:29 AM DrPizza (responding to me)

    >> Consider how frequently Windows 2000 closed

    >> down Internet Explorer due to IE trying to

    >> access invalid memory locations, both reads

    >> and writes.

    >

    > Infrequently,

    "Infrequently" like an average of once a day, but sometimes higher. When IE 5.5 SP2 came out with a feature to report errors to Microsoft, I let it send off about 50 to Microsoft within the first two weeks. (The US version of IE had it in 5.5 SP1 if I recall correctly.)

    > and normally due to plugins rather than IE

    > itself.

    Well, you could be right, but how can anyone other than Microsoft know that? Occasionally when Windows asked if I wanted to debug IE I pretended to want to do so, but couldn’t see much of use in the disassembly. If IE happily tried to execute garbage that was fed to it by invisibly installed and invisibly executed plugins, then it still seems IE is the primary contributor. The only binary that I intentionally executed in those cases was IE.

    >> Think about the damage the same IE bugs did

    >> to the kernels in W95 and W98 with no

    >> memory protection.

    >

    > Er… what kernels are they?

    The Windows 95 kernel and the Windows 98 kernel.

    An aside here to Mr. Chen: Where you have seen problems with PSS or with Office developers or with code that Microsoft built into Windows CDs that perhaps was submitted to Microsoft by other makers, Microsoft customers do not see PSS or Office developers or outside code. In these cases Microsoft customers see Microsoft.

Comments are closed.