Volume 1, Number 2


May 15, 1999 - In this issue:

        - SDelete
        - BlueScreen Screen Saver Win2K Update
        - “Linux and the Enterprise”
        - "Inside NT Utilities"
        - My May Windows NT Magazine Column
        - Not-So-New Stuff

        - Dr. GUI’s Poor Bedside Manners
        - WinDev ’99 East
        - Numega Driver Works Release Imminent
        - Beta 3 DDK Released
        - Win2K Queued Spinlocks

        - Win2K System File Protector (SFP)
The Systems Internals Newsletter is sponsored by Winternals Software, on the Web at
http://www.winternals.com. Winternals Software is the leading developer and provider of advanced systems tools for Windows NT/2K. Winternals Software products include FAT32 for Windows NT 4.0, ERD Commander (boot-disk capability for Windows NT), and NTRecover.


Hello everyone,

Welcome to the second edition of the Systems Internals newsletter. The newsletter currently has 2700 subscribers, with subscriptions still going strong.

Since the last newsletter Microsoft has officially released Windows 2000 Beta 3.  The build number of the Beta 3 kernel is 2031, while that of NT 4.0’s initial release kernel was 1381 and NT 3.51 had a build number of 1025. . What I find odd (and somewhat annoying), is that Microsoft increments the build number each time they do a full build of the operating system (every work day), however, the reported build number of the kernel reflects that of its initial public release. For example, even though the actual build number of the NT 4.0 Service Pack 5 kernel is much higher than 1381, the kernel still reports 1381 as the build number.

The Beta 3 release of Windows 2000 is intended to be a wakeup call for the developer community. Microsoft has announced that it will ship Windows 2000 in October, and that Beta 3 represents the feature-complete version of what will ship, so developers can begin writing new products without fear that things will change out from underneath them.

Windows 2000 comes with a slew of new APIs, layered services, and kernel enhancements. One change that will be especially visible to device driver developers is that the Blue Screen of Death (BSOD) has changed. In previous versions of NT, the BSOD displayed link-time and load address information for all the drivers on a system, as well as a dump of the stack as it exists at the time of the crash. In Windows 2000 only the stop code and associated address line(s) (address lines translate one or more of the stop-code parameters into locations within device drivers) are shown, along with a verbose message. The support message suggests that you check your BIOS and hard drive settings, and disable defragmenting software and virus scanners to try to avoid getting the crash again.  Microsoft Premier Support Services (PSS) determined, based on their experience and on customer feedback, that the NT 4-style BSOD is not useful for determining the cause of a crash.

I personally found the loaded driver list, and in particular the stack dump, to be useful when getting driver bug reports from users  it’s a lot easier and faster to get this information than to have users to send a multi-megabyte crash dump. I’ve often isolated the cause of crash based on the stack dump, and verified driver versions that users have loaded based on the version information displayed in the driver list. I’m curious to know what you think: would you like to see the NT 4-style BSOD carried forward to Windows 2000, or is the new BSOD format sufficient? Send me an e-mail if you have an opinion. I’ll report the results of this informal poll in the next newsletter. While I’m on the subject of BSODs, be sure to check out the Windows 2000 update of the ever-popular Systems Internals BlueScreen Screen Saver, which is covered in this issue.



========== WHAT'S NEW AT SYSTEMS INTERNALS ==========

As part of Windows NT 4.0 fulfilling C2 security rating requirements, it implements “object reuse protection”. This means that NT zeroes file and memory resources applications allocate when the applications access the resources for the first time. This prevents an application from, for example, creating a large file and examining its contents to see what was previously stored on disk. However, object reuse protection does not extent to protecting resources that are accessible by applications that bypass standard resource-related APIs, or that bypass the operating system altogether. For instance, you can use a disk editor, such as the Resource Kit’s DiskProbe, to examine the contents of unallocated portions of a disk. This enables you to see data that previously belonged to deleted files.

Many environments require a “secure delete” capability. This feature enables users to permanently delete sensitive data so that it is not visible by tools that bypass operating system protection facilities. The advent of the Encrypting File System (EFS) has highlighted the need for a secure delete facility in Windows 2000. When you encrypt a previously unencrypted file, EFS does not erase the contents of disk allocations that contained the file’s unencrypted data when it frees the disk allocations. Thus, even though the active version of a file you encrypt is secure, the old version of the file still exists in the unallocated portions of a disk until it happens to be overwritten by new file data that NTFS assigns to those portions.

In order to fill this hole, I’ve written SDelete (Secure Delete). It’s a command-line tool that makes it possible not only for you to securely delete standard files, but also to securely delete any previously deleted data that exists in the unallocated portions of a disk. In addition, it works with Windows NT/2000 compressed, encrypted and sparse files, something that requires use of the defragmentation API. SDelete adheres to the Department of Defense clearing and sanitizing standard DOD 5220.22-M, so that you can be sure that once you delete data, its gone forever.

I provide SDelete with full source code and a description of how it works, so that you can see how it makes use of the defragmention API, and so that you can verify my claims that it will prevent your sensitive deleted data from being recoverable.

You can find documentation on the Windows NT/2000 defragmentation API at
http://www.sysinternals.com/defrag.htm. Download SDelete with full source code at http://www.sysinternals.com/sdelete.htm.

The changes Microsoft has made to the NT startup screen and Blue Screen of Death (BSOD) layout in Windows 2000 made the Systems Internals BlueScreen Screen Saver require a major update. In order to continue providing you with the utmost in BSOD realism, I’ve released version 2.0 of the screen saver. It not only reflects the changes to the BSOD format, but also precisely mimics the Windows 2000 startup screen, complete with rotating progress stripe and progress bar updates. It’s so real that the screen saver will fool even Windows 2000 expert users and developers. Of course, under NT 4.0 BlueScreen Screen Saver still presents the NT 4.0 BSOD and startup screens.

How did I recreate the Windows 2000 startup screen so perfectly and at the same time not violate copyright laws? I don’t include the Windows 2000 startup bitmap graphics with the screen saver. Instead, I use DirectX to switch the graphics mode to the same used by Windows 2000 during the startup sequence, and then I reference the bitmap resources of the Windows 200 kernel file, ntoskrnl.exe. These resources (you can view them by opening the resources of ntoskrnl.exe in Visual Studio) are the ones that the kernel displays, which is a change from the Windows 9x way of doing things where startup graphics are actually separate files. It doesn’t look like computer OEMs will be given the opportunity to customize the startup experience in Windows 2000…

You can download the BlueScreen screen saver at
http://www.sysinternals.com/bluescreen.htm. If you have a humorous story related to fooling someone with the screen saver, please pass it along.

You can find out more information about the how’s and why’s of BSODs in my December 1997 Windows NT Magazine NT Internals column, “Inside the Blue Screen”. A link on the Systems Internals Publications page,
http://www.sysinternals.com/publ.htm, will take you to the on-line version of that column. The page also contains links to other on-line presentations of articles and columns I’ve authored.

The enormous response of the Linux community to my article in the April issue of Windows NT Magazine about the scalability deficiencies of the Linux  kernel has prompted the magazine to post the on-line version of the article ahead of schedule. You can find a link to the article, “Linux and the Enterprise”, in the “Articles” section at
http://www.sysinternals.com/publ.htm. The article describes several limitations of the current release of the Linux kernel (2.2x), including a lack of an efficient event-waiting mechanism, significant system-call serialization, no asynchronous I/O, and a poor implementation of the sendfile (in NT its called TransmitFile) socket API. The combination of these limitations prevent Linux from competing head-to-head with NT and other UNIXs, in terms of performance, on enterprise-class applications like web servers, database servers, and e-mail servers.

If you’ve used Filemon, Regmon, or HandleEx, and wanted to know more about what they tell you and how they are implemented, then you’ll be interested in my February Windows NT Magazine column, “Inside NT Utilities.” This column describes the internals of these tools, and for Regmon and Filemon, tells you a little bit about the error codes and request types that they log while capturing Registry or file system activity. A link to the on-line version of this article, which has just become available, is located at http://www.sysinternals.com/publ.htm.

 Have you ever wondered how Windows NT/2000 organize the Registry’s contents in-memory or on-disk? The current (May) issue of Windows NT Magazine includes my column, “Inside the Registry”, which tells you this and more. For instance, learn how the Configuration Manager kernel-mode subsystem (the subsystem responsible for managing the Registry) looks up keys, stores value data, optimizes searching, and protects the integrity of the Registry on-disk files. Windows NT Magazine, http://www.winntmag.com, is available at Borders and Barnes and Nobles.

 Not long after Windows 2000 Beta 2 was released, I took the Checked (debug) build of the kernel image file (ntoskrnl.exe), did a string search on the kernel, and came up with a list of the names of source files used to build the kernel. The Checked build of the NT/2000 kernel contains numerous Assert statements (consistency checks) that include the file name of the file in which the Assert is located.  Assuming that virtually every file of any significance in the kernel source will have at least one Assert in it, the list is fairly comprehensive. Dumping the list into a Java script gave me a nice Explorer-like treeview of the directory structure of the Windows 2000 source tree. Check it out at http://www.sysinternals.com/nt5src.htm.
================== INTERNALS NEWS =================

 In the March/April issue of Microsoft Developer Network News Dr. GUI fields a question from a reader that asks how a driver can affinitize (force to use a specific CPU) its threads. Dr. GUI responds that there is no way to determine the number of processors on a system from a driver, and that a driver thread cannot tell what processor it is running on. Unfortunately, Dr. GUI blew this diagnosis (maybe Dr. GUI should stick to GUIs).

The NT kernel (ntoskrnl.exe) exports a variable named KeNumberProcessors that is defined in NTDDK.H as:

extern PCCHAR KeNumberProcessors;

It can be directly referenced in a driver like this:

        CHAR    i;
        for( i = 0; i < *KeNumberProcessors; i++ ) {

                // do processor specific stuff

To determine which processor a driver thread is running on, use KeGetCurrentProcessorNumber(), another kernel export that is not only defined in NTDDK.H, but is actually documented in the DDK!

Dr. GUI prescribed the wrong medication for this ailment, so I politely let the Dr. know via a polite e-mail. Surprisingly, Dr. GUI never even acknowledged the e-mail. We'll see if the good Dr. fesses up to the error in the next issue…

The 1999 East Coast edition of the premier conference for Windows developers is fast approaching. WinDev ’99 East is taking place June 14-18 at the Boston Cambridge Marriot. A number of big names in Windows development are speaking, including Jeff Richter, Jeff Prosise, and Don Box. I’ll be there with Jamie Hanrahan and Brian Catlin in the device driver’s track. My presentations include a day-long tutorial on NT internals, as well as one on writing Windows NT/2K file system drivers and one on advanced device driver development issues.  Come and say hello!

Compuware NuMega Labs is on the brink of releasing a powerful new Windows 9x/NT/2K device driver development kit, DriverStudio. DriverStudio combines all of NuMega’s existing device driver tools, including DriverAgent, DriverWorks, SoftICE, and VtoolsD, and adds the new BoundsChecker for drivers and FieldAgent (Windows NT/2K only).

The device driver version of BoundsChecker provides comprehensive monitoring of every kernel API your driver uses, and you can use it to monitor your driver’s interactions with any other device driver on the system. FieldAgent lets you deploy the driver version of BoundsChecker to client systems so that clients can collect traces for you that you can analyze. Coming soon as a free update for DriverStudio customers are TrueTime for drivers, and TrueCoverage for drivers, tools that enable you to easily performance tune and coverage test your device drivers.

This package is the ultimate driver development kit, and I heartily recommend it (I’m on the Beta program). Find out more at http://www.numega.com.

In conjunction with the release of Windows 2000 Beta 3, Microsoft has made available for free download the Windows 2000 Beta 3 DDK (Device Driver Kit). You can grab the DDK at http://www.microsoft.com/ddk/ddk2kb3.htm. I’m hoping that the SDK will follow soon, as there are a number of Win32 APIs in Beta 3 that are not documented as of the April edition of MSDN.

Windows 2000 uses a new type of spinlock called a “queued spinlock” for its global locks. The global locks in Windows 2000 are the same as those for Windows NT 4.0, and include:

       - KiDispatcherLock: the scheduler database lock
       - KiContext-SwapLock: the tread swap lock
       - MmPfnLock: the physical page frame database lock
       - MmSystemSpaceLock: the kernel-mode address space lock
       - CcMasterSpinLock: the Cache Manager's global spinlock
       - CcVacbSpinLock: the Cache Manager's mapping-array lock

On a uniprocessor queued spinlocks work exactly like normal spinlocks. On the multiprocessor build of NT, however, queued spinlocks are significantly different. Like standard spinlocks, queued spinlocks are implemented in the HAL. Tthe kernel calls the HAL function KeAcquireQueuedSpinlock to acquire a queued spinlock, and it invokes KeReleaseQueuedSpinlock to release a queued spinlock. KeAcquireSpinlock and KeReleaseSpinlock, the HAL functions the kernel uses to acquire and release standard spinlocks, require the address of the specified spinlock as a parameter. By contrast, the queued spinlock functions take the index number of a global spinlock. The kernel initializes the global spinlocks in an array, where each spinlock has a predefined index number that the kernel uses to identify them to the HAL. Thus, queued spinlocks cannot be defined and used by device drivers, since there is no way of augmenting the global queued spinlock array.

In Windows 2000, each processor control region (PCR) in an SMP (there is one PCR for each processor) has an array with as many entries in it as there are queued spinlocks. Each array entry contains two fields: a pointer to the queued spinlock it corresponds to (the “spinlock” field), and “queue” field. In the following description, when I refer to the spinlock and queue fields, I’m talking about the fields associated with the array entry for the spinlock that is being acquired or released.

KeAcquireQueuedSpinlock works like this: the function attempts to acquire the spinlock by using the interlocked-exchange CPU instruction to place the address of the current processor’s PCR in the spinlock. If the spinlock is held, the function has, as part of the exchange operation, the address of another processor’s PCR. Then the function identifies itself as “waiting” by toggling the low bit of the spinlock field in its own PCR. Next, it places its own PCR’s address into the queue field of the PCR that it retrieved from the spinlock. Finally, it waits in a busy loop until the low bit is toggled off in its spinlock field  when the bit is off then the current processor has been granted the spinlock and so it returns to caller of the acquire function.

After a processor has acquired a queued spinlock and finished the processing it wanted to do while holding the lock, it calls KeReleaseQueuedSpinlock. KeReleaseQueuedSpinlock looks at the queue field for the specified spinlock in the current processor’s PCR. If the queue field is non-zero, then another processor has “queued” its PCR there. KeReleaseQueuedSpinlock clears the low bit of the spinlock field for the waiting PCR, and then clears its own queue field and returns. By clearing the low bit in the waiting PCR’s spinlock field it has just signaled the next CPU in line that it can have the lock. If the queue field was zero, then no other processor is waiting for the lock and KeReleaseQueuedSpinlock simply performs an interlocked exchange operation to clear the global spinlock.

The operation of queued spinlocks is one where processors “line up” waiting for a spinlock that is held. Each processor queues itself by telling the one ahead of it in line that it is waiting. This provides a deterministic ordering to the acquisition of a queued spinlock  processors acquire the spinlock in the order that they request it. For standard spinlocks there is no such ordering. Queued spinlocks have another more significant advantage. As a processor spins waiting for its spinlock field to have the low bit cleared, it is spinning on memory private to its own processor. When a processor busy waits for a standard spinlock it spins on the global spinlock itself, which is shared by all the processors. Thus, queued spinlocks have better multiprocessor bus characteristics because there is no shared cache-line access during the busy wait. In addition, because of the queuing nature of queued spinlocks, there are typically fewer bus lock operations than for standard spinlocks when a lock is under contention from several processors.

Queued spinlocks are one of several enhancement Microsoft has made the multiprocessing scalability of Windows 2000.

================ WHAT'S COMING UP =================
Windows 2000 includes numerous features that make it more resilient to operator errors and misbehaved applications. One of them is that many of the DLLs and drivers under the %systemroot%\system32 and %systemroot%\system32\drivers directory are protected by a watchdog called the System File Protector (SFP). You can verify its existence by going into that system32 directory and renaming ntoskrnl.exe. The watchdog will wakeup and notify you that it detected tampering with a protected system file and is repairing it. If you check the directory again you’ll find ntoskrnl.exe has been magically replaced. Next time I’ll tell you how this works.
Thank you for reading the Systems Internals Newsletter.

Skip to main content