What about critical sections? There is no "Uh-oh" return value for critical sections; EnterCriticalSection doesn't have a return value. Instead, the kernel just says "Open season on critical sections!" I get the mental image of all the gates in a parking garage just opening up and letting anybody in and out.

In Windows Vista, the gates don't go up. Instead they become electrified!

If during DLL_PROCESS_DETACH at process termination on Windows Vista you call EnterCriticalSection on a critical section that has been orphaned, the kernel no longer responds by just letting you through. Instead, it says, "Oh dear, things are in unrecoverably bad shape. Best to just terminate the process now." If you try to enter an orphaned critical section during process shutdown, the kernel simply calls TerminateProcess on the current process!

It's sort of like the movie Speed: If the thread encounters a critical section that causes it to drop below 50 miles per hour, it blows up.

But it also illustrates how the details of process shutdown are open to changes in the implementation at any time, so you shouldn't rely on them. Remember the classical model for how processes exit: You cleanly shut down all your worker threads, and then call ExitProcess. If you don't follow that model (and given the current programming landscape, you pretty have no choice but to abandon that model, what with DLLs creating worker threads behind your back), it's even more important that you follow the general guidance of not doing anything scary in your DllMain function.

I’m a little shocked (no pun intended…or is it?) to hear about the electrification of critical sections on process exit. I can imagine at least one scenario where the forced termination of the process might lead to data corruption in a file. But I suppose it’s generally better to terminate the application in case something might go wrong than to have an access violation dialog appear when you close the application.

P.S. There are two links to the Simpson’s wiki in your article that are broken because they use ‘hef’ instead of ‘href’ in the anchor tags. I only noticed them because I accidentally bumped my mouse and the pointer hovered over one of the links.

It’s a shame those DLLs don’t expose a means to clean up their threads. I remember reading something about the CLR, that said .Net solved this problem for CLR threads by marking them with a "strong" or "weak" value, and allowing the process to exit after all "strong" threads had exited. But I don’t rememebr where I read that exactly.

PS: Also, there’s the problem of COM components failing to properly call SHGetInstanceExplorer() when they create worker threads. Such as Windows’s own ZipFldr.dll, as it seemed when I tried to use it from a console application.

Now, if only Vista on session logout allowed applications to show their “Save: Yes, No, Cancel” dialogs (like XP does), instead of putting that dreaded shadow screen with scary words about a hung application…

[Now if only people would realize that the topic is a kernel-mode view of how processes terminate, not a discussion of the system shutdown user experience. Oh wait, complaining about Vista is always on-topic around here. -Raymond]

This reminds me of a boss I had – he basically told a bunch of us to always design apps for exit behavior. I suppose that if you don’t think about it up front, the natural tendency is for process shutdown to resemble a hotel demolition. Now, even more so.

@Tom: If an application needs to do work to properly save a file, it should do so before calling ExitProcess() or exiting winmain. It’s silly to design your system such that your DllMain() handler does mission critical work.

This is too much off-topic but I’ll try to sneak it anyway. Because I am a back-office guy (think of WMI providers, services, a little kernel-mode programming, stuff like this), when you talk to DllMain and friends I yawn, because there’s nothing new for me to learn. Will you please, please, please consider again writing articles about GUI stuff? I know that you have articles written for months in advance, but maybe you can reschedule something gui-related for publishing sooner. Pretty please?

[It’s easier writing about non-GUI stuff because when I write GUI stuff people expect to see sample code, and writing sample code is a lot of work. Whereas when I write about non-GUI stuff, I can just talk about code in a more general sense and nobody expects me to write a sample program that illustrates the topic. -Raymond]

do you have any idea why this detail was changed? Was it just a side effect of some other change or a conscientious decision? (A quick guess is that the new way might speed up the termination of not properly coded threads.)

Ben: The typical reason for trying saving a file from DllMain is when a DLL needs to write a diagnostic log file. If you write to the file on every function call, you could end up hitting the disk (or network) thousands of times per second, so instead you buffer your log messages and write them to disk only when the buffer is full. The only problem is then to flush the buffer and close the file when your DLL is unloaded.

Just CreateFile with default (cached) mode, and issue WriteFile for each log line. It won’t hit a disk for every call. Bonus point: If you open the file in APPEND mode (pass SYNCHRONIZE|APPEND to CreateFile instead of GENERIC_WRITE), you can write to the same file from separate processes (separate handles) without any synchronization.

1. The Open/Save dialog that actually *shows* me where in the file system I am. Epic Win. Nothing else to be done in Vista, that would be enough to release it.

2. The "Favourites" links at the top-left corner of Explorer, which are customisable with simple drag-drop. Epic Win.

3. The per-application volume control. Epic Win.

4. The new glossy shiny pretty icons

5. The search in the start menu

6. The search in control panel

7. The iSCSI control UI

8. The setupapi.dev.log – thank you, whoever designed and implemented it

9. UAC – finally I could browse felling more secure

10. The default sounds that were so good, that for the 1st time since Windows 3.0 era I kept them

11. The ARP panel which doesn’t block while the uninstaller is running, taking half the desktop real estate hostage

12. IE7 which was tolerable, instead of extremely awful as IE6 was

13. PowerShell. The CLI is unbearable, but the script language is awesome and it indeed has access to every corner of Windows so it is an epic win

14. The new network redirector/server/cleint. yeah before SP1 it broke byte range locks, so that even Access was corrupting its DB files, but watching how files transfer in seconds instead of half an hour was incredible

15. The new login screen, which was quite nice to the eye

16. The boot speed

17. the hybrid sleep, an epic win

18. kernel mode transactions. they are a game changer

19. the DWM which although all its inefficiencies (after all every software in its version 1 sucks) was an epic win both in usability and eye-candy

20. the gorgerous new wallpapers

21. the virtualization of registry/fs which fixed so many broken programs without messing with the OS

22. the new component based OS module setup system, which means I do not need to search the damned disks when I want to install something

23. the Windows Update UI which didn’t block the whole browser

24. the fact that open/save dialogs are mini-explorers so you can do everything from there (including hosting broken shell extensions :-D)

25. The new Task Scheduler, which

25.1. has much better UI with richer functionality

25.2. implements IDispatch so actually is usable by WSH

26. The new interface and xml-based export/import functionality of Event Viewer

27. The new Manage Computer MMC UI

28. The responsiveness

29. Superfetch

30. The Windows Firewall UI

31. The Volume Snapshot system which stopped sucking

32. The System restore based on p30 above

33. The WMI service which miraculously stopped corrupting its repository every 40 min

34. The Performance Monitor

35. The Task Manager

36. Session 0 isolation

37. Mandatory Access Controls ( can’t remember the official name right now, it’s well past midnight local time)

38. The most used keyboard layout for my country, included by default for the very first time since Windows exists!

39. The new fonts

40. The heap manager, which for first time in Windows history doesn’t suck

41. The virtually unlimited resources in kernel mode – the non-paged pool could be up to the whole physical memory minus handful of pages

42. doesn’t suffer badly when a program opens more than 100 handles to kernel objects

43. The WAIK that allows me to put any driver/program/setting into the setup media of Windows just like that

44. The clock in the notification area

45. The Bluetooth UI

46. The Wi-Fi UI

I guess you get the idea

Things I truly hate in Vista:

1. The Network Centre – it was a disaster, 3 years later I still cannot understand how to use it, I just blindly click on every link till I stumble on something that looks familiar enough – fixed in 7

2. The loss of the drag-and-drop to a console app – fixed in 7.

3. The broken nVidia drivers – you will not be surprised to learn that I blame MS for them, won’t you? I really find it an extra-human feat that such complex beasts can work with kernel interfaces designed in NT 3.1 era for then contemporary video cards. Oh, and the under-documented Windows kernel doesn’t help much.

But all in all, it wasn’t a very satisfactory release – you definitely could put more bad things into it, so I have more things to complain about! Now just 3 – where is the fun in it?

There are many good improvements in Vista and then in Win7. Some things are released undercooked, understandably. And there are things that were just broken. If people would not bitch about them, those things will remain broken forever. Take, for example, new help. It seems it’s using fulltext search instead of keywords. Thus, the results return so much noise, it becomes unuseable.

Another example. Win7 and Vista SP1 got new exFAT filesystem optimized for USB flash and other removeable media. Unfortunately, it was not backported to XP. Thus, I and many others will be very reluctant to use it.

Alexandre Grigoriev: Just appending to a file isn’t going to work for log files with sessions, like setupapi.dev.log (#8 on Teo’s list of improvements). When I first implemented the setupapi.log in 1998, I was reluctant to group log statements by session because I thought that appending would be faster and more robust. However, as Teo makes clear, the current format is so much easier to use that it’s worth the overhead.

So how do you implement per-sesson logging? You can either buffer all the messages and append them at once when the session ends, or do this for every message: lock the file; read it backwards until you find the beginning of your session; rewrite the sessions following yours; write out your session including the new log entry; and finally, unlock the file.

Of course setupapi is doing driver installs that could crash the machine, so it has to log the slow way, but it should be clear that there is definitely merit to the first method.

Re: Logging per session – Prefix each line with per-session unique ID (open time timestamp or like that), and per-session record number, and just append the lines for all sessions to the same file. Then, when you look at the file and want them grouped per session, either do grep, or simply sort the file.