mirror of
https://github.com/reactos/reactos.git
synced 2025-05-22 02:25:18 +00:00
[NTVDM][DDK]
Implement VDD user hooks: they are called when a DOS program is started or terminated, and when the VM enters a blocking state or is resumed. [NTVDM] - Do some parameter checks and set last errors in VDD memory helpers. - Fix a bug in VDDInstallIOHook when installing IO hooks: the IoHandlers pointer MUST NEVER be incremented!! [TESTVDD]: Update my test VDD with tests for the user hooks. svn path=/trunk/; revision=67671
This commit is contained in:
parent
7f03ff50e9
commit
16d08be7b0
9 changed files with 439 additions and 99 deletions
|
@ -39,6 +39,47 @@ WINAPI
|
|||
VDDTerminateVDM(VOID);
|
||||
|
||||
|
||||
/* VDD User Hooks */
|
||||
|
||||
typedef VOID
|
||||
(WINAPI *PFNVDD_UCREATE)(USHORT DosPDB);
|
||||
|
||||
typedef VOID
|
||||
(WINAPI *PFNVDD_UTERMINATE)(USHORT DosPDB);
|
||||
|
||||
typedef VOID
|
||||
(WINAPI *PFNVDD_UBLOCK)(VOID);
|
||||
|
||||
typedef VOID
|
||||
(WINAPI *PFNVDD_URESUME)(VOID);
|
||||
|
||||
// NOTE: Kept there for WinDDK compatibility, but it is in any case unused.
|
||||
#ifndef NO_NTVDD_COMPAT
|
||||
typedef struct _VDD_USER_HANDLERS {
|
||||
HANDLE hvdd;
|
||||
PFNVDD_UCREATE ucr_handler;
|
||||
PFNVDD_UTERMINATE uterm_handler;
|
||||
PFNVDD_UBLOCK ublock_handler;
|
||||
PFNVDD_URESUME uresume_handler;
|
||||
struct _VDD_USER_HANDLERS* next;
|
||||
} VDD_USER_HANDLERS, *PVDD_USER_HANDLERS;
|
||||
#endif
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
VDDInstallUserHook(
|
||||
_In_ HANDLE hVdd,
|
||||
_In_ PFNVDD_UCREATE Ucr_Handler,
|
||||
_In_ PFNVDD_UTERMINATE Uterm_Handler,
|
||||
_In_ PFNVDD_UBLOCK Ublock_Handler,
|
||||
_In_ PFNVDD_URESUME Uresume_Handler);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
VDDDeInstallUserHook(
|
||||
_In_ HANDLE hVdd);
|
||||
|
||||
|
||||
/* IRQ services */
|
||||
|
||||
WORD
|
||||
|
@ -122,7 +163,7 @@ VDDInstallIOHook(
|
|||
_In_ HANDLE hVdd,
|
||||
_In_ WORD cPortRange,
|
||||
_In_ PVDD_IO_PORTRANGE pPortRange,
|
||||
_In_ PVDD_IO_HANDLERS IOhandler);
|
||||
_In_ PVDD_IO_HANDLERS IoHandlers);
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "io.h"
|
||||
#include "hardware/ps2.h"
|
||||
|
||||
#include "vddsup.h"
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static inline VOID DosSetPspCommandLine(WORD Segment, LPCSTR CommandLine)
|
||||
|
@ -509,6 +511,9 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
|||
setSS(LoadSegment + Header->e_ss);
|
||||
setSP(Header->e_sp);
|
||||
|
||||
/* Notify VDDs of process execution */
|
||||
VDDCreateUserHook(Segment);
|
||||
|
||||
/* Execute */
|
||||
DosSetProcessContext(Segment);
|
||||
CpuExecute(LoadSegment + Header->e_cs, Header->e_ip);
|
||||
|
@ -596,6 +601,9 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
|||
*/
|
||||
*((LPWORD)SEG_OFF_TO_PTR(Segment, 0xFFFE)) = 0;
|
||||
|
||||
/* Notify VDDs of process execution */
|
||||
VDDCreateUserHook(Segment);
|
||||
|
||||
/* Execute */
|
||||
DosSetProcessContext(Segment);
|
||||
CpuExecute(Segment, 0x100);
|
||||
|
@ -613,7 +621,7 @@ Cleanup:
|
|||
{
|
||||
/* It was not successful, cleanup the DOS memory */
|
||||
if (EnvBlock) DosFreeMemory(EnvBlock);
|
||||
if (Segment) DosFreeMemory(Segment);
|
||||
if (Segment) DosFreeMemory(Segment);
|
||||
}
|
||||
|
||||
/* Unmap the file*/
|
||||
|
@ -850,6 +858,9 @@ VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode, WORD KeepResident)
|
|||
/* Check if this PSP is it's own parent */
|
||||
if (PspBlock->ParentPsp == Psp) goto Done;
|
||||
|
||||
/* Notify VDDs of process termination */
|
||||
VDDTerminateUserHook(Psp);
|
||||
|
||||
if (KeepResident == 0)
|
||||
{
|
||||
for (i = 0; i < PspBlock->HandleTableSize; i++)
|
||||
|
|
|
@ -497,19 +497,23 @@ EmulatorWriteIo(PFAST486_STATE State,
|
|||
|
||||
BOOL
|
||||
WINAPI
|
||||
VDDInstallIOHook(HANDLE hVdd,
|
||||
WORD cPortRange,
|
||||
PVDD_IO_PORTRANGE pPortRange,
|
||||
PVDD_IO_HANDLERS IOhandler)
|
||||
VDDInstallIOHook(IN HANDLE hVdd,
|
||||
IN WORD cPortRange,
|
||||
IN PVDD_IO_PORTRANGE pPortRange,
|
||||
IN PVDD_IO_HANDLERS IoHandlers)
|
||||
{
|
||||
WORD i;
|
||||
|
||||
/* Check validity of the VDD handle */
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE) return FALSE;
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Loop for each range of I/O ports */
|
||||
while (cPortRange--)
|
||||
{
|
||||
WORD i;
|
||||
|
||||
/* Register the range of I/O ports */
|
||||
for (i = pPortRange->First; i <= pPortRange->Last; ++i)
|
||||
{
|
||||
|
@ -544,12 +548,11 @@ VDDInstallIOHook(HANDLE hVdd,
|
|||
IoPortProc[i].IoHandlers.OutsD = NULL;
|
||||
|
||||
/* Save our handlers */
|
||||
IoPortProc[i].VddIoHandlers = *IOhandler;
|
||||
IoPortProc[i].VddIoHandlers = *IoHandlers;
|
||||
}
|
||||
|
||||
/* Go to the next range */
|
||||
++pPortRange;
|
||||
++IOhandler;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -557,18 +560,22 @@ VDDInstallIOHook(HANDLE hVdd,
|
|||
|
||||
VOID
|
||||
WINAPI
|
||||
VDDDeInstallIOHook(HANDLE hVdd,
|
||||
WORD cPortRange,
|
||||
PVDD_IO_PORTRANGE pPortRange)
|
||||
VDDDeInstallIOHook(IN HANDLE hVdd,
|
||||
IN WORD cPortRange,
|
||||
IN PVDD_IO_PORTRANGE pPortRange)
|
||||
{
|
||||
WORD i;
|
||||
|
||||
/* Check validity of the VDD handle */
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE) return;
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Loop for each range of I/O ports */
|
||||
while (cPortRange--)
|
||||
{
|
||||
WORD i;
|
||||
|
||||
/* Unregister the range of I/O ports */
|
||||
for (i = pPortRange->First; i <= pPortRange->Last; ++i)
|
||||
{
|
||||
|
|
|
@ -388,7 +388,12 @@ VDDInstallMemoryHook(IN HANDLE hVdd,
|
|||
PLIST_ENTRY Pointer;
|
||||
|
||||
/* Check validity of the VDD handle */
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE) return FALSE;
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dwCount == 0) return FALSE;
|
||||
|
||||
/* Make sure none of these pages are already allocated */
|
||||
|
@ -407,7 +412,11 @@ VDDInstallMemoryHook(IN HANDLE hVdd,
|
|||
{
|
||||
/* Create and initialize a new hook entry... */
|
||||
Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook));
|
||||
if (Hook == NULL) return FALSE;
|
||||
if (Hook == NULL)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Hook->hVdd = hVdd;
|
||||
Hook->Count = 0;
|
||||
|
@ -456,6 +465,13 @@ VDDDeInstallMemoryHook(IN HANDLE hVdd,
|
|||
PVOID Address = (PVOID)REAL_TO_PHYS(FirstPage * PAGE_SIZE);
|
||||
SIZE_T Size = (LastPage - FirstPage + 1) * PAGE_SIZE;
|
||||
|
||||
/* Check validity of the VDD handle */
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dwCount == 0) return FALSE;
|
||||
|
||||
/* Commit the pages */
|
||||
|
@ -504,6 +520,13 @@ VDDAllocMem(IN HANDLE hVdd,
|
|||
ULONG LastPage = ((ULONG_PTR)PHYS_TO_REAL(Address) + Size - 1) >> 12;
|
||||
SIZE_T RealSize = (LastPage - FirstPage + 1) * PAGE_SIZE;
|
||||
|
||||
/* Check validity of the VDD handle */
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Size == 0) return FALSE;
|
||||
|
||||
/* Fixup the address */
|
||||
|
@ -545,6 +568,13 @@ VDDFreeMem(IN HANDLE hVdd,
|
|||
ULONG LastPage = ((ULONG_PTR)PHYS_TO_REAL(Address) + Size - 1) >> 12;
|
||||
SIZE_T RealSize = (LastPage - FirstPage + 1) * PAGE_SIZE;
|
||||
|
||||
/* Check validity of the VDD handle */
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Size == 0) return FALSE;
|
||||
|
||||
/* Fixup the address */
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#include <winuser.h>
|
||||
#include <subsys/win/vdm.h>
|
||||
|
||||
// Do not include stuff that is only defined
|
||||
// for backwards compatibility in nt_vdd.h
|
||||
#define NO_NTVDD_COMPAT
|
||||
#include <vddsvc.h>
|
||||
|
||||
DWORD WINAPI SetLastConsoleEventActive(VOID);
|
||||
|
@ -50,7 +53,7 @@ DWORD WINAPI SetLastConsoleEventActive(VOID);
|
|||
/*
|
||||
* Activate this line for Win2k compliancy
|
||||
*/
|
||||
// #define WIN2K_COMPLIANT
|
||||
#define WIN2K_COMPLIANT
|
||||
|
||||
/*
|
||||
* Activate this line if you want advanced hardcoded debug facilities
|
||||
|
|
|
@ -233,3 +233,6 @@
|
|||
@ stdcall VDDSimulate16()
|
||||
@ stdcall host_simulate() VDDSimulate16
|
||||
@ stdcall VDDTerminateVDM()
|
||||
|
||||
@ stdcall VDDInstallUserHook(long ptr ptr ptr ptr)
|
||||
@ stdcall VDDDeInstallUserHook(long)
|
||||
|
|
|
@ -25,6 +25,20 @@ typedef struct _VDD_MODULE
|
|||
VDD_PROC DispatchRoutine;
|
||||
} VDD_MODULE, *PVDD_MODULE;
|
||||
|
||||
// WARNING: A structure with the same name exists in nt_vdd.h,
|
||||
// however it is not declared because its inclusion was prevented
|
||||
// with #define NO_NTVDD_COMPAT, see ntvdm.h
|
||||
typedef struct _VDD_USER_HANDLERS
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
|
||||
HANDLE hVdd;
|
||||
PFNVDD_UCREATE Ucr_Handler;
|
||||
PFNVDD_UTERMINATE Uterm_Handler;
|
||||
PFNVDD_UBLOCK Ublock_Handler;
|
||||
PFNVDD_URESUME Uresume_Handler;
|
||||
} VDD_USER_HANDLERS, *PVDD_USER_HANDLERS;
|
||||
|
||||
/* PRIVATE VARIABLES **********************************************************/
|
||||
|
||||
// TODO: Maybe use a linked list.
|
||||
|
@ -37,6 +51,8 @@ static VDD_MODULE VDDList[MAX_VDD_MODULES] = {{NULL}};
|
|||
#define HANDLE_TO_ENTRY(Handle) ((Handle) - 1)
|
||||
#define IS_VALID_HANDLE(Handle) ((Handle) > 0 && (Handle) <= MAX_VDD_MODULES)
|
||||
|
||||
static LIST_ENTRY VddUserHooksList = {&VddUserHooksList, &VddUserHooksList};
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static USHORT GetNextFreeVDDEntry(VOID)
|
||||
|
@ -144,7 +160,7 @@ static VOID WINAPI ThirdPartyVDDBop(LPWORD Stack)
|
|||
goto Quit;
|
||||
}
|
||||
|
||||
/* If we arrived there, that means everything is OK */
|
||||
/* If we reached this point, that means everything is OK */
|
||||
|
||||
/* Register the VDD DLL */
|
||||
VDDList[Entry].hDll = hDll;
|
||||
|
@ -347,6 +363,145 @@ Quit:
|
|||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
/*
|
||||
* NOTE: This function can be called multiple times by the same VDD, if
|
||||
* it wants to install different hooks for a same action. The most recent
|
||||
* registered hooks are called first.
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
VDDInstallUserHook(IN HANDLE hVdd,
|
||||
IN PFNVDD_UCREATE Ucr_Handler,
|
||||
IN PFNVDD_UTERMINATE Uterm_Handler,
|
||||
IN PFNVDD_UBLOCK Ublock_Handler,
|
||||
IN PFNVDD_URESUME Uresume_Handler)
|
||||
{
|
||||
PVDD_USER_HANDLERS UserHook;
|
||||
|
||||
/* Check validity of the VDD handle */
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// NOTE: If we want that a VDD can install hooks only once, it's here
|
||||
// that we need to check whether a hook entry is already registered.
|
||||
|
||||
/* Create and initialize a new hook entry... */
|
||||
UserHook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*UserHook));
|
||||
if (UserHook == NULL)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UserHook->hVdd = hVdd;
|
||||
UserHook->Ucr_Handler = Ucr_Handler;
|
||||
UserHook->Uterm_Handler = Uterm_Handler;
|
||||
UserHook->Ublock_Handler = Ublock_Handler;
|
||||
UserHook->Uresume_Handler = Uresume_Handler;
|
||||
|
||||
/* ... and add it at the top of the list of hooks */
|
||||
InsertHeadList(&VddUserHooksList, &UserHook->Entry);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: This function uninstalls the latest installed hooks for a given VDD.
|
||||
* It can be called multiple times by the same VDD to uninstall many hooks
|
||||
* installed by multiple invocations of VDDInstallUserHook.
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
VDDDeInstallUserHook(IN HANDLE hVdd)
|
||||
{
|
||||
PLIST_ENTRY Pointer;
|
||||
PVDD_USER_HANDLERS UserHook;
|
||||
|
||||
/* Check validity of the VDD handle */
|
||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Uninstall the latest installed hooks */
|
||||
for (Pointer = VddUserHooksList.Flink; Pointer != &VddUserHooksList; Pointer = Pointer->Flink)
|
||||
{
|
||||
UserHook = CONTAINING_RECORD(Pointer, VDD_USER_HANDLERS, Entry);
|
||||
if (UserHook->hVdd == hVdd)
|
||||
{
|
||||
RemoveEntryList(&UserHook->Entry);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, UserHook);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal functions for calling the VDD user hooks.
|
||||
* Their names come directly from the Windows 2kX DDK.
|
||||
*/
|
||||
|
||||
VOID VDDCreateUserHook(USHORT DosPDB)
|
||||
{
|
||||
PLIST_ENTRY Pointer;
|
||||
PVDD_USER_HANDLERS UserHook;
|
||||
|
||||
/* Call the hooks starting from the most recent ones */
|
||||
for (Pointer = VddUserHooksList.Flink; Pointer != &VddUserHooksList; Pointer = Pointer->Flink)
|
||||
{
|
||||
UserHook = CONTAINING_RECORD(Pointer, VDD_USER_HANDLERS, Entry);
|
||||
if (UserHook->Ucr_Handler) UserHook->Ucr_Handler(DosPDB);
|
||||
}
|
||||
}
|
||||
|
||||
VOID VDDTerminateUserHook(USHORT DosPDB)
|
||||
{
|
||||
PLIST_ENTRY Pointer;
|
||||
PVDD_USER_HANDLERS UserHook;
|
||||
|
||||
/* Call the hooks starting from the most recent ones */
|
||||
for (Pointer = VddUserHooksList.Flink; Pointer != &VddUserHooksList; Pointer = Pointer->Flink)
|
||||
{
|
||||
UserHook = CONTAINING_RECORD(Pointer, VDD_USER_HANDLERS, Entry);
|
||||
if (UserHook->Uterm_Handler) UserHook->Uterm_Handler(DosPDB);
|
||||
}
|
||||
}
|
||||
|
||||
VOID VDDBlockUserHook(VOID)
|
||||
{
|
||||
PLIST_ENTRY Pointer;
|
||||
PVDD_USER_HANDLERS UserHook;
|
||||
|
||||
/* Call the hooks starting from the most recent ones */
|
||||
for (Pointer = VddUserHooksList.Flink; Pointer != &VddUserHooksList; Pointer = Pointer->Flink)
|
||||
{
|
||||
UserHook = CONTAINING_RECORD(Pointer, VDD_USER_HANDLERS, Entry);
|
||||
if (UserHook->Ublock_Handler) UserHook->Ublock_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
VOID VDDResumeUserHook(VOID)
|
||||
{
|
||||
PLIST_ENTRY Pointer;
|
||||
PVDD_USER_HANDLERS UserHook;
|
||||
|
||||
/* Call the hooks starting from the most recent ones */
|
||||
for (Pointer = VddUserHooksList.Flink; Pointer != &VddUserHooksList; Pointer = Pointer->Flink)
|
||||
{
|
||||
UserHook = CONTAINING_RECORD(Pointer, VDD_USER_HANDLERS, Entry);
|
||||
if (UserHook->Uresume_Handler) UserHook->Uresume_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID VDDSupInitialize(VOID)
|
||||
{
|
||||
/* Register the 3rd-party VDD BOP Handler */
|
||||
|
|
|
@ -11,6 +11,11 @@
|
|||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID VDDCreateUserHook(USHORT DosPDB);
|
||||
VOID VDDTerminateUserHook(USHORT DosPDB);
|
||||
VOID VDDBlockUserHook(VOID);
|
||||
VOID VDDResumeUserHook(VOID);
|
||||
|
||||
VOID VDDSupInitialize(VOID);
|
||||
|
||||
#endif // _VDDSUP_H_
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
/* DEBUGGING HELPERS **********************************************************/
|
||||
|
||||
// Enable this define to use DPRINT1 instead of MessageBox
|
||||
// #define DBG_SILENT
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
#ifdef DBG_SILENT
|
||||
|
||||
#define VDD_DBG(...) \
|
||||
|
@ -81,8 +82,14 @@
|
|||
#define VDD_DBG VddDbgMsg
|
||||
#endif
|
||||
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
HANDLE hVdd = NULL;
|
||||
|
||||
|
||||
/* VDD I/O PORTS TESTING ******************************************************/
|
||||
|
||||
/*
|
||||
* Port hooks (serial ports) -- Each port range is for testing different port handlers.
|
||||
*/
|
||||
|
@ -96,26 +103,6 @@ VDD_IO_PORTRANGE PortDefs[NUM_PORTS] =
|
|||
{0x2E8, 0x2EF}
|
||||
};
|
||||
|
||||
// PFNVDD_INB PortInB;
|
||||
// PFNVDD_INW PortInW;
|
||||
// PFNVDD_INSB PortInsB;
|
||||
// PFNVDD_INSW PortInsW;
|
||||
// PFNVDD_OUTB PortOutB;
|
||||
// PFNVDD_OUTW PortOutW;
|
||||
// PFNVDD_OUTSB PortOutsB;
|
||||
// PFNVDD_OUTSW PortOutsW;
|
||||
|
||||
// VDD_IO_HANDLERS PortHandlers[NUM_PORTS] =
|
||||
// {
|
||||
// {PortInB, NULL , NULL , NULL , PortOutB, NULL , NULL , NULL },
|
||||
// {PortInB, PortInW, NULL , NULL , PortOutB, PortOutW, NULL , NULL },
|
||||
// {PortInB, NULL , PortInsB, NULL , PortOutB, NULL , PortOutsB, NULL },
|
||||
// {PortInB, NULL , NULL , PortInsW, PortOutB, NULL , NULL , PortOutsW},
|
||||
// };
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
PortInB(IN USHORT Port,
|
||||
|
@ -151,8 +138,6 @@ PortOutW(IN USHORT Port,
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
PortInsB(IN USHORT Port,
|
||||
|
@ -192,7 +177,6 @@ PortOutsW(IN USHORT Port,
|
|||
}
|
||||
|
||||
|
||||
|
||||
VDD_IO_HANDLERS PortHandlers[NUM_PORTS] =
|
||||
{
|
||||
{PortInB, NULL , NULL , NULL , PortOutB, NULL , NULL , NULL },
|
||||
|
@ -201,8 +185,11 @@ VDD_IO_HANDLERS PortHandlers[NUM_PORTS] =
|
|||
{PortInB, NULL , NULL , PortInsW, PortOutB, NULL , NULL , PortOutsW},
|
||||
};
|
||||
|
||||
|
||||
/* VDD MEMORY HOOKS TESTING ***************************************************/
|
||||
|
||||
/*
|
||||
* Memory hooking. Everything should be page-rounded.
|
||||
* Everything should be page-rounded.
|
||||
*/
|
||||
|
||||
#ifndef PAGE_SIZE
|
||||
|
@ -300,60 +287,66 @@ FindHookableMemory(IN USHORT StartSegment,
|
|||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
RegisterVDD(BOOLEAN Register)
|
||||
/* VDD USER HOOKS TESTING *****************************************************/
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
Create1Handler(USHORT DosPDB)
|
||||
{
|
||||
BOOLEAN Success = FALSE;
|
||||
|
||||
if (Register)
|
||||
{
|
||||
/* Hook some IO ports */
|
||||
VDD_DBG("VDDInstallIOHook");
|
||||
Success = VDDInstallIOHook(hVdd, NUM_PORTS, PortDefs, PortHandlers);
|
||||
if (!Success)
|
||||
{
|
||||
VDD_DBG("Unable to hook IO ports, terminate...");
|
||||
VDDTerminateVDM();
|
||||
}
|
||||
|
||||
/* Add a memory handler */
|
||||
VDD_DBG("FindHookableMemory");
|
||||
HookedAddress = FindHookableMemory(MEM_SEG_START, 0x0000,
|
||||
&HookedSegment, &HookedOffset);
|
||||
if (HookedAddress == NULL)
|
||||
{
|
||||
VDD_DBG("Unable to install memory handler, terminate...");
|
||||
VDDTerminateVDM();
|
||||
}
|
||||
VDD_DBG("Initialization finished!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Success = VDDFreeMem(hVdd, HookedAddress, MEM_SIZE);
|
||||
if (!Success) VDD_DBG("Unable to free memory");
|
||||
|
||||
/* Uninstall the memory handler */
|
||||
VDD_DBG("VDDDeInstallMemoryHook");
|
||||
Success = VDDDeInstallMemoryHook(hVdd, HookedAddress, MEM_SIZE);
|
||||
if (!Success) VDD_DBG("Memory handler uninstall failed");
|
||||
|
||||
VDD_DBG("VdmUnmapFlat");
|
||||
Success = VdmUnmapFlat(HookedSegment, HookedOffset, HookedAddress, getMODE());
|
||||
// FreeVDMPointer(GetVDMAddress(HookedSegment, HookedOffset), MEM_SIZE, HookedAddress, (getMSW() & MSW_PE));
|
||||
if (!Success) VDD_DBG("VdmUnmapFlat failed!");
|
||||
|
||||
/* Deregister the hooked IO ports */
|
||||
VDD_DBG("VDDDeInstallIOHook");
|
||||
VDDDeInstallIOHook(hVdd, NUM_PORTS, PortDefs);
|
||||
|
||||
VDD_DBG("Cleanup finished!");
|
||||
Success = TRUE;
|
||||
}
|
||||
|
||||
return Success;
|
||||
VDD_DBG("Create1Handler(0x%04x)", DosPDB);
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
VOID
|
||||
WINAPI
|
||||
Create2Handler(USHORT DosPDB)
|
||||
{
|
||||
VDD_DBG("Create2Handler(0x%04x)", DosPDB);
|
||||
}
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
Terminate1Handler(USHORT DosPDB)
|
||||
{
|
||||
VDD_DBG("Terminate1Handler(0x%04x)", DosPDB);
|
||||
}
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
Terminate2Handler(USHORT DosPDB)
|
||||
{
|
||||
VDD_DBG("Terminate2Handler(0x%04x)", DosPDB);
|
||||
}
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
Block1Handler(VOID)
|
||||
{
|
||||
VDD_DBG("Block1Handler");
|
||||
}
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
Block2Handler(VOID)
|
||||
{
|
||||
VDD_DBG("Block2Handler");
|
||||
}
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
Resume1Handler(VOID)
|
||||
{
|
||||
VDD_DBG("Resume1Handler");
|
||||
}
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
Resume2Handler(VOID)
|
||||
{
|
||||
VDD_DBG("Resume2Handler");
|
||||
}
|
||||
|
||||
|
||||
/* VDD INITIALIZATION AND REGISTRATION ****************************************/
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
|
@ -385,7 +378,99 @@ TestVDDDispatch(VOID)
|
|||
setCF(0);
|
||||
}
|
||||
|
||||
/* ENTRY-POINT ****************************************************************/
|
||||
BOOLEAN
|
||||
RegisterVDD(BOOLEAN Register)
|
||||
{
|
||||
BOOLEAN Success = FALSE;
|
||||
|
||||
if (Register)
|
||||
{
|
||||
/* Hook some IO ports */
|
||||
VDD_DBG("VDDInstallIOHook");
|
||||
Success = VDDInstallIOHook(hVdd, NUM_PORTS, PortDefs, PortHandlers);
|
||||
if (!Success)
|
||||
{
|
||||
VDD_DBG("Unable to hook IO ports, terminate...");
|
||||
VDDTerminateVDM();
|
||||
}
|
||||
|
||||
/* Add a memory handler */
|
||||
VDD_DBG("FindHookableMemory");
|
||||
HookedAddress = FindHookableMemory(MEM_SEG_START, 0x0000,
|
||||
&HookedSegment, &HookedOffset);
|
||||
if (HookedAddress == NULL)
|
||||
{
|
||||
VDD_DBG("Unable to install memory handler, terminate...");
|
||||
VDDTerminateVDM();
|
||||
}
|
||||
|
||||
/* Add some user hooks -- Test order of initialization and calling */
|
||||
VDD_DBG("VDDInstallUserHook (1)");
|
||||
Success = VDDInstallUserHook(hVdd,
|
||||
Create1Handler,
|
||||
Terminate1Handler,
|
||||
Block1Handler,
|
||||
Resume1Handler);
|
||||
if (!Success)
|
||||
{
|
||||
VDD_DBG("Unable to install user hooks (1)...");
|
||||
}
|
||||
|
||||
VDD_DBG("VDDInstallUserHook (2)");
|
||||
Success = VDDInstallUserHook(hVdd,
|
||||
Create2Handler,
|
||||
Terminate2Handler,
|
||||
Block2Handler,
|
||||
Resume2Handler);
|
||||
if (!Success)
|
||||
{
|
||||
VDD_DBG("Unable to install user hooks (2)...");
|
||||
}
|
||||
|
||||
/* We have finished! */
|
||||
VDD_DBG("Initialization finished!");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove the user hooks */
|
||||
VDD_DBG("VDDDeInstallUserHook (1)");
|
||||
Success = VDDDeInstallUserHook(hVdd);
|
||||
if (!Success) VDD_DBG("Unable to uninstall user hooks (1)");
|
||||
|
||||
// TODO: See which hooks are still existing there...
|
||||
|
||||
VDD_DBG("VDDDeInstallUserHook (2)");
|
||||
Success = VDDDeInstallUserHook(hVdd);
|
||||
if (!Success) VDD_DBG("Unable to uninstall user hooks (2)");
|
||||
|
||||
VDD_DBG("VDDDeInstallUserHook (3)");
|
||||
Success = VDDDeInstallUserHook(hVdd);
|
||||
if (!Success) VDD_DBG("EXPECTED ERROR: Unable to uninstall user hooks (3)");
|
||||
else VDD_DBG("UNEXPECTED ERROR: Uninstalling user hooks (3) succeeded?!");
|
||||
|
||||
/* Uninstall the memory handler */
|
||||
Success = VDDFreeMem(hVdd, HookedAddress, MEM_SIZE);
|
||||
if (!Success) VDD_DBG("Unable to free memory");
|
||||
|
||||
VDD_DBG("VDDDeInstallMemoryHook");
|
||||
Success = VDDDeInstallMemoryHook(hVdd, HookedAddress, MEM_SIZE);
|
||||
if (!Success) VDD_DBG("Memory handler uninstall failed");
|
||||
|
||||
VDD_DBG("VdmUnmapFlat");
|
||||
Success = VdmUnmapFlat(HookedSegment, HookedOffset, HookedAddress, getMODE());
|
||||
// FreeVDMPointer(GetVDMAddress(HookedSegment, HookedOffset), MEM_SIZE, HookedAddress, (getMSW() & MSW_PE));
|
||||
if (!Success) VDD_DBG("VdmUnmapFlat failed!");
|
||||
|
||||
/* Deregister the hooked IO ports */
|
||||
VDD_DBG("VDDDeInstallIOHook");
|
||||
VDDDeInstallIOHook(hVdd, NUM_PORTS, PortDefs);
|
||||
|
||||
VDD_DBG("Cleanup finished!");
|
||||
Success = TRUE;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
BOOL
|
||||
WINAPI // VDDInitialize
|
||||
|
|
Loading…
Reference in a new issue