windows-nt/Source/XPSP1/NT/base/mvdm/vdmdbg/wow.c
2020-09-26 16:20:57 +08:00

374 lines
8.4 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
wow.c
Abstract:
This module contains the WOW vdmdbg functions
Revision History:
--*/
#include <precomp.h>
#pragma hdrstop
typedef WORD HAND16;
#define SHAREWOW_MAIN
#include <sharewow.h>
//----------------------------------------------------------------------------
// VDMKillWOW()
//
// Interface to kill the wow sub-system. This may not be needed and is
// certainly not needed now. We are going to look into fixing the
// debugging interface so this is not necessary.
//
//----------------------------------------------------------------------------
BOOL
WINAPI
VDMKillWOW(
VOID
) {
return( FALSE );
}
//----------------------------------------------------------------------------
// VDMDetectWOW()
//
// Interface to detect whether the wow sub-system has already been started.
// This may not be needed and is certainly not needed now. We are going
// to look into fixing the debugging interface so this is not necessary.
//
//----------------------------------------------------------------------------
BOOL
WINAPI
VDMDetectWOW(
VOID
) {
return( FALSE );
}
INT
WINAPI
VDMEnumProcessWOW(
PROCESSENUMPROC fp,
LPARAM lparam
) {
LPSHAREDTASKMEM lpstm;
LPSHAREDPROCESS lpsp;
DWORD dwOffset;
INT count;
BOOL f;
HANDLE hProcess;
/*
** Open the shared memory window
*/
lpstm = LOCKSHAREWOW();
if ( lpstm == NULL ) {
// Wow must not be running
return( 0 );
}
//
// Now traverse through all of the processes in the
// list, calling the callback function for each.
//
count = 0;
dwOffset = lpstm->dwFirstProcess;
while ( dwOffset != 0 ) {
lpsp = (LPSHAREDPROCESS)((CHAR *)lpstm + dwOffset);
if ( lpsp->dwType != SMO_PROCESS ) {
// Some memory corruption problem
OutputDebugString("VDMDBG: Shared memory object is not a process? (memory corruption)\n");
return( 0 );
}
//
// Make sure the process hasn't gone away because of a
// crash or other rude shutdown that prevents cleanup.
//
hProcess = OpenProcess(
SYNCHRONIZE,
FALSE,
lpsp->dwProcessId
);
if (hProcess) {
CloseHandle(hProcess);
count++;
if ( fp ) {
f = (*fp)( lpsp->dwProcessId, lpsp->dwAttributes, lparam );
if ( f ) {
UNLOCKSHAREWOW();
return( count );
}
}
} else {
//
// This is a ghost entry, change the process ID to zero
// so that the next WOW started will be sure to remove
// this entry even if the process ID is recycled.
//
lpsp->dwProcessId = 0;
}
dwOffset = lpsp->dwNextProcess;
}
UNLOCKSHAREWOW();
return( count );
}
INT
WINAPI
VDMEnumTaskWOWWorker(
DWORD dwProcessId,
void * fp,
LPARAM lparam,
BOOL fEx
) {
LPSHAREDTASKMEM lpstm;
LPSHAREDPROCESS lpsp;
LPSHAREDTASK lpst;
DWORD dwOffset;
INT count = 0;
BOOL f;
//
// Open the shared memory window
//
lpstm = LOCKSHAREWOW();
if ( lpstm == NULL ) {
// Wow must not be running
return( 0 );
}
//
// Now traverse through all of the processes in the
// list, looking for the one with the proper id.
//
dwOffset = lpstm->dwFirstProcess;
while ( dwOffset != 0 ) {
lpsp = (LPSHAREDPROCESS)((CHAR *)lpstm + dwOffset);
if ( lpsp->dwType != SMO_PROCESS ) {
// Some memory corruption problem
OutputDebugString("VDMDBG: shared memory object is not a process? (memory corruption)\n");
UNLOCKSHAREWOW();
return( 0 );
}
if ( lpsp->dwProcessId == dwProcessId ) {
break;
}
dwOffset = lpsp->dwNextProcess;
}
if ( dwOffset == 0 ) { // We must not have found this Id.
UNLOCKSHAREWOW();
return( 0 );
}
//
// Now enumerate all of the tasks for this process
//
dwOffset = lpsp->dwFirstTask;
while( dwOffset != 0 ) {
lpst = (LPSHAREDTASK)((CHAR *)lpstm + dwOffset );
if ( lpst->dwType != SMO_TASK ) {
// Some memory corruption problem
OutputDebugString("VDMDBG: shared memory object is not a task? (memory corruption)\n");
UNLOCKSHAREWOW();
return( 0 );
}
count++;
if ( fp && lpst->hMod16 ) {
if (fEx) {
f = ((TASKENUMPROCEX)fp)( lpst->dwThreadId, lpst->hMod16, lpst->hTask16,
lpst->szModName, lpst->szFilePath, lparam );
} else {
f = ((TASKENUMPROC)fp)( lpst->dwThreadId, lpst->hMod16, lpst->hTask16, lparam );
}
if ( f ) {
UNLOCKSHAREWOW();
return( count );
}
}
dwOffset = lpst->dwNextTask;
}
UNLOCKSHAREWOW();
return( count );
}
INT
WINAPI
VDMEnumTaskWOW(
DWORD dwProcessId,
TASKENUMPROC fp,
LPARAM lparam
) {
return VDMEnumTaskWOWWorker(dwProcessId, (void *)fp, lparam, 0);
}
INT
WINAPI
VDMEnumTaskWOWEx(
DWORD dwProcessId,
TASKENUMPROCEX fp,
LPARAM lparam
) {
return VDMEnumTaskWOWWorker(dwProcessId, (void *)fp, lparam, 1);
}
BOOL
WINAPI
VDMTerminateTaskWOW(
DWORD dwProcessId,
WORD htask
)
{
BOOL fRet = FALSE;
LPSHAREDTASKMEM lpstm;
LPSHAREDPROCESS lpsp;
LPSHAREDTASK lpst;
DWORD dwOffset;
INT count;
HANDLE hProcess;
HANDLE hRemoteThread;
DWORD dwThreadId;
//
// Open the shared memory window
//
lpstm = LOCKSHAREWOW();
if ( lpstm == NULL ) {
// Wow must not be running
return( 0 );
}
//
// Now traverse through all of the processes in the
// list, looking for the one with the proper id.
//
dwOffset = lpstm->dwFirstProcess;
while ( dwOffset != 0 ) {
lpsp = (LPSHAREDPROCESS)((CHAR *)lpstm + dwOffset);
if ( lpsp->dwType != SMO_PROCESS ) {
// Some memory corruption problem
OutputDebugString("VDMDBG: shared memory object is not a process? (memory corruption)\n");
goto UnlockReturn;
}
if ( lpsp->dwProcessId == dwProcessId ) {
break;
}
dwOffset = lpsp->dwNextProcess;
}
if ( dwOffset == 0 ) { // We must not have found this Id.
goto UnlockReturn;
}
//
// Get a handle to the process and start W32HungAppNotifyThread
// running with htask as the parameter.
//
hProcess = OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
lpsp->dwProcessId
);
if (hProcess) {
hRemoteThread = CreateRemoteThread(
hProcess,
NULL,
0,
lpsp->pfnW32HungAppNotifyThread,
(LPVOID) htask,
0,
&dwThreadId
);
if (hRemoteThread) {
fRet = TRUE;
CloseHandle(hRemoteThread);
}
CloseHandle(hProcess);
}
UnlockReturn:
UNLOCKSHAREWOW();
return fRet;
}
BOOL
VDMStartTaskInWOW(
DWORD pidTarget,
LPSTR lpCommandLine,
WORD wShow
)
{
HWND hwnd = NULL;
DWORD pid;
BOOL fRet;
do {
hwnd = FindWindowEx(NULL, hwnd, TEXT("WowExecClass"), NULL);
if (hwnd) {
pid = 0;
GetWindowThreadProcessId(hwnd, &pid);
}
} while (hwnd && pid != pidTarget);
if (hwnd && pid == pidTarget) {
#define WM_WOWEXEC_START_TASK (WM_USER+2)
PostMessage(hwnd, WM_WOWEXEC_START_TASK, GlobalAddAtom(lpCommandLine), wShow);
fRet = TRUE;
} else {
fRet = FALSE;
}
return fRet;
}