INF: Creating Streamlined Code for Protected Mode Applications

ID Number: Q75253

3.00

WINDOWS

Summary:

If an application will be run only under one of Windows' protected

modes (standard mode or enhanced mode), and it is acceptable to allow

only one instance of the application to run at any given time, there

are techniques that can be used to create smaller, faster application

code. This article details the techniques and the factors that must be

considered when they are used.

More Information:

In Windows real mode, when Windows brings a portion of code in from

disk, other objects in memory can be moved about to make room. Every

FAR call (a call to another code segment) and every access to a

resource (menu, dialog box template, string table, and so forth) can

cause memory to move.

Windows allocates a data segment for each instance of each application

run. These data segments are objects that can be moved about as code

and resources are accessed.

Windows provides a data segment identifier to the application. This

value is placed into the DS register. The function prolog code,

generated by the C compiler when the -Gw switch is specified, stores

the value of the DS register on to the stack before any other function

code is executed. If the function changes the value of DS, the

function epilog code will restore the original value when the function

exits.

When Windows moves memory, it "walks" the stack, looking for the

stored DS values. Windows updates the stored information to reflect

the new location for the data segment.

In contrast, under Windows' protected modes, the identifier for the

data segment does not change, even when memory moves. However, because

functions may change the DS register, it is necessary to ensure that

the DS register contains the correct value. The Microsoft C Compiler,

versions 5.1 and later, provides the _loadds keyword, which instructs

the compiler to generate prolog and epilog code for a particular

function. If an application will be run only in protected mode, the

-Gw switch is not necessary. However, the _loadds modifier must be

specified for every exported function.

The restriction to a single instance is important. The code generated

by _loadds sets the DS register to point to the data segment of the

first instance of the program. The second and subsequent instances

would interfere with each other and with the first instance of the

application. The restriction to protected mode is of similar

importance. In the absence of prolog and epilog code, if the data

segment moved, the value of the DS register would not be updated to

reflect the new value; the application would use information in a

random portion of memory.

To prevent an application from running in real mode, use the Resource

Compiler -t option when binding the RES file to the EXE file.

The following code will prevent a second application of the

application from running. When an attempt is made to create a second

instance of the application, the first instance is brought to the top

and activated.

if (!hPrevInstance)

{

/* perform normal RegisterClass processing here */

}

else // This only allows one instance

{

HWND hWnd, hWnd1;

hWnd = FindWindow(szAppName, NULL);

if (IsWindow(hWnd))

{

hWnd1 = GetLastActivePopup(hWnd);

if (IsWindow(hWnd1))

hWnd = hWnd1;

BringWindowToTop(hWnd);

if (IsIconic(hWnd))

ShowWindow(hWnd, SW_RESTORE);

SetFocus(hWnd);

}

return FALSE;

}

Optionally, the -G2 switch can be specified to generate smaller and

faster code for the 80286 or later processors. Because the 8086

processor does not support protected mode, this does not exclude any

other equipment.

To summarize, an application that will run only in Windows protected

mode does not require the Windows prolog and epilog code. Applications

that are compiled without the C compiler -Gw switch must have the

following three attributes:

1. The _loadds modifier is specified for all exported functions.

2. The Resource Compiler -t switch is specified to prevent the

application from running in real mode.

3. Only one instance of the application is allowed. Use the code

provided above to enforce this restriction.