Software Development in Windows
Though this book focuses primarily on the post-Vista era of Windows, it's useful to look back at the history of Windows releases, because the roots of several building blocks of the underlying architecture can be traced all the way back to the Windows NT (an abbreviation for “New Technology”) operating system. Windows NT was first designed and developed by Microsoft in the late '80s, and continued to evolve until its kernel finally became the core of all client and server versions of the Windows operating system.
Windows Release History
Windows XP marked a major milestone in the history of Windows releases by providing a unified code base for both the business (server) and consumer (client) releases of Windows. Though Windows XP was a client release (its server variant was Windows Server 2003), it technically succeeded both Windows 95/98/ME (a lineage of consumer operating systems that find their roots in the MS-DOS and Windows 3.1 operating systems) and Windows NT 4/Windows 2000, combining for the first time the power of the Windows NT operating system kernel and its robust architecture with many of the features that had made Windows 95 and Windows 98 instant hits with consumers and developers alike (friendly user design, aesthetic graphical interface, plug and play model, rich Win32 and DirectX API sets, and so on).
Though both the server and client releases of Windows now share the same kernel, they still differ in many of their features and components. (For example, only the server releases of Windows support multiple concurrent remote desktop user sessions.) Since the release of Windows XP in 2001, Windows Server has followed a release cycle that can be loosely mapped to corresponding Windows client releases. Windows Server 2003, for instance, shares many of the new kernel and API features that were added in Windows XP. Similarly, Windows Server 2008 R2 represents the server variant of Windows 7, which was released in late 2009. (Don't confuse this with Windows Server 2008, which is the server variant of Windows Vista.)
Figure 1-1 illustrates the evolution of the Windows family of operating systems, with their approximate release dates relative to each other.
Figure 1-1 Timeline of major client and server releases of the Windows operating system since the early 90s.
Supported CPU Architectures
Windows was ported to many CPU architectures in the past. For example, Windows NT supported Alpha and MIPS processors until Windows NT 4. Windows NT 3.51 also had support for Power PC (another RISC family of processors that is used in many embedded devices, including, for example, Microsoft Xbox 360). However, Windows later narrowed its support to three CPU architectures: x86 (a 32-bit family of processors, whose instruction set was designed by Intel), x64 (also known as AMD-64, in reference to the fact this architecture was first introduced by AMD, though Intel also now releases processors implementing this instruction set), and ia64 (another 64-bit instruction set designed by Intel in collaboration with Hewlett-Packard).
Microsoft shipped the first ia64 version of Windows XP in late 2001 and followed it with an x64 version in 2005. Microsoft later dropped support for ia64 on client editions, including Windows XP. The x86, x64, and ia64 architectures supported in Windows Server 2003 and Windows XP are exactly those that were also supported when Windows Server 2008 R2 and Windows 7 shipped at the end of 2009, though x86 and x64 are clearly the more widely used Windows architectures nowadays. Note, however, that Windows Server no longer supports x86; it now supports only 64-bit architectures. Also, Microsoft announced early in 2011 that its upcoming release of the Windows operating system will be capable of running on ARM (in addition to the x86 and x64 platforms), a RISC instruction set that's widely used in embedded utilities, smartphones, and tablet (slate) devices thanks in large part to its efficient use of battery power.
Understanding the underlying CPU architecture of the Windows installation you are working on is very important during debugging and tracing because you often need to use native tools that correspond to your CPU architecture. In addition, sometimes you will also need to understand the disassembly of the code you are analyzing in the debugger, which is different for each CPU. This is one reason many debugger listings in this book also show the underlying CPU architecture that they were captured on so that you can easily conduct any further disassembly inspection you decide to do on the right target platform. In the following listing, for example, the vertarget command shows a Windows 7 AMD64 (x64) operating system. You'll see more about this command and others in the next chapter, so don't worry about how to issue it for now.
lkd> $ Multi-processor (2 processors or cores) Windows 7 x64 system lkd> vertarget Windows 7 Kernel Version 7600 MP (2 procs) Free x64 Built by: 7600.16385.amd64fre.win7_rtm.090713-1255
Given the widespread use of x86 and x64, and because you can also execute x86 programs on x64 machines, the majority of experiments in this book are conducted using the x86 architecture so that you can follow them the way they're described in this book regardless of your target architecture. Though x86 has been the constant platform of choice for Windows since its early days in the '80s, 64-bit processors continue to gain in popularity even among home computers and laptops, which now often carry x64 versions of Windows 7.
Windows Build Flavors
The vertarget debugger command output shown in the previous section referred to the Windows version on the target machine as a “free” (also known as retail) build. This flavor is the only one ever shipped to end users by Microsoft for any of the supported processor architectures. There is, however, another flavor called a “checked” (also known as debug) build, which MSDN subscribers can obtain from Microsoft if they want to test the software they build with this flavor of the Windows operating system. It's important to realize that checked flavors are mostly meant to help driver developers; they don't derive their name at all from being “tested” or otherwise “checked” more thoroughly than the free flavors.
If you recall, the Introduction of this book recommended using the Driver Development Kit (DDK) build environment if you wanted to recompile the companion C++ sample code. As was explained then, you can also specify the build flavor you want to target (the default being x86 free in the Windows 7 DDK) when starting a DDK build environment. This is, in fact, also how the checked flavor of Windows is built internally at Microsoft because the same build environment made available in the DDK is also used by Windows developers to compile the Windows source code. For example, the following command starts a DDK build environment where your source code is compiled into x64 binaries using the checked (chk) build flavor. This essentially turns off a few compiler optimizations and defines debug build macros (such as the DBG preprocessor variable) that turn on “debug” sections of the code, including assertions (such as the NT_ASSERT macro).
C:\DDK\7600.16385.1>bin\setenv.bat c:\DDK\7600.16385.1 chk x64
Naturally, you don't really need a checked build of Windows to run your checked binaries, and the main difference between your “free” and “checked” binaries is that the assertions you put in your code will occur only in the “checked” flavor. The benefit of the checked flavor of Windows itself is that it also contains many additional assertions in the system code that can point out implementation problems in your code, which is usually useful if you are developing a driver. The drawback to that Windows flavor, of course, is that it runs much slower than the free flavor and also that you must run it with a kernel debugger attached at all times so that you can ignore assertions when they're hit; otherwise, those assertions might go unhandled and cause the machine to crash and reboot if they are raised in code that runs in kernel mode.
Windows Servicing Terminology
Each major Windows release is usually preceded by a few public milestones that provide customers with a preview of the features included in that release. Those prerelease milestones are usually called Alpha, Beta1, Beta2, and RC or release candidate, in this chronological order, though several Windows releases have either skipped some of these milestones or named them differently. These prerelease milestones also present an opportunity for Microsoft to engage with customers and collect their feedback before Windows is officially “released to manufacturing,” a milestone referred to as RTM.
You will again recognize the major version of Windows in the build information displayed by the vertarget command that accompanies many of the debugger listings presented in this book. For example, the following listing shows that the target machine is running Windows 7 RTM and that July 13, 2009 (identified by the “090713” substring in the following output) is the date this particular Windows build was produced at Microsoft.
lkd> vertarget Windows 7 Kernel Version 7600 MP (2 procs) Free x64 Built by: 7600.16385.amd64fre.win7_rtm.090713-1255
In addition to the major client and server releases for each Windows operating system, Microsoft also ships several servicing updates in between those releases that get automatically delivered via the Windows Update pipeline and usually come in one of the following forms:
Service packs These releases usually occur a few years apart after RTM and compile the smaller updates made in between (and, on occasion, new features requested by customers) into a single package that can be applied at once by both consumers and businesses. They are often referred to using the “SP” abbreviation, followed by the service pack number. For example, SP1 is the first service pack after RTM, SP2 is the second, and so on.
Service packs are considered major releases and are subjected to the same rigorous release process that accompanies RTM releases. In fact, many Windows service packs also have one or more release candidate (RC) milestones before they're officially released to the public. The number of service packs for a major Windows release is often determined by customer demand and also the amount of changes accumulated since the last service pack. Windows NT4, for example, had six service packs, while Windows Vista had two.
GDR updates GDR (General Distribution Release) updates are issued to address bugs with broad impact or security implications. The frequency varies by need, but these updates are usually released every few weeks. These fixes are also rolled up into the following service pack release.
For example, the following output indicates that the target debugging machine is running a version of Windows 7 SP1. Notice also that the version of kernel32.dll that's installed on this machine comes from a GDR update subsequent to the initial Windows 7 SP1 release.
0:000> vertarget Windows 7 Version 7601 (Service Pack 1) MP (2 procs) Free x86 compatible kernel32.dll version: 6.1.7601.17651 (win7sp1_gdr.110715-1504)