'; window.popUpWin.document.write(zhtm); window.popUpWin.document.close(); // Johnny Jackson 4/28/98 } //--> Windows 98 Professional Reference -- Ch 11 -- Windows 98 Architecture and Application Support


Windows 98 Professional Reference

Previous chapterNext chapterContents


- 11-
Windows 98 Architecture and Application Support



If a surgeon knew all the best surgical techniques, all the different procedures, and all the proper practices for surgery but didn't understand the underlying reasons for all those things, you probably wouldn't want that surgeon operating on you, would you? On a different but related note, a musician who knows and can play a large number of songs can't really improvise unless he or she understands the underlying musical theory.

To be a top-notch Windows 98 professional, you have to understand the fundamental design and architecture of the operating system. Understanding its capabilities, limitations, and design can help you solve problems that arise in different situations. In this chapter, you learn

about the fundamentals of Windows 98: its architecture, how it multitasks, what programming models it supports, how it uses memory, how it handles its drivers, and so forth.

Understanding the Architecture of Windows 98

Before exploring the architecture of an operating system such as Windows 98, you must first ask what an operating system needs to do. Broadly speaking, today's operating systems are expected to do the following:

All these tasks are designed to make the user of the system as productive as possible. In the following sections, you learn how Windows 98 does these things. The sections are arranged according to the different areas, which together provide the operating system's management of the system.

Multitasking and Scheduling

Even in the days of DOS, people wanted to be able to run multiple applications at the same time. When a computer using a single-tasking operating system (such as DOS) is busy downloading a file for several hours or printing a large report, for example, it can't be used for any other purpose. Various attempts were made to try to mimic multitasking behavior under DOS--such as the various Terminate-and-Stay-Resident (TSR) programs that performed some work in the background or products such as DesqView or TopView--but all these solutions were essentially unsatisfying.


NOTE: Throughout this discussion, you will see references to applications, tasks, or processes when we talk about software programs. In this context, all these terms refer to the same thing: discrete software programs running on the computer. These software programs include actual applications software, device drivers, operating system processes, and so on.


Computers with a single processor never really do more than one thing at a time, but they're fast enough that they can be made to appear to do many things at once. Multitasking is basically: the ability to run multiple programs--or tasks--"at the same time." When you think about it, building this illusion and making it seamless to the user is quite complicated. Consider that the microprocessor and the memory in the system must be constantly doing small pieces of work for all the running applications, each with its own set of data, hardware requirements, and so forth. Coordinating these activities reliably is immensely complicated.

All multitasking operating systems divide the processor's time into units called time slices. A time slice is the smallest unit of time that can be allocated to a program. Under Windows 98, a time slice lasts only about twenty milliseconds (depending on the processor speed and its architecture). Depending on the needs of the applications and the system, an application may be allocated one time slice or many time slices before another task gets to use the processor. Determining which tasks get which time slices, and how they arrange their activity, is called scheduling.


NOTE: In Windows 98, a time slice is sometimes called a quantum.


Cooperative Versus Preemptive Multitasking

There are two main ways of building a multitasking system: cooperative multitasking and preemptive multitasking. A cooperative multitasking system relies on all the tasks running on the system to cooperate in sharing the processor. The system trusts each application to use the processor and then give it up voluntarily when the application has completed some atomic process. Then the next application does the same thing. All the running applications continue to do this in a round-robin fashion: Imagine all the applications in a circle, each one passing the ball (that is, the processor) to the next application, around and around.

In most cooperative multitasking schemes, there are both explicit and implicit yields. A yield is the process through which an application signals to the operating system that it's okay for the next application to commence work. An explicit yield is when an application literally sends a signal to the operating system saying, "I'm through for a moment, so you can give the next program a turn." Programmers of software running under a cooperative multitasking system issue explicit yield commands in their programs to do this.

An implicit yield is when the application performs some operation that implies that the operating system is free to let another application do some work while the first application's operation completes. An example of an implicit yield under Windows 3.1 is when an application makes a request of the operating system to retrieve some data from a hard disk. The operating system receives the request and sends the request to the hard disk interface card to process. While the hard disk controller and the disk itself are busy retrieving the data (this may take several seconds), the operating system can let other applications do some work on the processor until the hard disk interface signals that it's ready to provide the requested data through a signal on one of the processor's interrupt request lines (IRQs). The requesting application doesn't have to explicitly signal a yield in this case; the yield is assumed with certain operations.

Cooperative multitasking operating systems are the easiest kind to build (although they are still much more complicated than single-tasking operating systems). However, there are many problems with cooperative multitasking systems. The chief problem is that most software programs have a tendency to "hog" the system and aren't well written in terms of being truly cooperative. (In other words, they don't play well together). In addition, if an application crashes while it owns the processor, there may not be any way for the operating system to detect that occurrence and terminate the offending application gracefully--resulting in a hung computer. If you are running many applications, all presumably having important data, failures like this can cost much more in productivity than the multitasking features added to begin with. In addition to the risk of crashing the system, many programs running under a cooperative scheme are almost guaranteed to not cooperate consistently, so you almost always end up with "jerky" behavior from the system.

A preemptive multitasking system is very different in concept from a cooperative system. A preemptive system keeps control of the processor and can preempt a program that's using the processor at any time (thus the name). In a preemptive scheme, programs don't have to worry about yielding the processor to other programs; the operating system takes care of all those details and can more fairly and reliably apportion the finite resources of the system to all the programs using the system. In a preemptive scheme, a single program cannot "hog" the system, whether it wants to or not, or whether it's well written or badly written. Although a badly written application can make excessive demands of the system, the operating system ensures that all running programs get a fair chance to use the system resources. The user is left with the impression of a much more smoothly multitasking system, and is generally more productive using such a system.

Time Slicing Versus Managed Scheduling

Different programs have different needs. For example, software that provides network services generally expects the operating system to let it do its work whenever required, without waiting around for other, less time-sensitive programs to do their work. For example, if you're running Personal Web Server services under Windows 98, you don't want the Web services to stop responding to requests just because your system is busy printing a document. The way an operating system determines the priorities of different running programs and apportions system time to them is known as scheduling.

Cooperative systems have relatively unsophisticated scheduling mechanisms--if they have any at all. Many operate in a true round-robin fashion, in which every program has the same priority as any other program. Some cooperative schemes have rudimentary scheduling, with which the user of the system can assign different "weights" to different programs (DesqView did this, for example). For example, all else being equal, you may want your email program to be given fewer time slices on the system than your word processing program. Windows 3.1 had a very basic scheduling scheme with which you could weight the foreground and background priority, but it wasn't application specific. All these scheduling schemes are called time-slicing scheduling mechanisms.

A system that uses managed scheduling, on the other hand, lets each program signal its priority needs when it starts. The operating system takes care of doling out the processor's time based on the priorities claimed by the programs. A program can also signal that it temporarily requires a higher priority for some task; it is the application's responsibility to lower its own priority after it finishes the critical task. The priority of a program can be elevated (also called boosting) under certain circumstances. Generally, priority boosts occur in the following situations:

Before discussing program priorities in more detail, you must first have a better understanding of another topic: processes and threads.

Understanding Processes and Threads

Until now, we've discussed only generic programs, meaning any software running on the system. To continue the overall discussion of Windows 98's architecture, you must understand how programs are structured in the system, which means that you have to understand processes and threads.

Under single-tasking operating systems and some multitasking operating systems, a process is a program--a series of machine code instructions--along with all the resources of the program. These resources include memory addresses allocated to the program, hardware devices the program has reserved for its exclusive use, memory variables, and so forth.

Process-based multitasking operating systems have a big inherent weakness: If an application program has to do simultaneous work (such as printing a document while it also paginates), it does so by starting up an entirely new process to do that alternate work. The problem is that each process is a complete entity and must have its own memory space and other resources. Two processes being operated by a single application program have to pass a lot of data back and forth through a process called interprocess communication. Starting processes to do relatively simple tasks (such as spell-checking the last word the user entered in a word processor) is very expensive in terms of overhead requirements. It's almost as if the program has to create a complete clone of itself to do additional simultaneous work--and then the clones have to spend a lot of time talking to one another so that they can get their jobs done in sync.

To answer this need, a concept called threading was introduced many years ago. The idea is this: In a multitasking, multithreaded operating system, each process is still a complete program, with program code, memory addresses, and so forth, but it doesn't do any work. Instead, each process has at least one thread of execution (called Thread 0) which actually performs the work. A process must have at least one thread, but it can also have as many threads as it needs. Here's the neat thing: All the threads within a process share the resources of the process. A program can create new threads without having to copy a lot of data for the threads to use; all the threads use the same resources. Programs that use multithreading techniques can appear to do many things at once, and little overhead is required to accomplish this.

Programs written using the Win32 Application Programming Interface (API) can be multithreaded. It's entirely up to the needs (and abilities) of the programmer.

How Windows 98 Schedules Threads

Windows 98 allows both processes and threads to have their own priority levels, and it apportions the processor's time based on those priority levels. When a process is created in the system, it specifies its own base priority class. The threads within the process, unless otherwise specified, share that base priority class.

There are four different priority classes for Win32 programs under Windows 98:

Within each priority class are 32 different levels, from 0 (the lowest priority within the class) to 31 (the highest priority within the class). When you combine the 4 classes with the 32 levels, you see that there are 128 distinct priority levels within Windows 98.

For programming ease, the 32 priority levels within each class are divided into seven requested levels. When a thread is created within a priority class, the programmer can easily set its priority using one of these levels. From lowest priority to highest, the levels are IDLE, LOWEST, BELOW NORMAL, NORMAL, ABOVE NORMAL, HIGHEST, and TIME CRITICAL. Often, the thread of a program that processes the program's user interface is set to ABOVE NORMAL or HIGHEST so that the application is responsive; other threads are set to NORMAL or BELOW NORMAL, depending on the work they do.

When a thread is created, it has a base priority level. It also has a dynamic priority level, which is adjusted by the operating system's scheduler. At certain times, a thread's dynamic priority level may be boosted by the scheduler. Threads with a priority level of 0 through 15 can receive dynamic boosts; threads with a priority level of 16 through 31 cannot. Here are the three main circumstances in which a thread's priority can be boosted by the scheduler:

There is one other case in which a thread's priority is boosted: priority inversion. When a high priority thread depends on the results of a low priority thread, the low priority thread is temporarily boosted up to the level of the high priority thread for as long as the dependency exists. In a sense, the system recognizes that the low priority thread in this case is really an extension of the high priority thread, and so raises its priority. If priority inversion did not occur, situations could arise in which the high-low thread dependency could become stuck by a thread running at an intermediate level.

When threads are boosted by a dynamic priority boost from the scheduler, the scheduler reduces the priority of the threads by one level for each time slice they complete until they return to their base level. A thread is never forced to run at a priority level lower than its base priority level.

When multiple threads are set to the same level, and all are "ready to run" (in other words, are unblocked), the scheduler apportions processor time to each of the threads in a round-robin fashion.

Understanding Semaphores, Waits, and Critical Sections

Consider a process with many threads. Each of the threads can access the memory objects within the process. It is possible that while one thread is writing new data to a memory object, another thread may be reading that same data. In another case, two threads may try to write new data at the same time to the same memory location. Either of these situations could cause catastrophe and unpredictable results. As you can see, programmers need a way to coordinate access to the resources within the process so that threads aren't constantly "stepping on each others' toes."

Several mechanisms are available to let programmers perform this coordination. The first of these mechanisms are semaphores. Named for the flags used to signal trains (and keep them from accidentally colliding), a semaphore is also sometimes referred to as a flag. When a program creates a memory object that may be used by different threads, it attaches a semaphore to that memory object. The semaphore is then checked by each thread before that thread tries to access the memory object. If the semaphore signals that another thread is using the object, the intruding thread waits until the semaphore indicates that the object is available; the thread then sets the semaphore to indicate that it now owns the memory object temporarily. Semaphores can be created for other resources the process uses or accesses, or for any other purpose of the programmer for which this mechanism is helpful. Semaphores can be created to allow more than one thread to access the resource; for example, you can specify that a certain number of threads at once are allowed access to the resource.

Another coordination mechanism is a mutex object, which is a different breed of semaphore. A mutex ensures mutually exclusive access to a resource (thus the name).

Win32 threads under Windows 98 can also use wait functions, or waits, that can set specific criteria. When the criteria are met, the scheduler lets the threads continue. The wait criteria can be for a single object to become free, for multiple objects to become free, or for an object to become free and for something else to happen that the thread has to process (called an alertable wait).

Semaphores and wait functions can be used when a thread has to wait to use an object owned by any process in the system. When a thread is waiting for an object within its own process, it can use a mechanism called a critical section to coordinate access between itself and other threads within the same process. Because critical sections work within a single process, they carry less overhead than the other mechanisms.

Understanding the Windows 98 Memory Model

The early versions of the Intel family of processors used a segmented memory architecture to allow programs to access up to 1M of memory space. Early programs were limited to only 16 bits of memory addresses, yielding only 64K of addressable memory space. With the 8088 Intel processor, Intel crafted an additional 4 bits of memory addressing onto the chip (20 bits total), but to maintain compatibility with the 16-bit programs already in existence, Intel broke the memory into 16-bit (64K) chunks, called segments. Programs that wanted to access more than 64K of memory space had to access the memory by specifying two addresses: a segment and an offset. (Offsets were the actual address within the 64K segment.) Notice that the 20-bit addressing scheme yields 1M of addressable memory. Because the original PC set aside 384K of that 1M for the hardware devices in the computer, you can see where the original 640K memory limit came from--it was a function of both DOS's 16/20-bit design and the hardware design for which DOS was originally built.

Beginning with the 80386 chip, Intel packaged 32 bits of memory addressing onto the processor chips. (32 bits lets you access up to 4G of memory.) Although this allowed for full 32-bit addresses (a flat memory model without segment and offset addresses), earlier DOS and Windows operating systems couldn't take advantage of it.

Windows 98 uses the flat memory model. Each memory address on the system is specified using 32 bits, giving each program the capability to address up to 4G of memory. However, this brings up some interesting questions: If each program can address up to 4G of memory, and if you can have multiple programs, does that mean that you can have more than 4G of memory in the system? How is that possible when there are only 32 bits' worth of addressing on the processor itself? And when you think about it, any Windows 98 system addresses a lot more physical memory than actually exists on the system (which is certainly less than 4G). These questions lead to the next discussion: virtual memory, a key component of Windows 98 and virtually all modern operating systems.

Virtual Memory

The current Intel family of processors has a feature called paging. When paging is disabled on the processor, there is a 1:1 correlation between a memory address and a location in a physical memory chip (RAM, generally). When paging is disabled, the processor can address up to 4G of physical memory, and programs can access all that memory. But all that memory must be actual RAM when the paging feature is disabled.

However, virtually all modern operating systems, including Windows 98, operate with the paging feature of the processor enabled. When paging is enabled, there is no longer a 1:1 correlation between a memory address used by a program and a physical memory location. Instead, the operating system and processor maintain tables that let them locate a specific physical memory address for each logical memory address used.

The system divides up all memory in the system into 4K pages (this is where the name paging comes from). A 32-bit address used by an application is translated into a physical address using a table. The first 20 bits of a 32-bit memory address locate a specific page of memory. Thus, the system can manage a little more than 1 million 4K pages at a time. The remaining 12 bits specify an actual address within the selected page.

Why does the system maintain complicated tables to resolve a memory address? Wouldn't it be easier to simply map a memory address directly to a physical memory location, where address 11245 meant physical memory address 11245, for example? The reason is that the system must implement virtual memory, where both physical RAM in the system and emulated memory in a disk file both serve as addressable memory. Because the system must be free to move memory data between RAM and the virtual memory file, the system must keep track of where all the memory is at any given time. Managing this on a byte-by-byte basis would bog the system down unnecessarily, making it figure out whether each memory address was in virtual memory or real RAM. Instead, the system manages 4K pages of memory. Entire 4K pages of memory--not individual bytes--are moved back and forth between the virtual memory file on the disk and real RAM. Using this scheme, the overall system is more efficient.

As far as the applications on the system are concerned, each 32-bit address is simply that: a 32-bit address indicating a specific memory location. The operating system, however, needs a way to figure out whether the memory is in RAM or in the paging file, and so this scheme of memory indirection is used.

Windows 98 implements a memory page management system called demand paging. In this system, memory pages are preferentially kept in real RAM based on how recently they have been used (how much they are in demand). Memory pages that are least recently used (LRU) are moved to the paging file on a hard disk. The system constantly examines the pages of memory and their usage history to determine which pages can most likely be moved to the paging file. When an application requests a memory address for a page of data that has been moved to the paging file, the operating system transparently moves the page back into physical RAM before letting the application continue working with the page. The thread requesting the page is blocked automatically until the transfer occurs (it's typically a fairly fast operation).

Paging schemes such as the one used by Windows 98 are a great boon to users--and are virtually required with a multitasking operating system in which many software components and memory objects are in use at one time. When you're using a word processor, its memory pages (or at least the memory pages relating to the features you're using at that time) are kept in RAM; programs and memory objects that are loaded but not doing anything are paged to the paging file, ready to be called back at a moment's notice. Virtual memory lets the system accomplish much more work than it could otherwise and lets the system process much larger programs (and many more of them) than would be possible without paging.

The danger with virtual memory systems (from a performance standpoint) is a condition called thrashing. Thrashing occurs when multiple programs are running, all of which combined require more memory pages than can fit in the physical RAM of the system. The system thrashes as it constantly moves memory pages back and forth from the paging file, trying to satisfy all the running applications at once. When this happens, you have only two courses of action: You can reduce the program load by running fewer programs (or by reducing the amount of data with which they have to work) or you can add more physical RAM to the system.


TIP: Because of the way virtual memory works, you can sometimes accomplish more work with a system by doing your work in sequence rather than in parallel (simultaneously). If you have enough RAM for all the programs, running them simultaneously accomplishes the work about as fast as running the programs sequentially. If you overburden RAM by opening all your programs at once, however, you can get better results by running the programs sequentially because you avoid the severe performance penalty that thrashing entails.


Under Windows 98, you can manage the virtual memory settings for the system using the System Control Panel. Chapter 35, "Tools and Strategies for Optimizing Windows 98," contains details about these settings.

Memory Protection

Windows 98 is essentially a 32-bit protected-memory operating system. It's called protected because the system ensures that programs don't improperly access the memory of other programs. Each process owns its own memory pages; if another program inadvertently tries to access a memory page that it doesn't own, it is denied access. This protection scheme helps prevent bugs in one program from corrupting the memory of other programs.

The Intel architecture supports a concept called privilege rings. A privilege ring is really just a way of sorting all the memory of the system in a useful way. Intel processors allow up to four different privilege rings (Rings 0 through 3), but only two are implemented by Windows 98 and Windows NT: Ring 0 and Ring 3.

Different programs run at different privilege rings. The operating system and processor know at which ring each program runs and restrict its access to memory based on that ring. Programs running at Ring 0 have unrestricted access to all the memory of the system; programs running at Ring 3 have restricted access to memory. A program running at Ring 0 can access any memory, including memory "owned" by any processes at any other rings. Programs running at Ring 3 can access only their own memory. This scheme is enforced by the processor hardware of the computer and is supported by the operating system.

It is desirable to restrict the software running at Ring 0 to only the most trusted areas of the operating system, which require Ring 0 access to do their work. Everything else--including application programs and parts of the operating system that don't require Ring 0 access--should run at Ring 3. The Windows 98 kernel (the core of the operating system) runs at Ring 0, as do various performance-sensitive components such as video drivers. Programs running at Ring 0 operate much more quickly than those running at Ring 3 because there is no memory protection mechanism slowing down their ability to access system memory.

Windows 98 divides memory in a way that supports privilege rings. Within the total 4G memory address space, applications and their data are restricted to occupying the first 2G of memory addresses (although real-mode device drivers exist in the first 640K). The next 1G of memory addresses are occupied by core operating system components and DLLs. The final 1G of memory addresses are restricted to Ring 0 software (the fundamental core software of Windows 98). Figure 11.1 shows you this layout. (: This information may be on the MCSE test.)

Figure 11.1

The Windows 98 memory address space.

Understanding Windows 98 Components

A number of different components make up the architecture of Windows 98. The following sections discuss each component and how it fits into the overall scheme. Figure 11.2 shows the overall arrangement of these components.

Figure 11.2

Overall arrangement of Windows 98 components.


Device Drivers

Interacting directly with the computer's hardware, device drivers are software entities customized to work with each different possible hardware device. Device drivers exist for different video cards, different hard disk subsystems, different communication and printer ports, different modems and printers, and so forth. Device drivers are customized for the hardware components with which they interact. For example, a device driver that knows how to talk to a SCSI hard disk is different from a driver that knows how to talk to an EIDE-based hard disk.

Because device drivers interact directly with the hardware with which they communicate and serve as the ultimate interface between the hardware and the rest of the system, they are thought to be at the lowest possible level of the system's architecture.

Windows 98 makes use of a universal driver/minidriver design that makes individual device drivers simpler and more robust. For example, there is a universal modem driver (called UNIMODEM.DRV) that knows how to talk to all modems that use an AT command set. Working in concert with the universal driver is a minidriver that knows how a particular model of modem behaves. This duality reduces the complexity of developing individual modem minidrivers because the universal driver already has most of the logic required for devices of that general type.

New to Windows 98 is a Unified Device Driver model; in this model, drivers for Windows NT and Windows 98 can be the same. By adding certain simulated Windows NT kernel services to a DLL running in Windows 98, vendors can now develop single drivers for both operating system targets.


What Is a DLL?


Dynamic Link Libraries (DLLs) are files containing executable program code that can be shared by different components of a single application--or even other applications on the system. In fact, some core components of Windows itself are implemented as DLLs, partly so that applications can make use of the routines included in those DLL files.
When an application links to a DLL, it can then call routines within the DLL file to do work for the application. DLLs allow applications to be much smaller than they would be otherwise because they keep common code in a single location instead of forcing each separate .EXE file to contain all the functions it has to call.


Many device drivers in the system are called virtual device drivers (VxDs), which are each assigned to a particular piece of hardware in the system. The x in VxD refers to the actual type of device driver: A printer driver is a VPD, a display driver is a VDD, and so forth. The actual virtual device driver files in Windows 98 all have a .VXD extension.

Configuration Manager

Above device drivers in the architecture of Windows 98 components are three system components: Configuration Manager, Virtual Machine Manager, and the Installable File System Manager. Configuration Manager is the system component that handles Plug and Play devices (and functionality) on the system. Configuration Manager is responsible for coordinating all the IRQs, DMA ports, I/O port addresses, and other system resources for all the installed devices. Configuration Manager ensures that no device uses the resources needed by other devices; when there is a conflict, Configuration Manager has the power to change the settings for a device to avoid conflict.

The Configuration Manager uses bus enumerators to build a tree of all the hardware in a Windows 98 system. A bus enumerator is a driver that can enumerate (list) all the devices connected to a particular bus, such as EISA or PCI buses. The hardware tree is a hierarchical listing of devices on the system, starting at the root of the tree, expanding into different buses, and including the devices on each bus. You can view the hardware tree for a given system by opening Registry Editor and navigating to the key HKEY_LOCAL_MACHINE/Enum.

When Configuration Manager detects a conflict in the resource requirements for different hardware devices, it invokes a resource arbitrator to resolve the difficulty automatically.

As the system boots and any device configuration problems are resolved, Configuration Manager notifies the supporting device drivers of the exact configuration of each device in the system.

Virtual Machine Manager

The second operating system component above device drivers (that is, the second com- ponent that can talk directly to device drivers), the Virtual Machine Manager is responsible for virtualizing access to all the devices in the computer. Virtual machines are emulated, complete computers that exist in memory. For different purposes, different virtual machines are created as needed.

All of Windows 98 itself and any Windows-based applications run within one virtual machine, called the System Virtual Machine. Each MS-DOS application running on the system gets its own private virtual machine. Separate virtual machines are required for MS-DOS applications because most MS-DOS applications--being written for a single-tasking operating system--are written as if they own the complete computer. They make direct hardware calls, manipulate hardware directly, and so forth. Because this behavior can't be tolerated in a multitasking operating system in which other applications have to run, each MS-DOS application gets its own virtual machine, which emulates the hardware devices in the computer and prevents the MS-DOS application from monopolizing those devices. (The DOS programs just think they're monopolizing the devices!)

The Virtual Machine Manager (VMM) is also responsible for process scheduling, virtual memory management, and of course MS-DOS support. The VMM is an essential part of the system and plays a crucial role in the operation of Windows 98.

Through the efforts of the VMM, Windows 98 supports both preemptive and cooperative multitasking. All Win32 applications are preemptively multitasked with respect to one another and to the system itself. All MS-DOS applications are also preemptively multitasked with respect to one another and to the system itself. Win16 applications developed for Windows 3.1, however, are all cooperatively multitasked with respect to each other (because Windows 3.1 only supported cooperative multitasking for Windows applications developed for Windows 3.1--known as Win16 applications).

Another service provided by the VMM is virtual memory management. Under Windows 98, each process can access up to 2G of logical memory addresses. The upper 2G of logical memory addresses (within the total 4G limit) is reserved for shared code and for the operating system itself.

Installable File System Manager

The Installable File System Manager (IFSM) manages the installable file systems in Windows 98. An Installable File System (IFS) is a sort of driver that provides file system services to the operating system. Different IFSs provide access to FAT16, FAT32, CD-ROM, and network file systems. Because the Windows 98 system uses file systems that are installable, support for other file systems is possible: The file system support must merely be developed, and then it can be easily installed into Windows 98 to add support for that file system. For example, when the FAT32 file system was developed and deployed for Windows 95 OSR2, the operating system didn't have to be changed; support for the new file system was added using the Installable File System Manager.

Installable File Systems insulate applications from dealing with the peculiarities of each different file system. An application (as well as the OS itself) doesn't have to worry about how files are stored on a CD-ROM, FAT16, FAT32, or network file system. Instead, the file system driver handles the interaction with the file system itself and interprets the results for the operating system and applications.

Installable File Systems run at Ring 0 privilege level, giving them greater speed. They also use full 32-bit paths for moving data between the operating system and the file system, also adding to their performance.

The Core Components

Above the device drivers and the three next-level components sit the Windows 98 core components. The so-called core components include the User, Kernel, and GDI components.

The User component handles all input from the user and outputs messages to the system's user interface; it also handles the sound drivers and communication ports. The User component manages the messages within the system. A message is an event that occurs when a user minimizes or closes a window, presses a key on the keyboard, or moves or uses the mouse. Messages are routed by the User component to the appropriate input queue for the window from which they were sent. Input queues accumulate messages for their applications until the applications process the messages and remove them from the queues.

Each Win32 application in the system can have its own message queue; Win16 applications share a single message queue. Handling message queue logic is integral to the design of applications; because Windows 3.1 supported only a single message queue, the system must provide only a single message queue for Win16 applications to be able to run. Win32-based applications are more sophisticated and can handle their own, private message queues.

The Kernel core component handles the most basic operating system functions such as loading and unloading programs, handling exceptions, and allocating virtual memory.

The final core component is the Graphical Device Interface, called the GDI. The GDI is responsible for all display output, drawing of bitmaps and graphic primitives, and interacting with the display device drivers on the system. The GDI component also provides support to the printing subsystem, which handles printed output from the system.

The Shell

The final Windows 98 architecture component you learn about in this chapter is the shell, a 32-bit application that handles the Windows 98 desktop and Explorer. The shell runs in its own thread, which can be restarted in the event of an error in the shell. Although it runs at the same level as applications in the system, the shell also provides services to those other applications. For example, the shell provides the various Windows 98 user-interface components the applications may use, such as button support, drop-down list boxes, checkboxes, File Open dialog boxes, and so on.

Summarizing the Windows 98 Architecture

As you have seen, Windows 98 is made up of a number of different components, all of which operate in concert to make Windows 98 work and to give it so many capabilities. People used to sneer at the architecture of Windows 3.1; it was a very weak operating system. Windows 98, however, brings all the benefits of a modern multitasking, multithreaded, graphical, protected-mode operating system to common desktop computers. Although Windows 98 does not possess the same "industrial-strength" architecture of Windows NT, it also does not have Windows NT's resource requirements. Moreover, Windows 98 had to make certain architectural sacrifices to continue running Win16 and MS-DOS applications as well as it does. Because there still persist, even today, many applications developed for these older platforms, and because running those applications is a requirement for many users, the sacrifices made in Windows 98 are a fair tradeoff.

Understanding Application Support

An operating system is nothing without applications that can run on it. Any operating system must provide rich support for the widest possible range of applications, which are the actual tools people use to accomplish work with their computers. The design requirements for the Windows 95 and 98 family were stringent and difficult to meet: Windows 95 and 98 must support legacy MS-DOS and Win16 applications and also provide a foundation for a new class of more powerful 32-bit applications that use the Win32 Applications Programming Interface. The following sections explain how Windows 98 supports these different application types.

APIs

Windows 98 supports three different application types: Win32, Win16, and MS-DOS. This section discusses Win32 and Win16 support under Windows 98; a later section discusses MS-DOS support.

When Windows NT 3.1 was developed, a new Applications Programming Interface (API) called Win32 was introduced. The Win32 API is a full 32-bit API that supports modern application features and takes advantage of advanced operating system services. Initially, Win32 was limited to Windows NT. Microsoft later introduced a limited API called Win32s, which was designed for 32-bit application support under Windows 3.1 (with the appropriate services installed), and ultimately for Windows 95 and 98. Maintaining the two APIs was confusing, however. Eventually, a single Win32 API came to be supported, with comments when certain functions in the API required Windows NT or Windows 95 or 98. For example, certain Win32 API functions that involve Windows NT's advanced security do not work under Windows 98. Application developers can write Win32 applications that use only broad functions supported in both families of Windows products, or they can make use of operating system-specific features in the Win32 API that restrict the application to running under only one of the two platforms. (Generally, any Windows 95 or 98 application runs under the latest version of Windows NT; the Win32 API calls supported by Windows 95 and 98 are generally a subset of those supported by Windows NT.)

Win32 applications are the native type of application supported by Windows 98. An application written for Windows 98 using Win32 also takes advantage of all the features of Windows 98, is fully preemptive, can use multiple threads, and so forth. Win32 applications are therefore much more powerful than their Win16 predecessors.

Each Win32 application under Windows 98 runs in its own private, protected memory space, in which its memory is protected from other applications running on the system. Win32 applications can take advantage of long filenames and threads and receive other advantages from the operating system. Generally, Win32 applications are also faster than Win16 applications, all else being equal.

Support for Win16 applications (those originally developed for Windows 3.x) is built into Windows 98. These applications typically run without modification under Windows 98, although a very few restrictions exist. The promise of Windows 95 and 98 was that all Win16 applications would run as well as or better than they did under Windows 3.x. Most often, this goal was met. Because some of the underlying system services of Windows 95 and 98 are much faster than those in Windows 3.x, Win16 applications are faster in the Windows 95 and 98 environment than they were in their original native environment.

All Win16 applications running under Windows 98 share a single virtual machine, in which they cooperatively multitask with respect to one another. The virtual machine they share, however, is preemptively multitasked with respect to the rest of the system. Although you cannot say that Win16 applications are preemptively multitasked because their virtual machine is, you can say that they are "sort of preemptive" when there is only a single Win16 application running at one time. The sharing of a single virtual machine means, however, that if one Win16 application crashes, chances are that all the other Win16 applications will also crash. The good news is that the crashes are restricted to the VM in which they run and should not affect the rest of the system.

OLE Support

Integral to Win32 and Win16 applications is their support for a system service called Object Linking and Embedding (OLE, pronounced like the Ol�! of a bullfighter). OLE is a technology that lets Windows applications share their data with one another, managed by the user. The biggest reason to support OLE within an application is so that entities called compound documents can be created and used by the application. A compound document is one that incorporates document objects from other applications installed on the system. For example, Word can incorporate Excel objects (such as cell ranges, charts, or entire worksheets) into a Word document and can also incorporate PowerPoint objects (such as individual slides or drawing objects). OLE allows you to build documents that incorporate the features of all the OLE applications installed on a system, seamlessly and easily.

OLE is covered in detail in Chapter 15, "OLE, COM, DCOM, and ActiveX."

MS-DOS Support

Even today, literally thousands of MS-DOS applications are still useful and are still required by users. Windows 95 and 98 had to support those DOS applications, or people would not have been able to make full use of Windows 95 and 98 and would have had to wait for all those applications to be ported to one of the WinXX APIs to use them. Unfortunately, MS-DOS applications are not designed to run in a multitasking operating system. Because they were developed for a single-tasking operating system that allowed them complete access to system memory and the computer hardware, they often make use of programming techniques that are anathema in a multitasking environment. Supporting MS-DOS applications is therefore a complex undertaking for the operating system.

Each MS-DOS application under Windows 98 runs in its own private virtual machine. The virtual machine virtualizes all the hardware devices in the system, insulating the MS-DOS application from the actual hardware. The MS-DOS application thinks it is running on a standalone PC running only MS-DOS. The MS-DOS application is free to directly manipulate its hardware. Although this is how it appears to the MS-DOS application, the reality is that the application only manipulates the virtual hardware within the virtual machine. The virtual device drivers then take care of doing the actual hardware interface and of letting other applications in the system share the actual hardware through their interfaces.

MS-DOS applications are not designed for multitasking of any kind whatsoever. They don't support cooperative or preemptive multitasking. Their virtual machine, however, is preemptive within the system, and therefore each MS-DOS application behaves as if it is preemptively multitasked. It cannot, however, signal priority requirements to the operating system, although the operating system can sense what it is doing and can take appropriate scheduling actions based on the application's requirements.

Working with MS-DOS applications under Windows 98 is a bit different from working with other types of applications. For one thing, MS-DOS applications must be installed and removed using their native installation and removal procedures rather than using the Windows 98 Add/Remove Programs dialog box. For another thing, each MS-DOS application has many specific settings that can be activated to change how the system supports the application, and these settings are unique to MS-DOS applications.

Installing and Removing MS-DOS Applications

Installing and removing MS-DOS applications is easy. You simply open a command prompt and then follow the application's installation procedures (which usually involves running a program called SETUP.EXE or INSTALL.EXE). MS-DOS applications do not appear in the Add/Remove Programs dialog box under Windows 98 and so cannot share in the unified program installation management that Win32-based applications make use of. To remove MS-DOS applications, follow the instructions that come with the program.

Installing an MS-DOS application is only half the battle. Afterwards, you'll want to create an entry in the Start menu (or on the desktop) for launching the application. You may also have to customize the Windows 98 settings for MS-DOS applications to enable the application to run as well as possible.

Setting MS-DOS Program Properties

Creating program shortcuts is covered in many other areas, and you probably need no guidance in this area if you're reading this book. Setting an MS-DOS program's properties, however, is a slightly different matter. In this section, you learn about the possible settings and what they do.

To access the settings for a DOS application, right-click the actual program file and choose Properties, or right-click any shortcuts pointing to the program file and choose Properties. You see the program's Properties dialog box, shown in Figure 11.3.

Figure 11.3

A DOS program's Properties dialog box.

When you create a shortcut to a DOS program, you are actually creating a Program Information File (PIF) for the program. The PIF file stores the settings for the program, which are used when the shortcut is used to open the program. If needed, you can have multiple shortcuts to a single program file, each of which has different settings.


TIP: When you start a DOS program from a command prompt, its PIF settings are not used.


The following sections discuss each tab of the program's Properties dialog box.

General Page

The General page of a DOS program's Properties dialog box is primarily informational (see Figure 11.3). You see the actual name of the program (or its shortcut name), its 8.3 MS-DOS name, its size and location, and date and time information about the file. There are also four checkboxes that let you control the file attributes of the program file itself (or its PIF, if that's what you're editing). You can choose to set or clear the following attributes:

Program Page

The Program page (see Figure 11.4) of a DOS program's Properties dialog box contains many important settings that control how the program starts and runs. Table 11.1 details the fields on this page.

Figure 11.4

The Program page of a DOS program's Properties dialog box.

Table 11.1 Program Page Fields

Field Name Description
Top field The top field, which does not have a name, controls the name of the program that appears in the title bar when it is running in a window on your desktop.
Cmd Line The Cmd Line field specifies the exact filename (or path and filename if the file is not in the defined search path) used to run the program. If the program requires any command-line parameters, add them to this line just as you would if you were typing the command and parameters at a DOS prompt.
Working Use the Working field to control the working directory the program uses when it starts. When this field is blank, the directory in which the program is stored is used as the working directory. In most cases, this setting should be left unchanged, or the DOS program may not run properly.
Batch File This field lets you specify a batch file to run whenever the program is started.
Shortcut Key Use this field to define a key combination that will instantly invoke the program from your Windows 98 desktop. Click in the field and then press the key combination you want to assign. You must include the Ctrl or Alt key (or both keys). If the key combination you choose conflicts with a Windows shortcut key, the combination you define will not work.
Run Use this field to choose what type of window is used to run the program. Your choices are Normal, Maximized, and Minimized. The program starts using whatever window choice you select.
Close on Exit If this box is checked, the virtual machine that is started to run the program automatically closes when the program terminates.

The Program page also lets you choose a customized CONFIG.SYS and AUTOEXEC.BAT file to be used with the program. To access this feature, click the Advanced button to display the dialog box shown in Figure 11.5.

Figure 11.5

A program's Advanced Settings dialog box.

You can control how a program starts with the Advanced Settings dialog box. Choose from the following options:

MS-DOS mode removes Windows 98 from memory and starts the system with only MS-DOS running, along with any real-mode drivers that are loaded through the CONFIG.SYS or AUTOEXEC.BAT files. You use MS-DOS mode to run legacy MS-DOS programs that run poorly under Windows 98, or when MS-DOS application performance is paramount (as is true of MS-DOS-based games). If you are using an MS-DOS program that has problems under Windows 98, MS-DOS mode may allow the program to run without error.


TIP: You can enter MS-DOS mode manually by choosing the Shut Down command and then choosing the Restart in MS-DOS Mode option.


In the Advanced Settings dialog box, you can define custom AUTOEXEC.BAT and CONFIG.SYS files for the program by typing the commands you want to use for each. This is useful when you need to load TSR programs or real-mode device drivers to support the MS-DOS program, or when you want to set application-specific environment variables for a particular MS-DOS program. By default, AUTOEXEC.BAT and CONFIG.SYS are used from the root of the drive from which you booted Windows 98.

When setting a custom AUTOEXEC.BAT or CONFIG.SYS file for a particular program, you can also choose which system services will be provided to the MS-DOS session by clicking the Configuration button at the bottom of the dialog box. Doing so displays a new dialog box from which you can choose whether or not Windows 98 will provide EMS memory, disk cache services, DOSKEY services, or direct disk access services to the MS-DOS program.

Finally, the General page lets you choose a new icon for the DOS program. Click the Change Icon button to display the Change Icon dialog box shown in Figure 11.6. Simply select a new icon from the list and click OK to apply the change. You can also click the Browse button to choose a new .ICO file from a folder.

Figure 11.6

Use the Change Icon dialog box to choose a new desktop icon for the program.

Font Page

You use the Font page of the program's Properties dialog box to choose the font to be used when the program runs in a window on your desktop. You can also use the Font page to choose the types of fonts available for the program. The Font page is shown in Figure 11.7.

Figure 11.7

The Font page of a DOS program's Properties dialog box.

From the Available Types area of the dialog box, you can choose bitmap fonts, TrueType fonts, or both types of fonts. Generally, choose Both Font Types to have the most choices available.


TIP: On some systems, bitmap fonts may display more quickly than TrueType fonts.


Use the Font Size window to choose the exact font size you want to use for the DOS program. Sizes are listed in terms of the number of pixels taken up horizontally and vertically. The font size bears a direct relationship to the size of the DOS window, which you can see in the Window Preview box as you select different fonts. You can also preview how the font will appear on your desktop in the Font Preview box. Depending on the type of program you're running, you may want to use a small font that takes up a minimum of screen space; alternatively, you may want to use a large font so that you can clearly see what you are working with.

Memory Page

The Memory page contains a number of settings that control how much memory the program "sees" when it runs. You want to control these settings, because some programs require minimum values if they are to work properly. However, many DOS programs--because they were written for an operating system in which they could take control of the machine--grab all the memory they are aware of and attempt to use it. For example, a spreadsheet program may try to use a full 16M of EMS or XMS memory, even when it's not really needed by the program. Using the Memory page of the Properties dialog box, you can place limits on what the program can use. You see the Memory page in Figure 11.8; Table 11.2 describes its settings.

Figure 11.8

The Memory page of a DOS program's Properties dialog box.

Table 11.2 Memory Page Settings

Setting Description
Conventional Memory The settings in this section control the amount of conventional memory (memory from 0 to 640K) that the program has available
Initial Environment DOS programs make use of environment variables, and you can control the size of the initial setting environment provided with this
Protected Specifies that the program will be run in a more protected mode. Selecting this option may slow the program somewhat, but will help protect certain critical memory structures in Windows 98 itself from the DOS program.
Expanded (EMS) This setting controls the amount of LIM (Lotus-Intel-Microsoft)
Memory expanded memory available to your program. Up to 16M can be allocated.
Extended (XMS) Controls the amount of XMS memory available to your program.
Memory Up to 16M can be allocated.
Uses HMA If your program makes use of the High Memory Area available to XMS-aware programs, select this checkbox.
MS-DOS Protected- Controls the amount of DOS Protected Mode Interface (DPMI)
Mode (DPMI) Memory memory available to the program, up to 16M.

Screen Page

The Screen page controls various video-related settings for DOS programs. You see this page in Figure 11.9; Table 11.3 lists the settings available.

Figure 11.9

The Screen page of a DOS program's Properties dialog box.

Table 11.3 Screen Page Settings

  system does not have ample RAM installed.  

Misc Page

The final tab in a DOS program's Properties dialog box is the Misc page, which controls a variety of functions. You can see this page in Figure 11.10; Table 11.4 details its options.

Figure 11.10

The Misc page of a DOS program's Properties dialog box.

Table 11.4 Misc Page Settings

Setting Description
Allow Screen Saver When this is selected, your Windows 98 screen saver will run, even when the DOS program is in the foreground. There is a very slight system overhead when this option is selected.
Quick Edit This option lets you simply drag across a DOS window to select text within it for use with the Clipboard.
Exclusive Mode This option causes the mouse pointer to work only with the DOS program until the program is exited, even when the program runs in a window.
Always Suspend Some DOS programs do no useful work when you are not actually using them. For such programs, you can speed up the rest of the system by making them inactive when they are minimized or otherwise placed in the background by selecting this option.
Warn If Still Active If you select this option, you are warned if you try to terminate this program from Windows NT Workstation while it is still running.
Idle Sensitivity DOS programs typically poll the keyboard for input; this polling consumes processor cycles. Setting Idle Sensitivity to High causes Windows 98 to assume that the program is merely polling for input sooner, at which point it reduces the amount of processor time allocated to the program to avoid wasting processor resources. Low sensitivity causes Windows 98 to be more lenient in assuming that the program is truly idle.
Fast Pasting You can copy text from the Windows 98 Clipboard into DOS programs. Two methods accomplish this: When Fast Pasting is selected, the quicker method is used. Some DOS programs cannot accept input in this way, however; in such cases, you should turn this option off.
Windows Shortcut The selected key combinations are intercepted from being sent to the
Keys DOS program and are instead sent to Windows 98 (they are Windows 98 shortcut keys). In some cases, you want your DOS program to accept some of these key combinations. When this is true, clear the checkbox for the key combination you want your DOS program to accept.

Performing a Local Reboot

Any application can freeze up from time to time and become unresponsive to the user and to the operating system. Windows 98 allows you to perform what is called a local reboot of such applications, closing them gracefully without affecting other running applications. This feature is enhanced in Windows 98 and works better than it did under Windows 95.

To perform a local reboot, press Ctrl+Alt+Delete to display the Close Program dialog box. Select the offending program (it often displays the Not Responding message next to its name in the list) and click the End Task button. Windows 98 then attempts to close the program and free up its memory resources. In some cases, after about 20 seconds, you may be prompted that the program is not responding to the Terminate command from Windows 98, and asking whether it's okay to force the application to close.

Conclusion

This chapter covered quite a lot of ground. You learned a great deal about Windows 98 architecture--how it is built and what fundamental capabilities it possesses. You also learned about how it supports the three types of applications you can use with it: Win32, Win16, and MS-DOS applications. For MS-DOS applications, you learned details about how they are configured for the Windows 98 environment.

The next chapter discusses Windows 98 device support in much greater detail. You learn about how Plug and Play works and how various hardware resources in the system are handled (such as IRQs, I/O port addresses, DMAs, and so forth).


Previous chapterNext chapterContents

Copyright, Macmillan Computer Publishing. All rights reserved.