Author: hbelusca Date: Fri Mar 20 00:14:11 2015 New Revision: 66828
URL: http://svn.reactos.org/svn/reactos?rev=66828&view=rev Log: [MVDM]: Add a testbench VDD. Tested by hyoenmadan on NT4 MIPS NTVDM and by myself on 2k3 NTVDM.
Added: trunk/reactos/subsystems/mvdm/samples/ (with props) trunk/reactos/subsystems/mvdm/samples/CMakeLists.txt (with props) trunk/reactos/subsystems/mvdm/samples/testvdd/ (with props) trunk/reactos/subsystems/mvdm/samples/testvdd/CMakeLists.txt (with props) trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.c (with props) trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.rc (with props) trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.spec (with props) Modified: trunk/reactos/subsystems/mvdm/CMakeLists.txt trunk/reactos/subsystems/mvdm/README.txt
Modified: trunk/reactos/subsystems/mvdm/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/CMakeLists.... ============================================================================== --- trunk/reactos/subsystems/mvdm/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/CMakeLists.txt [iso-8859-1] Fri Mar 20 00:14:11 2015 @@ -2,5 +2,6 @@ add_subdirectory(config) #add_subdirectory(dos) add_subdirectory(ntvdm) +add_subdirectory(samples) add_subdirectory(vdmdbg) #add_subdirectory(wow16)
Modified: trunk/reactos/subsystems/mvdm/README.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/README.txt?... ============================================================================== --- trunk/reactos/subsystems/mvdm/README.txt [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/README.txt [iso-8859-1] Fri Mar 20 00:14:11 2015 @@ -4,5 +4,6 @@ - config : Miscellaneous configuration files. - dos : All 16-bit DOS files (kernel, drivers, apps...) are placed here. - ntvdm : NT Virtual DOS Machine. +- samples: Sample programs for NTVDM. - vdmdbg : Virtual DOS Machine debug helper DLL (from Wine). - wow16 : All Win16 thunk files are placed here.
Propchange: trunk/reactos/subsystems/mvdm/samples/ ------------------------------------------------------------------------------ --- bugtraq:logregex (added) +++ bugtraq:logregex Fri Mar 20 00:14:11 2015 @@ -0,0 +1 @@ +((CORE|ROSTESTS|ROSAPPS)-\d+)(,? ?((CORE|ROSTESTS|ROSAPPS)-\d+))*(,? ?(and |or )?((CORE|ROSTESTS|ROSAPPS)-\d+))?
Propchange: trunk/reactos/subsystems/mvdm/samples/ ------------------------------------------------------------------------------ bugtraq:message = See issue %BUGID% for more details.
Propchange: trunk/reactos/subsystems/mvdm/samples/ ------------------------------------------------------------------------------ bugtraq:url = https://jira.reactos.org/browse/%BUGID%
Propchange: trunk/reactos/subsystems/mvdm/samples/ ------------------------------------------------------------------------------ tsvn:logminsize = 10
Added: trunk/reactos/subsystems/mvdm/samples/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/samples/CMa... ============================================================================== --- trunk/reactos/subsystems/mvdm/samples/CMakeLists.txt (added) +++ trunk/reactos/subsystems/mvdm/samples/CMakeLists.txt [iso-8859-1] Fri Mar 20 00:14:11 2015 @@ -0,0 +1,2 @@ + +add_subdirectory(testvdd)
Propchange: trunk/reactos/subsystems/mvdm/samples/CMakeLists.txt ------------------------------------------------------------------------------ svn:eol-style = native
Propchange: trunk/reactos/subsystems/mvdm/samples/testvdd/ ------------------------------------------------------------------------------ --- bugtraq:logregex (added) +++ bugtraq:logregex Fri Mar 20 00:14:11 2015 @@ -0,0 +1 @@ +((CORE|ROSTESTS|ROSAPPS)-\d+)(,? ?((CORE|ROSTESTS|ROSAPPS)-\d+))*(,? ?(and |or )?((CORE|ROSTESTS|ROSAPPS)-\d+))?
Propchange: trunk/reactos/subsystems/mvdm/samples/testvdd/ ------------------------------------------------------------------------------ bugtraq:message = See issue %BUGID% for more details.
Propchange: trunk/reactos/subsystems/mvdm/samples/testvdd/ ------------------------------------------------------------------------------ bugtraq:url = https://jira.reactos.org/browse/%BUGID%
Propchange: trunk/reactos/subsystems/mvdm/samples/testvdd/ ------------------------------------------------------------------------------ tsvn:logminsize = 10
Added: trunk/reactos/subsystems/mvdm/samples/testvdd/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/samples/tes... ============================================================================== --- trunk/reactos/subsystems/mvdm/samples/testvdd/CMakeLists.txt (added) +++ trunk/reactos/subsystems/mvdm/samples/testvdd/CMakeLists.txt [iso-8859-1] Fri Mar 20 00:14:11 2015 @@ -0,0 +1,16 @@ + +spec2def(testvdd.dll testvdd.spec) + +list(APPEND SOURCE + testvdd.c + testvdd.rc + ${CMAKE_CURRENT_BINARY_DIR}/testvdd.def) + +add_library(testvdd SHARED ${SOURCE}) +#set_module_type(testvdd win32dll UNICODE ENTRYPOINT VDDInitialize) +set_module_type(testvdd win32dll UNICODE) + +target_link_libraries(testvdd ${PSEH_LIB}) + +add_importlibs(testvdd ntvdm user32 msvcrt kernel32 ntdll) +#add_cd_file(TARGET testvdd DESTINATION reactos/system32 FOR all)
Propchange: trunk/reactos/subsystems/mvdm/samples/testvdd/CMakeLists.txt ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/samples/tes... ============================================================================== --- trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.c (added) +++ trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.c [iso-8859-1] Fri Mar 20 00:14:11 2015 @@ -0,0 +1,436 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Virtual DOS Machine + * FILE: samples/testvdd/testvdd.c + * PURPOSE: Testing VDD for NTVDM + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include <stdio.h> + +#include <windows.h> +#include <vddsvc.h> + +#define NDEBUG +#include <debug.h> + +// Enable this define to use DPRINT1 instead of MessageBox +// #define DBG_SILENT + +/* GLOBALS ********************************************************************/ + +#ifdef DBG_SILENT + + #define VDD_DBG(...) \ + do { \ + DPRINT1(__VA_ARGS__); \ + DbgPrint("\n"); \ + } while(0) + +#else + + static VOID + VddDbgMsg(LPCSTR Format, ...) + { + #ifndef WIN2K_COMPLIANT + CHAR StaticBuffer[256]; + LPSTR Buffer = StaticBuffer; // Use the static buffer by default. + #else + CHAR Buffer[2048]; // Large enough. If not, increase it by hand. + #endif + size_t MsgLen; + va_list Parameters; + + va_start(Parameters, Format); + + #ifndef WIN2K_COMPLIANT + /* + * Retrieve the message length and if it is too long, allocate + * an auxiliary buffer; otherwise use the static buffer. + */ + MsgLen = _vscprintf(Format, Parameters) + 1; // NULL-terminated + if (MsgLen > ARRAYSIZE(StaticBuffer)) + { + Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MsgLen * sizeof(WCHAR)); + if (Buffer == NULL) + { + /* Allocation failed, use the static buffer and display a suitable error message */ + Buffer = StaticBuffer; + Format = "DisplayMessage()\nOriginal message is too long and allocating an auxiliary buffer failed."; + MsgLen = strlen(Format); + } + } + #else + MsgLen = ARRAYSIZE(Buffer); + #endif + + /* Display the message */ + _vsnprintf(Buffer, MsgLen, Format, Parameters); + MessageBoxA(NULL, Buffer, "Test VDD", MB_OK); + + #ifndef WIN2K_COMPLIANT + /* Free the buffer if needed */ + if (Buffer != StaticBuffer) HeapFree(GetProcessHeap(), 0, Buffer); + #endif + + va_end(Parameters); + } + + #define VDD_DBG VddDbgMsg +#endif + +HANDLE hVdd = NULL; + +/* + * Port hooks (serial ports) -- Each port range is for testing different port handlers. + */ +#define NUM_PORTS 4 + +VDD_IO_PORTRANGE PortDefs[NUM_PORTS] = +{ + {0x3F8, 0x3FF}, + {0x2F8, 0x2FF}, + {0x3E8, 0x3EF}, + {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, + OUT PUCHAR Data) +{ + *Data = 0; + VDD_DBG("0x%08x (BYTE 0x%02x) <-- Port 0x%04x", Data, *Data, Port); +} + +VOID +WINAPI +PortOutB(IN USHORT Port, + IN UCHAR Data) +{ + VDD_DBG("(BYTE 0x%02x) --> Port 0x%04x", Data, Port); +} + +VOID +WINAPI +PortInW(IN USHORT Port, + OUT PUSHORT Data) +{ + *Data = 0; + VDD_DBG("0x%08x (WORD 0x%04x) <-- Port 0x%04x", Data, *Data, Port); +} + +VOID +WINAPI +PortOutW(IN USHORT Port, + IN USHORT Data) +{ + VDD_DBG("(WORD 0x%04x) --> Port 0x%04x", Data, Port); +} + + + + +VOID +WINAPI +PortInsB(IN USHORT Port, + OUT PUCHAR Data, + IN USHORT Count) +{ + VDD_DBG("0x%08x (BYTESTR[%u]) <-- Port 0x%04x", Data, Count, Port); + while (Count--) *Data++ = 0; +} + +VOID +WINAPI +PortOutsB(IN USHORT Port, + IN PUCHAR Data, + IN USHORT Count) +{ + VDD_DBG("0x%08x (BYTESTR[%u]) --> Port 0x%04x", Data, Count, Port); +} + +VOID +WINAPI +PortInsW(IN USHORT Port, + OUT PUSHORT Data, + IN USHORT Count) +{ + VDD_DBG("0x%08x (WORDSTR[%u]) <-- Port 0x%04x", Data, Count, Port); + while (Count--) *Data++ = 0; +} + +VOID +WINAPI +PortOutsW(IN USHORT Port, + IN PUSHORT Data, + IN USHORT Count) +{ + VDD_DBG("0x%08x (WORDSTR[%u]) --> Port 0x%04x", Data, Count, Port); +} + + + +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}, +}; + +/* + * Memory hooking. Everything should be page-rounded. + */ + +#ifndef PAGE_SIZE +#define PAGE_SIZE 0x1000 +#endif + +#ifndef PAGE_ROUND_DOWN +#define PAGE_ROUND_DOWN(x) \ + ( ((ULONG_PTR)(x)) & (~(PAGE_SIZE-1)) ) +#endif + +#ifndef PAGE_ROUND_UP +#define PAGE_ROUND_UP(x) \ + ( (((ULONG_PTR)(x)) + PAGE_SIZE-1) & (~(PAGE_SIZE-1)) ) +#endif + +#define MEM_SEG_START 0x0000 +#define MEM_SIZE PAGE_SIZE + +USHORT HookedSegment = 0x0000; +ULONG HookedOffset = 0x0000; +PVOID HookedAddress = NULL; + +VOID +WINAPI +MemoryHandler(IN PVOID FaultAddress, + IN ULONG RWMode) +{ + BOOLEAN Success = FALSE; + + VDD_DBG("MemoryHandler(0x%08x, %s)", FaultAddress, (RWMode == 1) ? "Write" : "Read"); + // VDDTerminateVDM(); + + Success = VDDAllocMem(hVdd, HookedAddress, MEM_SIZE); + if (!Success) VDD_DBG("Unable to allocate memory"); +} + +PVOID +FindHookableMemory(IN USHORT StartSegment, + IN ULONG StartOffset, + OUT PUSHORT HookedSegment, + OUT PULONG HookedOffset) +{ + BOOLEAN Success; + PVOID PhysMemStart = NULL; + USHORT Segment = StartSegment; + ULONG Offset = PAGE_ROUND_DOWN(StartOffset); + + *HookedSegment = 0x0000; + *HookedOffset = 0x0000; + + while (Segment <= 0xF000) + { + // PhysMemStart = GetVDMPointer(GetVDMAddress(Segment, Offset), MEM_SIZE, (getMSW() & MSW_PE)); + PhysMemStart = VdmMapFlat(Segment, Offset, getMODE()); + + /* Try to hook this memory area... */ + Success = VDDInstallMemoryHook(hVdd, PhysMemStart, MEM_SIZE, MemoryHandler); + if (!Success) + { + /* ... it didn't work. Free PhysMemStart, increase segment/offset and try again. */ + DPRINT1("%04lX:%08lX hooking failed, continue...\n", Segment, Offset); + + VdmUnmapFlat(Segment, Offset, PhysMemStart, getMODE()); + // FreeVDMPointer(GetVDMAddress(Segment, Offset), MEM_SIZE, PhysMemStart, (getMSW() & MSW_PE)); + PhysMemStart = NULL; + + Offset += MEM_SIZE; + if (Offset + MEM_SIZE > 0xFFFF) + { + Segment += 0x1000; + Offset = 0x0000; + } + } + else + { + /* ... it worked. We'll free PhysMemStart later on. */ + DPRINT1("%04lX:%08lX hooking succeeded!\n", Segment, Offset); + break; + } + } + + if (PhysMemStart) + { + VDD_DBG("We hooked at %04lX:%08lX (0x%p)", Segment, Offset, PhysMemStart); + *HookedSegment = Segment; + *HookedOffset = Offset; + } + else + { + VDD_DBG("Hooking attempt failed!"); + } + + return PhysMemStart; +} + + +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(); + } + 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; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +VOID +WINAPI +TestVDDRegister(VOID) +{ + VDD_DBG("TestVDDRegister"); + + /* Clear the Carry Flag: success */ + setCF(0); +} + +VOID +WINAPI +TestVDDUnRegister(VOID) +{ + VDD_DBG("TestVDDUnRegister"); + + /* Clear the Carry Flag: success */ + setCF(0); +} + +VOID +WINAPI +TestVDDDispatch(VOID) +{ + VDD_DBG("TestVDDDispatch"); + + /* Clear the Carry Flag: success */ + setCF(0); +} + +/* ENTRY-POINT ****************************************************************/ + +BOOL +WINAPI // VDDInitialize +DllMain(IN HINSTANCE hInstanceDll, + IN DWORD dwReason, + IN LPVOID lpReserved) +{ + BOOLEAN Success; + + UNREFERENCED_PARAMETER(lpReserved); + + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + { + VDD_DBG("DLL_PROCESS_ATTACH"); + + /* Save our global VDD handle */ + hVdd = hInstanceDll; + + /* Register VDD */ + Success = RegisterVDD(TRUE); + if (!Success) VDD_DBG("Failed to register the VDD..."); + + break; + } + + case DLL_PROCESS_DETACH: + { + VDD_DBG("DLL_PROCESS_DETACH"); + + /* Unregister VDD */ + Success = RegisterVDD(FALSE); + if (!Success) VDD_DBG("Failed to unregister the VDD..."); + + break; + } + + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + default: + break; + } + + return TRUE; +} + +/* EOF */
Propchange: trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/samples/tes... ============================================================================== --- trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.rc (added) +++ trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.rc [iso-8859-1] Fri Mar 20 00:14:11 2015 @@ -0,0 +1,6 @@ + +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "NTVDM Testing VDD" +#define REACTOS_STR_INTERNAL_NAME "testvdd" +#define REACTOS_STR_ORIGINAL_FILENAME "testvdd.dll" +#include <reactos/version.rc>
Propchange: trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.rc ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/samples/tes... ============================================================================== --- trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.spec (added) +++ trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.spec [iso-8859-1] Fri Mar 20 00:14:11 2015 @@ -0,0 +1,5 @@ +; @ stdcall DllMain(ptr long ptr) + +@ stdcall TestVDDRegister() +@ stdcall TestVDDUnRegister() +@ stdcall TestVDDDispatch()
Propchange: trunk/reactos/subsystems/mvdm/samples/testvdd/testvdd.spec ------------------------------------------------------------------------------ svn:eol-style = native