Microsoft KB Archive/105676
Starting and Terminating Windows-Based Applications
The information in this article applies to:
- Microsoft Win32 Software Development Kit (SDK) for Windows NT
A 16-bit Windows-based application running under Windows NT runs as a thread in a virtual MS-DOS machine (VDM). These threads are non-preemptively scheduled. A 16-bit Windows-based application shares an address space and an input queue with other 16-bit Windows-based applications running in the same VDM. Objects created by a thread (application) are owned by the thread (application). This environment is called WOW (Windows on Win32).
Windows NT version 3.5 introduced support for multiple WOWs, so a single 16- bit Windows-based application, or group of applications, can be run in its own address space. For additional information, please see the following article in the Microsoft Knowledge Base:
Q115235 Running a Windows-Based Application in its Own VDM
When a 16-bit Windows-based application is started by using CreateProcess() without CREATE_SEPARATE_WOW_VDM, the thread handle is meaningless, normally NULL, and the process handle is a special event handle only useful when used with one of the wait APIs like WaitForSingleObject() to detect program termination or WaitForInputIdle to detect when the app is up and fully running with no pending input.
NOTE: When you call CreateProcess() with CREATE_SEPARATE_WOW_VDM, the handles returned in the hProcess and hThread fields of the PROCESS_INFORMATION structure are valid handles. The hProcess handle is the handle to the new WOW process, but the hThread handle is the handle to the WOWEXEC thread, and not the thread of the application that you spawned. You can wait on either of these handles and you will be released when the Windows-based application terminates, because the separate VDM goes away when the last application in it terminates. Be aware that if your Windows- based application spawns another Windows-based application and terminates, the VDM stays around, because the application is run in the same VDM as the application that spawned it.
Similarly, the PROCESS_INFORMATION.dwProcessId and the PROCESS_INFORMATION.dwThreadId variables are also valid IDs when you use the CREATE_WOW_SEPARATE_VDM flag to start your 16-bit application. Just like with the handles, however, they do not directly relate to the 16-bit application but to the VDM process and the WOWEXEC thread.
CAUTION: As Microsoft Knowledge Base Article Q115235 states, separate VDMs are not free. Each separate VDM that you create consumes about 2.5MB of private memory. Creating a separate VDM just so that you can get more useful handles and/or IDs for the application is considered poor programming practice.
A common question is "How can I terminate a 16-bit process from a 32-bit process?" As implied above, PROCESS_INFORMATION.hProcess cannot be used in TerminateProcess() and PROCESS_INFORMATION.dwThreadId cannot be used in PostThreadMessage().
One way to terminate an individual 16-bit Windows-based application is to enumerate the desktop windows using EnumWindows(), determine which is the correct window, obtain the thread ID with GetWindowThreadProcessId(), and post a WM_QUIT message via PostThreadMessage() to terminate the application.
Another way to terminate an individual 16-bit Windows-based application is to use the TOOLHELP APIs. Use TaskFirst() and TaskNext() to enumerate the tasks, determine which is the correct task, and call TerminateApp() to kill the application. The Windows SDK sample THSAMPLE demonstrates how this can be done.
Additional query words: 3.50 4.00 win16 WOW VDM NTVDM
Issue type :
Technology : kbWin32SDKSearch kbAudDeveloper kbSDKSearch kbWin32sSearch
Last Reviewed: January 16, 2000