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

203 lines
7.3 KiB
C

#include <windows.h> /* required for all Windows applications */
#define MAX_COMMUNICATION_BLOCK_SIZE 4096
#define DEAD_VALUE 0xFEFEFEFEL
#include <dbginfo.h>
extern BOOL FAR PASCAL WowKillRemoteTask( LPSTR lpBuffer );
int PASCAL WinMain(HANDLE hInstance,
HANDLE hPrevInstance, LPSTR lpszCmdLine, int iCmd )
{
HANDLE hCommunicationBlock;
LPSTR lpCommunicationBlock;
BOOL b;
LPCOM_HEADER lphead;
WORD wArgsPassed;
WORD wArgsSize;
WORD wSuccess;
DWORD dwReturnValue;
LPSTR lpModuleName;
LPSTR lpEntryName;
HANDLE hModule;
DWORD (FAR PASCAL *lpfn)();
BOOL fFailed;
LPWORD lpw;
// We only want 1 instance of WOWDEB
if ( hPrevInstance != NULL ) {
return( FALSE );
}
hCommunicationBlock = GlobalAlloc(GMEM_FIXED, MAX_COMMUNICATION_BLOCK_SIZE);
if ( hCommunicationBlock == (HANDLE)0 ) {
OutputDebugString("Failed to allocate memory block\n");
return( FALSE );
}
lpCommunicationBlock = GlobalLock(hCommunicationBlock);
if ( lpCommunicationBlock == NULL ) {
OutputDebugString("Failed to lock memory block\n");
return( FALSE );
}
/*
** Just make sure that TOOLHELP is loaded before we remotely kill
** ourselves.
*/
hModule = LoadLibrary( "TOOLHELP.DLL" );
dwReturnValue = DEAD_VALUE;
wSuccess = (WORD)FALSE;
do {
/*
** Initialize the communications block
*/
lphead = (LPCOM_HEADER)lpCommunicationBlock;
lphead->dwBlockAddress = (DWORD)lpCommunicationBlock;
lphead->dwReturnValue = dwReturnValue;
lphead->wArgsPassed = 0;
lphead->wArgsSize = 0;
lphead->wBlockLength = MAX_COMMUNICATION_BLOCK_SIZE;
lphead->wSuccess = (WORD)wSuccess;
b = WowKillRemoteTask( lpCommunicationBlock );
if ( !b ) {
break;
}
wSuccess = (WORD)FALSE;
dwReturnValue = 0;
/*
** Unpacketize the information and execute it
** Note: The below statements expect the contents of the structures
** to change after the above "WowKillRemoteTask" API call. If the
** compiler attempts to optimize the references below, it will get
** the wrong values.
*/
wArgsPassed = lphead->wArgsPassed;
wArgsSize = lphead->wArgsSize;
lpModuleName = lpCommunicationBlock + sizeof(COM_HEADER) + wArgsSize;
lpEntryName = lpModuleName + lstrlen(lpModuleName) + 1;
hModule = LoadLibrary( lpModuleName );
if ( hModule == 0 ) {
#ifdef DEBUG
OutputDebugString("Failed to load library\n");
#endif
continue;
}
lpfn = (DWORD (FAR PASCAL *)())GetProcAddress( hModule, lpEntryName );
if ( lpfn == NULL ) {
#ifdef DEBUG
OutputDebugString("Failed to get proc address\n");
#endif
continue;
}
// Now copy the right number of bytes onto the stack and call the
// function.
lpw = (LPWORD)(lpCommunicationBlock + sizeof(COM_HEADER));
fFailed = FALSE;
// Cheesy way of putting a variable number of arguments on the stack
// for a pascal call.
switch( wArgsPassed ) {
case 0:
dwReturnValue = (* lpfn)();
break;
case 2:
dwReturnValue = (* lpfn)( lpw[ 0] );
break;
case 4:
dwReturnValue = (* lpfn)( lpw[ 1], lpw[ 0] );
break;
case 6:
dwReturnValue = (* lpfn)( lpw[ 2], lpw[ 1], lpw[ 0] );
break;
case 8:
dwReturnValue = (* lpfn)( lpw[ 3], lpw[ 2], lpw[ 1], lpw[ 0] );
break;
case 10:
dwReturnValue = (* lpfn)( lpw[ 4], lpw[ 3], lpw[ 2], lpw[ 1],
lpw[ 0] );
break;
case 12:
dwReturnValue = (* lpfn)( lpw[ 5], lpw[ 4], lpw[ 3], lpw[ 2],
lpw[ 1], lpw[ 0] );
break;
case 14:
dwReturnValue = (* lpfn)( lpw[ 6], lpw[ 5], lpw[ 4], lpw[ 3],
lpw[ 2], lpw[ 1], lpw[ 0] );
break;
case 16:
dwReturnValue = (* lpfn)( lpw[ 7], lpw[ 6], lpw[ 5], lpw[ 4],
lpw[ 3], lpw[ 2], lpw[ 1], lpw[ 0] );
break;
case 18:
dwReturnValue = (* lpfn)( lpw[ 8], lpw[ 7], lpw[ 6], lpw[ 5],
lpw[ 4], lpw[ 3], lpw[ 2], lpw[ 1],
lpw[ 0] );
break;
case 20:
dwReturnValue = (* lpfn)( lpw[ 9], lpw[ 8], lpw[ 7], lpw[ 6],
lpw[ 5], lpw[ 4], lpw[ 3], lpw[ 2],
lpw[ 1], lpw[ 0] );
case 22:
dwReturnValue = (* lpfn)( lpw[10], lpw[ 9], lpw[ 8], lpw[ 7],
lpw[ 6], lpw[ 5], lpw[ 4], lpw[ 3],
lpw[ 2], lpw[ 1], lpw[ 0] );
break;
case 24:
dwReturnValue = (* lpfn)( lpw[11], lpw[10], lpw[ 9], lpw[ 8],
lpw[ 7], lpw[ 6], lpw[ 5], lpw[ 4],
lpw[ 3], lpw[ 2], lpw[ 1], lpw[ 0] );
break;
case 26:
dwReturnValue = (* lpfn)( lpw[12], lpw[11], lpw[10], lpw[ 9],
lpw[ 8], lpw[ 7], lpw[ 6], lpw[ 5],
lpw[ 4], lpw[ 3], lpw[ 2], lpw[ 1],
lpw[ 0] );
break;
case 28:
dwReturnValue = (* lpfn)( lpw[13], lpw[12], lpw[11], lpw[10],
lpw[ 9], lpw[ 8], lpw[ 7], lpw[ 6],
lpw[ 5], lpw[ 4], lpw[ 3], lpw[ 2],
lpw[ 1], lpw[ 0] );
break;
case 30:
dwReturnValue = (* lpfn)( lpw[14], lpw[13], lpw[12], lpw[11],
lpw[10], lpw[ 9], lpw[ 8], lpw[ 7],
lpw[ 6], lpw[ 5], lpw[ 4], lpw[ 3],
lpw[ 2], lpw[ 1], lpw[ 0] );
break;
case 32:
dwReturnValue = (* lpfn)( lpw[15], lpw[14], lpw[13], lpw[12],
lpw[11], lpw[10], lpw[ 9], lpw[ 8],
lpw[ 7], lpw[ 6], lpw[ 5], lpw[ 4],
lpw[ 3], lpw[ 2], lpw[ 1], lpw[ 0] );
break;
default:
#ifdef DEBUG
OutputDebugString("Wrong number of parameters\n");
#endif
fFailed = TRUE;
break;
}
if ( fFailed ) {
continue;
}
wSuccess = (WORD)TRUE;
} while( TRUE );
return( 1 );
}