As you saw in Chapter 4, Ntldr is the Windows 2000 operating system file that conducts the first portion of the Windows boot process. Ntldr resides on the system volume; the boot-sector code on the system volume executes Ntldr. Ntldr reads the Boot.ini file from the system volume and presents the computer's boot choices to the user. The partition names that Boot.ini designates are in the form multi(0)disk(0)rdisk(0)partition(1). These names are Advanced RISC Computing (ARC) names because they're part of a standard partition-naming scheme that Alpha firmware and other RISC processors use. Ntldr translates the name of the Boot.ini boot entry that a user selects to the appropriate boot partition and then loads the Windows 2000 system files (starting with the registry, Ntoskrnl.exe, and the boot drivers) into memory to continue the boot process.
During initialization, the Windows 2000 I/O manager starts the hard disk storage drivers. Storage drivers in Windows 2000 follow a class/port/miniport architecture, in which Microsoft supplies a storage class driver that implements functionality common to all storage devices and a storage port driver that implements functionality common to a particular bus, such as a Small Computer System Interface (SCSI) bus or an Integrated Devise Electronics (IDE) system, and OEMs supply miniport drivers that plug into the port driver to interface Windows 2000 to a particular implementation.
In the disk storage driver architecture, only class drivers conform to the standard Windows 2000 device driver interfaces. Miniport drivers use a port driver interface instead of the device driver interface, and the port driver simply implements a collection of device driver support routines that interface miniport drivers to Windows 2000. This approach simplifies the role of miniport driver developers and, because Microsoft supplies operating system-specific port drivers, gives miniport drivers binary portability between Windows 98, Windows Millennium Edition, and Windows 2000.
Windows 2000 includes Disk (\Winnt\System32\Drivers\Disk.sys), a class driver that implements functionality common to disks. Windows 2000 also provides a handful of disk port drivers. For example, Scsiport.sys is the port driver for disks on SCSI buses, and Pciidex.sys is a port driver for IDE-based systems. Windows 2000 ships with several miniport drivers, including one—Aha154x.sys—for Adaptec's 1540 family of SCSI controllers. On systems that have at least one ATAPI-based IDE device, one driver—Atapi.sys—combines port and miniport functionality. Most Windows 2000 installations include one or more of the drivers mentioned.
The Windows 2000 disk class driver creates device objects that represent disks and partitions. Device objects that represent disks have names of the form \Device\HarddiskX\DRX; the number that identifies the disk replaces both Xs. The disk class driver uses the I/O manager's IoReadPartitionTable function to identify device objects that represent partitions. As miniport drivers present the disks that they identify early in the boot process to the disk class driver, the disk class driver invokes the IoReadPartitionTable function for each disk. IoReadPartitionTable invokes sector-level disk I/O that the class, port, and miniport drivers provide to read a disk's MS-DOS-style partition table and construct an internal representation of the disk's hard partitioning. The disk class driver creates device objects to represent each primary partition (including primary partitions within extended partitions) that the driver obtains from IoReadPartitionTable. The following is an example partition object name:
This name identifies the first partition on a system's first disk. The first two hexadecimal numbers (0x7e000 and 0x7ff50c00) designate the start and length of the partition, and the last number is an internal identifier that the class driver assigns.
To maintain compatibility with applications that use the Windows NT 4 naming conventions, the disk class driver creates symbolic links with Windows NT 4-formatted names that refer to the device objects the driver created. For example, the Disk class driver creates the link \Device\Harddisk0\Partition0 to refer to \Device\Harddisk0\DR0, and \Device\Harddisk0\Partition1 to refer to the first partition device object of the first disk. The class driver also creates the same Win32 symbolic links in Windows 2000 that represent physical drives that it created in Windows NT 4 systems. Thus, for example, the link \??\PhysicalDrive0 references \Device\Harddisk0\DR0. Figure 10-3 shows the Winobj utility (available on the companion CD in \Sysint\Winobj.exe) displaying the contents of a Harddisk directory for a basic disk. You can see the physical disk and partition device objects in the right-hand pane.
Figure 10-3 Winobj showing a Harddisk directory of a basic disk
As you saw in Chapter 3, the Win32 API is unaware of the Windows 2000 object manager namespace. Windows 2000 reserves two different namespace subdirectories for Win32 to use, one of which is the \?? subdirectory. (The other is the \BaseNamedObjects subdirectory, which is covered in Chapter 3.) In this subdirectory, Windows 2000 makes available device objects that Win32 applications interact with—including COM and parallel ports—as well as disks. Because disk objects actually reside in other subdirectories, Windows 2000 uses symbolic links to connect names under \?? with objects located elsewhere in the namespace. For each physical disk on a system, the I/O manager creates a \??\PhysicalDriveX link that points to \Device\HarddiskX\Partition0. (Numbers, starting from 0, replace X.) Win32 applications that directly interact with the sectors on a disk open the disk by calling the Win32 CreateFile function and specifying the name \\.\PhysicalDriveX (in which X is the disk number) as a parameter. The Win32 application layer converts the name to \??\PhysicalDriveX before handing the name to the Windows 2000 object manager.
The FtDisk driver (\Winnt\System32\Drivers\Ftdisk.sys) creates disk device objects that represent volumes on basic disks. FtDisk is present in Windows NT 4 only when at least one multipartition volume is present; in Windows 2000, FtDisk plays an integral role in managing all basic disk volumes, including simple volumes. For each volume, FtDisk creates a device object of the form \Device\HarddiskVolumeX, in which X is a number (starting from 1) that identifies the volume. FtDisk uses the basic disk configuration information that the registry key HKLM\SYSTEM\Disk stores to determine what basic volumes, multipartition and otherwise, a system includes. Note that the Disk key is only on Windows 2000 systems that were upgraded from Windows NT 4 (or Windows 98) and that already had a Disk key from previous disk-management activity (such as assigning drive letters to volumes or creating multipartition volumes). To avoid reliance on the registry, FtDisk migrates configuration information from the Disk key to hidden sectors on disk.
FtDisk is actually a bus driver because it's responsible for enumerating basic disks to detect the presence of basic volumes and report them to the Windows 2000 Plug and Play manager. To implement this enumeration, FtDisk leverages the Plug and Play manager, with the aid of the partition manager (Partmgr.sys) driver, to determine what basic disk partitions exist. The partition manager registers with the Plug and Play manager so that Windows 2000 can inform the partition manager whenever the disk class driver creates a partition device object. The partition manager informs FtDisk about new partition objects through a private interface and creates filter device objects that the partition manager then attaches to the partition objects. The existence of the filter objects prompts Windows 2000 to inform the partition manager whenever a partition device object is deleted so that the partition manager can update FtDisk. The disk class driver deletes a partition device object when a partition in the Disk Management Microsoft Management Console (MMC) snap-in is deleted. As FtDisk becomes aware of partitions, it uses the basic disk configuration information to determine the correspondence of partitions to volumes and creates a volume device object when it has been informed of the presence of all the partitions in a volume's description.
Windows 2000 volume drive-letter assignment, a process described shortly, creates drive-letter symbolic links under the \?? object manager directory that point to the volume device objects that FtDisk creates. When the system or an application accesses a volume for the first time, Windows 2000 performs a mount operation that gives file system drivers the opportunity to recognize and claim ownership for volumes formatted with a file system type they manage. (Mount operations are described in the section "Volume Mounting" later in this chapter.)
The Disk Management MMC snap-in DLL (DMDiskManager, located in Winnt\System32\Dmdskmgr.dll), shown in Figure 10-4, uses the DMAdmin, the LDM Disk Administrator service (Winnt\System32\Dmadmin.exe) to create and change the contents of the LDM database. When you launch the Disk Management MMC snap-in, DMDiskManager loads into memory and starts DMAdmin, if it's not already running. DMAdmin reads the LDM database from each disk and returns the information it obtains to DMDiskManager. If DMAdmin detects a database from another computer's disk group, it notes that the volumes on the disk are foreign and lets you import them into the current computer's database if you want to use them. As you change the configuration of dynamic disks, DMDiskManager informs DMAdmin of the changes and DMAdmin updates its in-memory copy of the database. When DMAdmin commits changes, it passes the updated database to DMIO, the Dmio.sys device driver. DMIO is the dynamic disk equivalent of FtDisk, so it controls access to the on-disk database and creates device objects that represent the volumes on dynamic disks. When you exit Disk Management, DMDiskManager stops and unloads the DMAdmin service.
Figure 10-4 Disk Management MMC snap-in
DMIO doesn't know how to interpret the database it oversees. DMConfig (Winnt\System32\Dmconfig.dll), a DLL that DMAdmin loads, and another device driver, DMBoot (Dmboot.sys), are responsible for interpreting the database. DMConfig knows how to both read and update the database; DMBoot knows only how to read the database. DMBoot loads during the boot process if another LDM driver, DMLoad (Dmload.sys), determines that at least one dynamic disk is present on the system. DMLoad makes this determination by asking DMIO, and if at least one dynamic disk is present, DMLoad starts DMBoot, which scans the LDM database. DMBoot informs DMIO of the composition of each volume it encounters so that DMIO can create device objects to represent the volumes. DMBoot unloads from memory immediately after it finishes its scan. Because DMIO has no database interpretation logic, it is relatively small. Its small size is beneficial because DMIO is always loaded.
Like FtDisk, DMIO is a bus driver and creates a device object for each dynamic disk volume with a name in the form \Device\HarddiskDmVolumes\PhysicalDmVolumes\BlockVolumeX, in which X is an identifier that DMIO assigns to the volume. In addition, DMIO creates another device object that represents raw (unstructured) I/O in a volume named \Device\HarddiskDmVolumes\PhysicalDmVolumes\RawVolumeX. Figure 10-5 shows the device objects that DMIO created on a system that consists of two dynamic disk volumes. DMIO also creates numerous symbolic links in the object manager namespace for each volume, starting with one link in the form \Device\HarddiskDmVolumes\ComputerNameDg0\VolumeY for each volume. DMIO replaces ComputerName with the name of the computer, and replaces Y with a volume identifier (different from the internal identifier that DMIO assigns to the device objects). These links refer to the block-device objects under the PhysicalDmVolumes directory.
Figure 10-5 DMIO driver device objects
Windows 2000 I/O architecture permits the dynamic layering of device objects, which Chapter 9 describes in detail. A device driver can create a device object and attach it to a target device object. The I/O manager routes requests directed at a target device object to that object's attached device object, if one exists. Device drivers use this mechanism to monitor, augment, or change the behavior of device objects that belong to other device drivers. A driver that relies on layering is a filter driver, and when a filter driver receives an I/O request packet (IRP) aimed at a target device, the filter driver has full control over the request. The filter driver can fail the request, create new subrequests, or pass the unmodified request to the target device. (IRPs are covered in more detail in Chapter 9.)
Windows 2000 storage drivers commonly use layering in two places. The first place involves file system filter drivers. At the highest level, file system filter drivers attach to the target device objects that represent mounted partitions that file system drivers create. A file system filter driver therefore intercepts requests aimed at mounted volumes so that the driver can implement functionality such as monitoring, encryption, or on-access virus scanning. File Monitor, a utility included on the companion CD under \Sysint\Filemon.exe, is an example of a file system filter driver.
The second place storage drivers commonly use layering is to implement monitoring. Windows 2000 includes a layered storage driver named DiskPerf (Disk Performance driver - \Winnt\System32\Drivers\Diskperf.sys) to do this. DiskPerf attaches to the device objects that represent physical disks (for example, \Device\Harddisk0\Partition0) so that it can generate performance-related statistics for the Performance tool to present. Statistics include bytes read and written per second, transfers per second, and the amount of time spent performing disk I/O.