PRB: WinExec() Fails Due to Memory Not De-allocated (126710)
The information in this article applies to:
- Microsoft Win32s 1.3c
- Microsoft Win32s 1.15
- Microsoft Win32s 1.2
- Microsoft Win32s 1.25
- Microsoft Win32s 1.3
- Microsoft Win32s 1.30a
This article was previously published under Q126710 SYMPTOMS
Under Win32s version 1.15, when a Win32-based application spawns a 16-bit
application several times using WinExec(), after a few successful spawns,
WinExec() fails.
Each time WinExec() is called to start a 16-bit application, Win32s
allocates a fixed and page-locked block. The owner of this block is the
Win32-based application. The memory is not de-allocated when the 16-bit
application is terminated, only when the 32-bit application is terminated.
CAUSE
This is actually a bug in Windows version 3.1. The 32-bit WinExec() calls
the 16-bit LoadModule(). Win32s passes the environment of the calling
process to LoadModule(). Then the Windows 3.1 LoadModule() allocates a
buffer for the environment, copies this environment to the buffer, and
passes this buffer to the child process. The problem is that the owner of
the new allocated buffer is the parent, so the memory is freed when the
parent exits. There is no code for otherwise freeing the memory. This bug
also affects 16-bit Windows-based applications if LoadModule() is called
with an environment selector that is not NULL.
In a related problem, when the parent terminates, the child's environment
becomes invalid. This may cause a general protection (GP) fault.
RESOLUTION
To work around the problem, you can call the Windows version 3.1 WinExec()
through the Universal Thunk. However, the parent will not be able to modify
the child's environment.
In Win32s version 1.2x and later, this problem exists only if you start 16-
bit application using CreateProcess() or LoadModule() and pass it explicit
environment strings. In this case, you will encounter the Windows version
3.1 bug. If you do not pass an explicit environment, the environment passed
to the 16-bit application is NULL. This resolves the problems mentioned in
the Symptoms and Cause sections of this article.
MORE INFORMATION
With the changes in Win32s version 1.2x, if the calling application
modifies the environment, the child process will not get the modified
environment of the parent. It will get the global MS-DOS environment. This
is also true for WinExec().
If you need to pass a modified environment, call LoadModule() or
CreateProcess() with the environment set to what GetEnvironmentStrings()
returns. Be aware that this will cause a memory leak. In addition, if the
parent terminates before the child, the child's environment will become
invalid.
Modification Type: | Major | Last Reviewed: | 3/15/2004 |
---|
Keywords: | KB126710 |
---|
|