摘要
即使是在 32位环境中编写程序,也经常碰到处理 16位应用程序的情况。在 Windows NT 中,16位程序是运行在虚拟 DOS 机(VDM)中的。VDMDBG.dll 包含许多处理16位程序的有用函数,这个库是 Platform SDK 的一部分。
VDMDBG 中的函数提供了很好的方式在 VDM 中枚举、创建和终止 16位进程(任务)。本文将描述如何在Windows NT、Windows 2000 和 Windows XP 中使用这些函数。
如果需要使用 VDMDBG 函数,你的工程必须链接 VDMDBG.lib。
下面提及的 VDMDBG 函数仅仅是一个子集。未提及的函数只与调试器有关。
枚举 VDMs
VDMEnumProcessWOW() 函数提供了一种简单的方式来枚举所有 运行 Windows 任务的 VDMs。这些 VDMs 包含 WowExec.exe 任务。DOS VDMs 不在枚举之列。 该函数的声明如下:INT WINAPI VDMEnumProcessWOW( PROCESSENUMPROC fp, LPARAM lparam );
该函数的返回值是当前运行的 VDMs 数,或者终止枚举前的枚举数目。fp 是一个回调函数指针。该函数针对被枚举的 VDM 被调用一次。lParam 是用户定义的值,这个值被传递给回调函数。
PROCESSENUMPROC 的声明如下:
typedef BOOL ( WINAPI *PROCESSENUMPROC )(
DWORD dwProcessId,
DWORD dwAttributes,
LPARAM lpUserDefined
);
这个函数返回 TRUE 停止枚举,返回 FALSE 继续枚举。dwProcessId 是 NTVDM.exe 进程ID。在调用其它VDM函数时(下面会提到这些函数),你会需要此 ID。
枚举 16-位 Windows 任务
你可以用 VDMEnumTaskWOW() 和 VDMEnumTaskWOWEx() 在特定的 VDM 中枚举任务。两者的差别是 VDMEnumTaskWOWEx() 为回调函数提供更多的信息。你只能使用 VDMEnumProcessWOW() 返回的 VDMs 来调用这些任务枚举函数。用 DOS VDMs 是没有意义的,因为 DOS 应用程序运行在自己的 VDM 中。这两个函数的恶声明如下:
INT WINAPI VDMEnumTaskWOW( DWORD dwProcessId, TASKENUMPROC fp,LPARAM lparam );
INT WINAPI VDMEnumTaskWOWEx( DWORD dwProcessId, TASKENUMPROCEX fp,
LPARAM lparam );
这两个函数的返回值是当前运行在指定 VDM 中的任务数,或者每局终止前的枚举数。dwProcessId 是 VDM 的恶进程ID。fp 是指向回调函数的指针。每个被枚举的任务都调用该函数。lparam 是传给回调函数的用户定义的值。
TASKENUMPROC 和 TASKENUMPROCEX 的定义如下:
typedef BOOL ( WINAPI *TASKENUMPROC )(
DWORD dwThreadId,
WORD hMod16,
WORD hTask16,
LPARAM lpUserDefined
);
typedef BOOL ( WINAPI *TASKENUMPROCEX )(
DWORD dwThreadId,
WORD hMod16,
WORD hTask16,
PSZ pszModName,
PSZ pszFileName,
LPARAM lpUserDefined
);
这些函数返回 TRUE 停止枚举,返回 FALSE 继续枚举。你可以在某个调用中用 hTask16 终止任务。