Article ID: 182559 - View products that this article applies to.
This article was previously published under Q182559
Even when programming in a 32-bit environment, there are times when working with 16-bit applications is necessary. In Windows NT, 16-bit applications run within a Virtual DOS Machine (VDM). VDMDBG.dll contains many functions that are useful for working with 16-bit applications. This library is part of the Microsoft Platform SDK.
VDMDBG functions provide a good way to enumerate, create, and terminate 16- bit processes (tasks) within a VDM. This article describes how to use these functions on Microsoft Windows NT, Windows 2000, and Windows XP.
When you use any of the VDMDBG functions, you need to link VDMDBG.lib with your project.
The VDMDBG functions mentioned below are only a subset of the available functions. However, the functions that are not mentioned are only relevant to a debugger.
Enumerating VDMsThe VDMEnumProcessWOW() function provides a simple way to enumerate all VDMs running 16-bit Windows tasks. These VDMs contain the WowExec.exe task. DOS VDMs are not enumerated.
The declaration for this function is as follows:
The return value for this function is the number of VDMs currently running, or the number enumerated before enumeration was terminated. fp is a pointer to a callback function. The function is called for each VDM that is enumerated. lParam is a user-defined value that is passed to the callback function.
PROCESSENUMPROC is declared as follows:
The function should return TRUE to stop enumeration or FALSE to continue enumeration. dwProcessId is the process ID of the NTVDM.exe process. You will need this ID when calling the other VDM functions mentioned below.
Enumerating 16-bit Windows TasksYou can use VDMEnumTaskWOW() and VDMEnumTaskWOWEx() to enumerate tasks within a particular VDM. The difference between the two is that VDMEnumTaskWOWEx() provides more information to the callback function. You should only use VDMs returned by VDMEnumProcessWOW() with these task enumeration functions. Using DOS VDMs does not make sense because every DOS application runs in its own VDM.
The declarations are:
The return value for each of these functions is the number of tasks currently running within the indicated VDM, or the number enumerated before enumeration was terminated. dwProcessId is the process ID of the VDM. fp is a pointer to a callback function. The function is called for each task that is enumerated. lparam is a user-defined value that is passed to the callback function.
TASKENUMPROC and TASKENUMPROCEX are defined as follows:
These functions should return TRUE to stop enumeration or FALSE to continue enumeration. You can use hTask16 in a call to terminate the task.
Example of Enumeration
Creating 16-bit TasksVDMStartTaskInWOW() creates a task within a VDM. The declaration is as follows:
The return value of this function is TRUE if the task is successfully started, otherwise it is FALSE. dwProcessId is the VDM process ID. lpCommandLine is a string indicating the filename of the 16-bit application along with any command-line parameters. wShow indicates how the window will be shown. wShow can be any value that is valid for the 16-bit ShowWindow() function.
Terminating 16-bit TasksTo terminate a task within a VDM call VDMTerminateTaskWOW(). The declaration is as follows:
The return value of this function is TRUE if the task is successfully terminated, otherwise it is FALSE. dwProcessId is the VDM process ID. hTask is the handle to the task. This task handle can be obtained through VDMEnumTaskWOW() or VDMEnumTaskWOWEx().
This method is a rough equivalent to TerminateProcess() in Win32. It should be avoided, if possible. It does not give the task a chance to cleanly exit, so data may be lost. Unlike Win32, the WowExec is not guaranteed to clean up after a terminated task. This can leave the VDM corrupt and unusable. To terminate the task cleanly, send a WM_CLOSE to its top-level window.
Note Regarding 16-bit DOS ApplicationsNone of the VDMDBG functions work with 16-bit DOS applications. To enumerate DOS VDMs, you need to use another method. First, you could use VDMEnumProcessWOW() to make a list of all Win16 VDMs, and then enumerate all instances of NTVDM.exe using some other scheme (such as PSAPI). Any NTVDM.exe from the full enumeration that was not in the Win16 list is a DOS VDM. You can create and terminate 16-bit DOS applications with CreateProcess() and TerminateProcess().
Article ID: 182559 - Last Review: November 21, 2006 - Revision: 3.4