25 Jun 1995

Windows 3.1 Programs

If somebody buys a new computer today, it will probably come with Windows 3.1 installed. When the machine boots up, it first loads some version of DOS 6.x including device drivers from CONFIG.SYS and resident routines in AUTOEXEC. In particular, the DOS drivers HIMEM and EMM386 provide basic management of the RAM memory above the first megabyte and SMARTDRV provides a disk cache to improve I/O performance. The last statement in AUTOEXEC typically starts up Windows.

Windows depends on the DOS drivers and the BIOS to support the floppy disk, hard drive, and CDROM file system. The primary function of Windows is to supply the WIMPS interface (Windows, Icons, Mouse, Pointer, Scroll-Bars). To accomplish this, most of the Windows code consists of routines to manage buttons, boxes, menus, drop-down lists, and other dialog components. This code is so large that it cannot reasonably fit in the old DOS 640K. Windows is therefore forced to exploit the entire RAM memory.

The HIMEM and EMM386 drivers provide very primitive memory management, Windows must add its own much more sophisticated algorithms. In particular, Windows programs and libraries have to be loaded and run in the addresses above one megabyte.

Windows does provide some device support, but it concentrates on the devices that have the greatest effect on the user interface. During the installation of Windows, a user selects a type of display adapter (including the resolution, number of colors, and refresh rate), a type of keyboard, and a type of mouse. Windows continues to defer to DOS to handle file systems and disk devices.

To the application program, Windows appears to be a large collection of subroutines that draw boxes and text on the screen or on the printer page. There are also a smaller collection of routines that load programs, allocate storage, and manage timers and the COM port.

To Windows, the application program appears as a subroutine that should be called when the user moves the mouse into a particular area of the screen and clicks a button or presses a key on the keyboard. Windows passes the application subroutine information about the event, and the application then calls other routines to change the screen in response.

Anyone who has ever written a computer program knows that a mistake in a subroutine will crash the program that calls it. Without any formal distinction between the programs and the system, Windows is vulnerable to errors in any program that it runs. If most PC users developed there own programs, the way that mainframe and minicomputer users have traditionally coded, then the system would crash so frequently that it would be unusable.

However, PC users tend to run only a small number of thoroughly tested commercial applications from companies like Microsoft, Lotus, and Novell. These programs occasionally fail, but they run most of the time and that appears to be good enough. When end users develop their own "programs" they use languages such as Visual Basic or Excel macros that limit the possible kinds of damage.

The limitations of Windows were clear from the very beginning. The solution was also understood by everyone familiar with mainframes, VAX minicomputers, or Unix. Ultimately, the computer needed a "real" operating system that could control the programs, isolating them from each other and from the system control blocks where the real damage could occur. In 1985 IBM and Microsoft began development of a better system, and in 1988 they delivered the first versions of OS/2. The OS/2 Presentation Manager had essentially the same user interface as Windows, but it ran each application in its own isolated memory area and maintained a clean, protected interface between the system and applications.

Meanwhile, Microsoft continued to develop the old Windows system and released Version 3.0 during the summer of 1990. Although it lacked the structural integrity of OS/2, it ran faster and used less memory. The applications were eventually debugged so that they work fairly well most of the time. This success provides a warning that users are strongly influenced by appearance and cost, and give very little consideration to underlying structure.

Memory Management

Windows provides two memory management schemes. In Standard mode, which was designed to the capabilities of the 286 CPU chip, programs are divided into sectors. Each sector is of variable length up to 64K bytes. Sectors can reside in extended memory or they can be swapped to a file on disk. This arrangement tends to save memory, but it produces a massive housekeeping burden on the CPU to manage and move the odd sized sectors around in memory.

On a 386/486/Pentium system, Windows runs in Enhanced mode. Memory is divided into 4K pages. Program or library sectors are rounded up to the nearest 4K and are then chopped up into pages. Rounding tends to use more memory, but pages are interchangeable and can be allocated, freed, and reused at will. Memory can be logically extended with a disk file. A machine with eight megabytes of RAM and an eight megabyte disk file can be treated as having sixteen megabytes of logical memory in which to store programs and libraries.

Although there are still millions of 286 computers in use, the latest releases of most Windows programs will not run on them. Meaningful use of Windows requires at least a 386 CPU and four or more megabytes of RAM.

DLLs

Collections of useful routines that perform common functions are gathered together into Dynamic Link Libraries (DLLs). A DLL is simply a special form of EXE module with no main entry point. It contains parts of programs, but is not itself an application. Routines in the DLL are "exported" by name. These routines are added to a table that allows other programs to call the routine and request the service.

In this example, the PSYCHIC DLL has a routine that picks winning Lottery numbers. It simply chooses the number, it does not know how to communicate to the user. A separate program called BETLOTTO is written. It calls the "picknum" routine to get the numbers, then displays them on the screen so the user can make the right bet. PSYCHIC.DLL contains the "picknum" routine and exports it; BETLOTTO calls the picknum routine and therefore imports it.

While DOS requires that a service be already loaded into memory before it can be used by another program, Windows does contain the more sophisticated memory and program management needed to load modules on demand. That is why a Dynamic Link Library is Dynamic. In this example, loading the BETLOTTO.EXE program will cause Windows to locate and load the PSYCHIC.DLL module at the same time. If more than one program uses routines in PSYCHIC.DLL, only one copy will be loaded and they will all share it. When all the applications end, Windows will free the storage that PSYCHIC.DLL occupied. If it is needed again, a fresh copy can be loaded from disk.

Programming tools built two types of modules. A normal application program or utility is an EXE file. A library is a DLL file. However, once you build a library module you can rename it to any other file type and it still remains a library. Windows has a number of categories of DLL with special qualifiers:

EXE - To be confusing, Windows names its three most important DLL modules (USER, GDI, and KRNL386) with the qualifier of EXE normally used by programs. They are not programs. They are misnamed DLLs.

DRV - During Windows installation, the user selects a particular type of keyboard, mouse, display, and printer. DLLs that contain support for a particular type of a general device typically have the DRV file type.

VBX - Visual Basic "custom controls" package certain types of screen design elements. Other languages are beginning to support VBX libraries as well.

A generic Windows 3.1 environment would then have three categories of DLL routine. The three key libraries that have the most import application services are the three misnamed EXE modules (USER, GDI, and KRNL). Windows then has what amounts to a set of slots into which one must insert one selected driver for the keyboard (KBDUS.DRV for standard American key layout), display (S3.DRV for the popular S3 family of chips), mouse (MOUSE.DRV). The sound card and printer drivers are optional.

The last category of modules retains the DLL file type. They typically reside in the \WINDOWS\SYSTEM directory, although they can be anywhere in the path. The provide support for additional program interfaces. NETAPI provides routines associated with network servers. OLE provides the Microsoft conventions for application programs to cooperate editing compound documents. ODBC is a generic support to various database managers. WINSOCK would provide access to the Internet.

A DLL exports routines that the application program calls directly. The DLL routine runs as an extension of the application program. On a 386 or better CPU, Windows can run in Enhanced mode, using more advanced memory management to provide some isolation and protection against program errors. This provides a logical barrier between applications and some Windows components, particularly those that access memory at the hardware level, bypassing the memory management. The supervisory functions of Windows on the other side of this barrier can be extended by a special kind of DLL called a VxD. VxD's were originally designed to manage devices, but they are also used to extend system services.

Events

An application program calls a DLL routine to request a Windows service. All Windows application program also export one of their own routines to handle events.

Any Windows program is driven by events. The event can be the user clicking the mouse, or pressing a key on the keyboard, or the end of some time period. Each Windows program supplies a routine to receive and handle such events. Windows calls the event handling routine in essentially the same way that the application program calls a Windows DLL routine requesting service. In some languages, the direct event handler is supplied by the language and the event is then translated into a call to a Visual Basic routine or a C++ method.

Since applications can be interconnected, and windows appear within windows, there may be several handler routines that could possibly receive an event. The Windows rule is to start with the handler for the window "on top" of everything else, then work down until one of the handlers recognizes and accepts the event.

Although Windows may run several application programs at once, each program gets a chance to execute when its event handling routine is called, and it stops executing when it returns back to the Windows system after handing the event. If it takes too long, the user sees an hourglass pointer as an indication that the application is busy. A program cannot perform a long and complicated operation except by holding the CPU and gumming up the user interface.

System Buffers

Windows 3.1 uses the services of BIOS, DOS, and DOS device drivers. Whenever it is necessary to perform I/O to the network, Windows becomes an ordinary DOS application and makes a standard service request. However, the DOS rules require that any data buffers reside in the first megabyte of memory. Therefore, Windows allocates buffers in the first 640K of storage, and it moves data between application buffers in Windows memory and these utility buffers in the DOS area.

SYSTEM.INI

Any release of Windows has only one copy of the USER, GDI, and KRNL386 modules. There are many possible screen, mouse, or sound card drivers. Network access could be provided to Novell, NT, IBM, Banyan, or other servers. Different devices or networks are supported by different DLL modules.

When Windows starts up, it reads the \WINDOWS\SYSTEM.INI file. This file contains the configuration established during installation or modified subsequently by Windows Setup or by the Control Panel. Statements in SYSTEM.INI tell Windows which DLL module to use for each system function.

display.drv=s3flat.drv
shell=progman.exe
network.drv=
language.dll=langeng.dll

This excerpt from SYSTEM.INI tells Windows to use a display driver for the S3 chip set, load the standard Program Manager, expect that there is no network support installed, and expect an English speaking user. These standard parameters are widely understood and are maintained by SETUP and most utilities. Other parameters are added to support unusual devices, special processing, or advanced applications. It is not unreasonable to claim that SYSTEM.INI has the same function for WINDOWS that CONFIG.SYS has for DOS itself.

Problems can arise in SYSTEM.INI when Windows is "upgraded" across versions. Since some statements can be added to this file to support an ISDN communications adapter or Ada language compiler, no upgrade can ever expect to identify every statement in the file. An upgrade will change the standard statements like "display.drv=" that it understands. It will ignore statements of the form:

[386Enh]
DEVICE=MWAVE.386
DEVICE=VMWGames.386

This particular sequence adds a hardware device driver for one of the IBM MWave modem or sound cards. It also adds support so that some DOS games designed for a Creative Labs SoundBlaster card will run on an IBM MWave sound card. These drivers work in Windows 3.1. They will not be removed when the Windows system is upgraded to Chicago. The drivers will then not work on the advanced system and the statements must be removed manually.

When Windows is upgraded, the new version may alter the old SYSTEM.INI statements that it understands. When it encounters an unrecognized statement, it will generally ignore it. Maybe the strange driver will run in the new system. If not, then the end user will have to edit SYSTEM.INI and remove the statements manually.

New releases of the same code from the same vendor will properly upgrade earlier configuration files. However, the changes that Microsoft made from Windows 3.1 to Windows 3.11 or from Plain Old Windows to Windows for Workgroups took time to become widely understood. The original version of OS/2 for Windows would not install on 3.11 or WFWG, and it took several months before IBM was able to produce a patch to smarten up its installation process.

VxDs

An application program views itself as a collection of segments. The physical reality on a 386 is that the program has been chopped up into 4K pages scattered throughout extended storage. This is important to the system, because pages are much easier to allocate, administer, and control. The memory management tables in the CPU hide the reality of pages and allow the program to think it is occupying large contiguous areas of memory.

Windows can be extended by installing new DLL modules. A DLL routine, however, is called directly by an application program and inherits the environment of the caller. In particular, the DLL is unaware that it, as well as the application, has been chopped up into little 4K pages. This doesn't matter, because most Windows programs do not depend on an accurate hardware level view of memory.

However, if a Windows program manages a hardware device, then it may need a physically accurate view of the system. Ordinary devices receive data one or two bytes at a time from the program running on the CPU. High performance devices (disk controllers, LAN adapters, and sound cards for example) often support Direct Memory Access or Busmaster support where the driver simply points to the hardware location of the buffer and the device transfers bytes as needed to or from memory. To support DMA, the driver must have access to the memory management tables to locate the scattered pages that form part of the buffer. A routine that provides this support in Windows is called a VxD.

The simplest formula is to say that VxD's serve for Windows the same function that device drivers serve for DOS, OS/2, or Unix. A lot of the time they manage adapter cards, disks, timers, or communication ports. Occasionally, the extend the standard system services with some additional function that requires access to the physical hardware or memory management tables. The VxD is the only Windows component or extension that has access both to the "hardware" view of the computer as raw RAM and I/O devices generating interrupts and to the "application" view of segments, pages, and an event queue. The VxD can move data between application buffers and real memory buffers. It can convert hardware interrupts into events.

The previous section showed statements that install the MWAVE.386 VxD for the MWave modem or audio card. Such a card will have a Digital Signal Processor chip, RAM, and an onboard operating system. Programs are loaded onto the card for playing recorded sound, synthesizing music, or modem functions. The DSP chip generates interrupts, by default on IRQ 15.

Most sound cards operate on some form of Direct Memory Access. A Windows application loads some recorded sound from a *.WAV file into a buffer. It then passes the address of the buffer and its length to the DMA logic of the sound card. The card plays the recorded sound in the background, while Windows displays information or pictures on the screen. When the buffer is exhausted, an interrupt is generated to allow the program to switch buffers. The application program may believe that it is building buffers in 64K segments, but hardware would see the data scatter around in much smaller 4K pieces. The MWAVE.386 VxD deals with the fragmented buffers, manages the DMA, and handles the interrupts.

Once VxD's had been created, programmers found that they were a useful way to circumvent any restriction in the Windows architecture. Some backup programs use a VxD to maximize performance. Visual C++ has a VxD to help its program development environment VxD's may have to be rewritten for Chicago, and they are not supported in OS/2 or NT.

There has been a general trend in Windows 3.x to expand the number of VxD routines and the amount of Windows services that they provide. Windows for Workgroups 3.11 contains VxD routines to manage the network adapter, network protocols, disk I/O, and FAT file system.

WIN32S

The 386/486/Pentium CPU chips allow programs to run in both 16-bit and 32-bit addressing modes. In 16-bit mode, a large program is chopped up into numbered segments each no larger than 64K. In 32-bit mode, a program manipulates one large storage area. A 32-bit program is generally larger, but because it does not have to manage the numbered segments it typically runs a bit faster.

The real push for 32-bit programming is portability. The 16-bit operation is unique to the Intel CPU family. All the other processors (Macintosh 680x0, PowerPC, Alpha, MIPS) run only in 32-bit mode. Unix is a 32-bit system. Creating any large body of portable, reusable application code requires 32-bit support. Applications that regularly manipulate sound or images (data items often much larger than 64K) may run a great deal faster in 32-bit mode.

The application program interface designed originally for Windows 3.x is called WIN16. Physically, WIN16 is a collection of routines packaged in Windows system DLL modules that provide the graphic user interface, passthrough access to DOS services, and network client functions. To this, Microsoft has added the WIN32 program interface for programs running in 32-bit mode. Again, WIN32 is packaged as a set of DLL routines. In addition to all the WIN16 services, WIN32 adds features available in Windows NT, such as multithreading, security, improved error recovery, and storage isolation.

To promote 32-bit programming, Microsoft offers a subset of the WIN32 interface as an option for Windows 3.1 and WFWG 3.11. Designated WIN32S, this subset supports 32-bit application programs provided that they call only the 32-bit version of WIN16 services. This is one of three versions of WIN32 support:

  1. The Windows 3.1 system is natively a 16-bit operating system. WIN32S allows 32-bit programs to run under it, but it adds no additional system services. WIN32S is packaged as a new set of DLL routines that receive 32-bit calls, repackage the request into a corresponding old WIN16 request, and then pass it on to the traditional Windows system.

  2. Chicago is a hybrid system with a mixture of 16-bit and 32-bit components. There is no native mode of execution. Some WIN16 requests have to be converted to 32-bit calls where a system service has been recently rewritten. Some WIN32 requests have to be converted back to 16-bit calls when the system support hasn't be changed. Chicago includes some advanced features (such as multithreading) but does not include other features (such as security).

  3. Windows NT is natively a 32-bit operating system. The only real system services are WIN32. There is a separate subsystem running in its own address space that manages the WIN32 requests. Applications written to WIN32 run in their own address spaces. All the WIN16 applications are lumped together in a single virtual machine. Their WIN16 requests are trapped by 16-bit DLL's loaded into the virtual machine, are then converted to WIN32 requests, and are passed on to the subsystem.

WIN32S is installed into Windows 3.1 or WFWG by running SETUP and loading files off two diskettes. It provides a set of DLL's and VxD's that support 32-bit application programs and convert all calls to the WIN16 interface.

The process of translating between 16-bit and 32-bit addresses is called Thunking. The translation requires only a few instructions, unless more than one 16-bit segment is involved. Window NT is internally a completely 32-bit system, so when old 16-bit Windows applications run in it all requests have to be thunked up to 32-bits. Windows 3.1 is an entirely 16-bit system, so when 32-bit programs run under WIN32S, all of the calls have to be thunked down to 16-bit. Chicago is a hybrid. Generally in Chicago, GUI calls (windows, menus, dialogs, boxes) are thunked down to 16-bit and kernel calls (storage, tasks, I/O) are thunked up to 32-bit.

Although the term "32-bit" applies to both WIN32S and to VxD's, it has two quite different meanings. WIN32S is a program interface that allows the 32-bit applications to run on what is basically a 16-bit operating system. The calling program runs in 32-bit mode, but the internal work is done in 16-bit mode. A VxD is the only part of the Windows systems that is written to do work in 32-bit mode. However, the VxD is a device driver that supports the ordinary 16-bit Windows applications.

Conclusions

In addition to providing a graphic user interface, Windows provides memory and program management that allows application programs and support routines to be loaded into memory above the first megabyte. However, Windows 3.1 remains dependent on DOS, the DOS device drivers, resident routines loaded from AUTOEXEC, and the BIOS to perform I/O requests. In some cases, information must be moved from the user buffers to buffers allocated in the first 640K area of memory to accommodate the restrictions of these drivers.

Low level control of the page tables and memory mapping features of the Intel CPU is provided by the Virtual Machine Manager (VMM). Its 32-bit global view of raw hardware memory is also shared by Virtual Device Drivers (VxDs) that either perform I/O or provide extended memory management services to the applications.

All the other Windows functions (screen management, program loading, mouse events, dialogs, INI files) are provided through routines packages as Dynamic Link Libraries (DLL modules). When a DLL is needed, it is found in the path and is loaded into memory. It is then shared by all the programs that need it. When it is no longer required, it can be deleted from memory. All Windows services are supplied by DLL routines, but they sometimes have different extensions (DLL, EXE, DRV, VBX). In Windows 3.x, all the system DLL's operate in 16-bit mode.

The Windows 3.x system looks like a package of subroutines to the application program, but the application also looks like an event handling subroutine to Windows. If someone watches the way that execution flows through the system, Windows 3.x looks like one great big program with a lot of subroutine libraries. Without clear boundaries, proper cleanup cannot be guaranteed. An application failure can crash Windows, or can leave the system so unstable that it has to be rebooted anyway.

Microsoft provides an optional upgrade to Windows 3.x called WIN32S. It provides changes to the Virtual Machine Manager and VxD's to create a "flat" address space for 32-bit programs. It also provides a complete set of dummy 32-bit routines packaged as DLL modules so that the 32-bit programs can make a subset of the WIN32 program calls. WIN32S does not, however, change the core Windows libraries (USER, GDI, KRNL, or the DRV modules). All work to support WIN32S programs is still done by the traditional 16-bit system routines.

Continue Back PCLT

Copyright 1995 PCLT -- Surviving the Next Operating System -- H. Gilbert

This document generated by SpHyDir, another fine product of PC Lube and Tune.