From db20f3f1bb8595633a7e16c8900fd401a453a6b5 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Tue, 27 Dec 2016 16:46:08 +0900 Subject: Imported Upstream version 1.0.0.9127 --- .../WriteProcessMemory/test1/CMakeLists.txt | 4 +- .../debug_api/WriteProcessMemory/test1/helper.c | 243 --------------------- .../debug_api/WriteProcessMemory/test1/helper.cpp | 243 +++++++++++++++++++++ .../debug_api/WriteProcessMemory/test1/test1.c | 189 ---------------- .../debug_api/WriteProcessMemory/test1/test1.cpp | 189 ++++++++++++++++ 5 files changed, 434 insertions(+), 434 deletions(-) delete mode 100644 src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.c create mode 100644 src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.cpp delete mode 100644 src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.c create mode 100644 src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.cpp (limited to 'src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1') diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/CMakeLists.txt b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/CMakeLists.txt index 39130aac1c..afd581fb92 100644 --- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/CMakeLists.txt +++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(TESTSOURCES - test1.c + test1.cpp ) add_executable(paltest_writeprocessmemory_test1 @@ -20,7 +20,7 @@ target_link_libraries(paltest_writeprocessmemory_test1 set(HELPERSOURCES - helper.c + helper.cpp ) add_executable(paltest_writeprocessmemory_test1_helper diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.c b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.c deleted file mode 100644 index 1a7318969c..0000000000 --- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.c +++ /dev/null @@ -1,243 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================= -** -** Source: helper.c -** -** Purpose: This helper process sets up a several blocks of memory, -** then uses a file to tell its parent process where that memory is -** So it can do a WriteProcessMemory on it. When the parent process is done -** we check here that it was written properly. -** -** -**============================================================*/ - -#include "commonconsts.h" - -#include - -struct allhandles_t -{ - HANDLE hEvToHelper; - HANDLE hEvFromHelper; - char *valuesFileName; -}; - - -/* function: wpmDoIt - * - * This is a general WriteProcessMemory testing function that sets up - * the RAM pointed to and tells the companion process on the other end - * of the handles in 'Comms' to attempt to alter 'lenDest' bytes at - * '*pDest'. - * - * '*pBuffer'[0..'lenBuffer'] is expected to be a guard region - * surrounding the '*pDest'[0..'lenDest'] region so that this function - * can verify that only the proper bytes were altered. - */ - -int wpmDoIt(struct allhandles_t Comms, - char * pBuffer, unsigned int lenBuffer, - char * pDest, unsigned int lenDest, - const char* storageDescription) -{ - char *pCurr; - FILE *commsFile; - DWORD dwRet; - - if (pBuffer > pDest || lenDest > lenBuffer) - { - Trace("WriteProcessMemory::DoIt() test implementation: " - "(pBuffer > pDest || lenDest > lenBuffer)\n"); - return FALSE; - } - - /* set up the storage */ - memset(pBuffer, guardValue, lenBuffer); - memset(pDest, initialValue, lenDest); - - /* tell the parent what RAM to adjust */ - if(!(commsFile = fopen(Comms.valuesFileName, "w"))) - { - Trace("WriteProcessMemory: fopen of '%S' failed (%u). \n", - Comms.valuesFileName, GetLastError()); - return FALSE; - } - if (!fprintf(commsFile, "%u %u '%s'\n", - pDest, lenDest, storageDescription)) - { - Trace("WriteProcessMemory: fprintf to '%S' failed (%u). \n", - Comms.valuesFileName, GetLastError()); - return FALSE; - } - PEDANTIC1(fclose, (commsFile)); - - /* Tell the parent the data is ready for it to adjust */ - PEDANTIC(ResetEvent, (Comms.hEvToHelper)); - PEDANTIC(SetEvent, (Comms.hEvFromHelper)); - - dwRet = WaitForSingleObject(Comms.hEvToHelper, TIMEOUT); /* parent is done */ - if (dwRet != WAIT_OBJECT_0) - { - Trace("helper WaitForSingleObjectTest: WaitForSingleObject " - "failed (%u)\n", GetLastError()); - return FALSE; - } - - /* check the stuff that SHOULD have changed */ - for (pCurr = pDest; pCurr < (pDest + lenDest); pCurr++) - { - if ( *pCurr != nextValue) - { - Trace("When testing '%s': alteration test failed " - "at %u offset %u. Found '%c' instead of '%c'\n.", - storageDescription, pDest, pCurr - pDest, *pCurr, nextValue); - Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer); - return FALSE; - } - } - /* check the stuff that should NOT have changed */ - for (pCurr = pBuffer; pCurr < pDest; pCurr++ ) - { - if ( *pCurr != guardValue) - { - Trace("When testing '%s': leading guard zone test failed " - "at %u offset %u. Found '%c' instead of '%c'\n.", - storageDescription, pDest, pCurr - pBuffer, *pCurr, guardValue); - Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer); - return FALSE; - } - } - for (pCurr = pDest + lenDest; pCurr < (pBuffer + lenBuffer); pCurr++ ) - { - if ( *pCurr != guardValue) - { - Trace("When testing '%s': trailing guard zone test failed " - "at %u offset %u. Found '%c' instead of '%c'\n.", - storageDescription, pDest + lenDest, pCurr - pBuffer, *pCurr, guardValue); - Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer); - return FALSE; - } - } - - return TRUE; -} - -int __cdecl main(int argc, char *argv[]) -{ - - BOOL success = TRUE; /* assume success */ - struct allhandles_t Comms = {0,0,0} ; - - /* variables to track storage to alter */ - char *pTarget = NULL; - unsigned int sizeTarget; - - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - /* hook up with the events created by the parent */ - Comms.hEvToHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcToHelperEvName); - if (!Comms.hEvToHelper) - { - Fail("WriteProcessMemory: OpenEvent of '%S' failed (%u). " - "(the event should already exist!)\n", - szcToHelperEvName, GetLastError()); - } - Comms.hEvFromHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcFromHelperEvName); - if (!Comms.hEvToHelper) - { - Trace("WriteProcessMemory: OpenEvent of '%S' failed (%u). " - "(the event should already exist!)\n", - szcFromHelperEvName, GetLastError()); - success = FALSE; - goto EXIT; - } - Comms.valuesFileName = argv[1]; - - { - char autoAllocatedOnStack[51]; - - /* Get the parent process to write to the local stack */ - success &= wpmDoIt(Comms, autoAllocatedOnStack, - sizeof(autoAllocatedOnStack), - autoAllocatedOnStack + sizeof(int), - sizeof(autoAllocatedOnStack) - 2 * sizeof(int), - "const size array on stack with int sized guards"); - } - - /* Get the parent process to write to stuff on the heap */ - sizeTarget = 2 * sizeof(int) + 23 ; /* 23 is just a random prime > 16 */ - if (!(pTarget = malloc(sizeTarget))) - { - Trace("WriteProcessMemory helper: unable to allocate '%s'->%d bytes of memory" - "(%u).\n", - argv[3], sizeTarget, GetLastError()); - success = FALSE; - goto EXIT; - - } - success &= wpmDoIt(Comms, pTarget, sizeTarget, - pTarget + sizeof(int), - sizeTarget - 2 * sizeof(int), - "array on heap with int sized guards"); - - /* just to be nice try something 16 - 2 * sizeof(int) bytes long */ - { - char autoAllocatedOnStack[16]; - - /* Get the parent process to write to the local stack */ - success &= wpmDoIt(Comms, autoAllocatedOnStack, - sizeof(autoAllocatedOnStack), - autoAllocatedOnStack + sizeof(int), - sizeof(autoAllocatedOnStack) - 2 * sizeof(int), - "another 16 byte array on stack with int sized guards inside"); - } - - /* NOTE: Don't try 0 bytes long. Win32 WriteProcessMemory claims - * it writes 8 bytes in that case! */ - - /* and 1 byte long... */ - { - char autoAllocatedOnStack[1+ 2 * sizeof(int)]; - - /* Get the parent process to write to the local stack */ - success &= wpmDoIt(Comms, autoAllocatedOnStack, - sizeof(autoAllocatedOnStack), - autoAllocatedOnStack + sizeof(int), - 1, - "no bytes with int sized guards outside on stack"); - } - - -EXIT: - /* Tell the parent that we are done */ - if (!DeleteFile(Comms.valuesFileName)) - { - Trace("helper: DeleteFile failed so parent (test1) is unlikely " - "to exit cleanly\n"); - } - PEDANTIC(ResetEvent, (Comms.hEvToHelper)); - if (!SetEvent(Comms.hEvFromHelper)) - { - Trace("helper: SetEvent failed so parent (test1) is unlikely " - "to exit cleanly\n"); - } - - free(pTarget); - PEDANTIC(CloseHandle, (Comms.hEvToHelper)); - PEDANTIC(CloseHandle, (Comms.hEvFromHelper)); - - if (!success) - { - Fail(""); - } - - PAL_Terminate(); - - return success ? PASS : FAIL; -} diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.cpp b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.cpp new file mode 100644 index 0000000000..d965ca7a51 --- /dev/null +++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.cpp @@ -0,0 +1,243 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================= +** +** Source: helper.c +** +** Purpose: This helper process sets up a several blocks of memory, +** then uses a file to tell its parent process where that memory is +** So it can do a WriteProcessMemory on it. When the parent process is done +** we check here that it was written properly. +** +** +**============================================================*/ + +#include "commonconsts.h" + +#include + +struct allhandles_t +{ + HANDLE hEvToHelper; + HANDLE hEvFromHelper; + char *valuesFileName; +}; + + +/* function: wpmDoIt + * + * This is a general WriteProcessMemory testing function that sets up + * the RAM pointed to and tells the companion process on the other end + * of the handles in 'Comms' to attempt to alter 'lenDest' bytes at + * '*pDest'. + * + * '*pBuffer'[0..'lenBuffer'] is expected to be a guard region + * surrounding the '*pDest'[0..'lenDest'] region so that this function + * can verify that only the proper bytes were altered. + */ + +int wpmDoIt(struct allhandles_t Comms, + char * pBuffer, unsigned int lenBuffer, + char * pDest, unsigned int lenDest, + const char* storageDescription) +{ + char *pCurr; + FILE *commsFile; + DWORD dwRet; + + if (pBuffer > pDest || lenDest > lenBuffer) + { + Trace("WriteProcessMemory::DoIt() test implementation: " + "(pBuffer > pDest || lenDest > lenBuffer)\n"); + return FALSE; + } + + /* set up the storage */ + memset(pBuffer, guardValue, lenBuffer); + memset(pDest, initialValue, lenDest); + + /* tell the parent what RAM to adjust */ + if(!(commsFile = fopen(Comms.valuesFileName, "w"))) + { + Trace("WriteProcessMemory: fopen of '%S' failed (%u). \n", + Comms.valuesFileName, GetLastError()); + return FALSE; + } + if (!fprintf(commsFile, "%u %u '%s'\n", + pDest, lenDest, storageDescription)) + { + Trace("WriteProcessMemory: fprintf to '%S' failed (%u). \n", + Comms.valuesFileName, GetLastError()); + return FALSE; + } + PEDANTIC1(fclose, (commsFile)); + + /* Tell the parent the data is ready for it to adjust */ + PEDANTIC(ResetEvent, (Comms.hEvToHelper)); + PEDANTIC(SetEvent, (Comms.hEvFromHelper)); + + dwRet = WaitForSingleObject(Comms.hEvToHelper, TIMEOUT); /* parent is done */ + if (dwRet != WAIT_OBJECT_0) + { + Trace("helper WaitForSingleObjectTest: WaitForSingleObject " + "failed (%u)\n", GetLastError()); + return FALSE; + } + + /* check the stuff that SHOULD have changed */ + for (pCurr = pDest; pCurr < (pDest + lenDest); pCurr++) + { + if ( *pCurr != nextValue) + { + Trace("When testing '%s': alteration test failed " + "at %u offset %u. Found '%c' instead of '%c'\n.", + storageDescription, pDest, pCurr - pDest, *pCurr, nextValue); + Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer); + return FALSE; + } + } + /* check the stuff that should NOT have changed */ + for (pCurr = pBuffer; pCurr < pDest; pCurr++ ) + { + if ( *pCurr != guardValue) + { + Trace("When testing '%s': leading guard zone test failed " + "at %u offset %u. Found '%c' instead of '%c'\n.", + storageDescription, pDest, pCurr - pBuffer, *pCurr, guardValue); + Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer); + return FALSE; + } + } + for (pCurr = pDest + lenDest; pCurr < (pBuffer + lenBuffer); pCurr++ ) + { + if ( *pCurr != guardValue) + { + Trace("When testing '%s': trailing guard zone test failed " + "at %u offset %u. Found '%c' instead of '%c'\n.", + storageDescription, pDest + lenDest, pCurr - pBuffer, *pCurr, guardValue); + Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer); + return FALSE; + } + } + + return TRUE; +} + +int __cdecl main(int argc, char *argv[]) +{ + + BOOL success = TRUE; /* assume success */ + struct allhandles_t Comms = {0,0,0} ; + + /* variables to track storage to alter */ + char *pTarget = NULL; + unsigned int sizeTarget; + + if(0 != (PAL_Initialize(argc, argv))) + { + return FAIL; + } + + /* hook up with the events created by the parent */ + Comms.hEvToHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcToHelperEvName); + if (!Comms.hEvToHelper) + { + Fail("WriteProcessMemory: OpenEvent of '%S' failed (%u). " + "(the event should already exist!)\n", + szcToHelperEvName, GetLastError()); + } + Comms.hEvFromHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcFromHelperEvName); + if (!Comms.hEvToHelper) + { + Trace("WriteProcessMemory: OpenEvent of '%S' failed (%u). " + "(the event should already exist!)\n", + szcFromHelperEvName, GetLastError()); + success = FALSE; + goto EXIT; + } + Comms.valuesFileName = argv[1]; + + { + char autoAllocatedOnStack[51]; + + /* Get the parent process to write to the local stack */ + success &= wpmDoIt(Comms, autoAllocatedOnStack, + sizeof(autoAllocatedOnStack), + autoAllocatedOnStack + sizeof(int), + sizeof(autoAllocatedOnStack) - 2 * sizeof(int), + "const size array on stack with int sized guards"); + } + + /* Get the parent process to write to stuff on the heap */ + sizeTarget = 2 * sizeof(int) + 23 ; /* 23 is just a random prime > 16 */ + if (!(pTarget = (char*)malloc(sizeTarget))) + { + Trace("WriteProcessMemory helper: unable to allocate '%s'->%d bytes of memory" + "(%u).\n", + argv[3], sizeTarget, GetLastError()); + success = FALSE; + goto EXIT; + + } + success &= wpmDoIt(Comms, pTarget, sizeTarget, + pTarget + sizeof(int), + sizeTarget - 2 * sizeof(int), + "array on heap with int sized guards"); + + /* just to be nice try something 16 - 2 * sizeof(int) bytes long */ + { + char autoAllocatedOnStack[16]; + + /* Get the parent process to write to the local stack */ + success &= wpmDoIt(Comms, autoAllocatedOnStack, + sizeof(autoAllocatedOnStack), + autoAllocatedOnStack + sizeof(int), + sizeof(autoAllocatedOnStack) - 2 * sizeof(int), + "another 16 byte array on stack with int sized guards inside"); + } + + /* NOTE: Don't try 0 bytes long. Win32 WriteProcessMemory claims + * it writes 8 bytes in that case! */ + + /* and 1 byte long... */ + { + char autoAllocatedOnStack[1+ 2 * sizeof(int)]; + + /* Get the parent process to write to the local stack */ + success &= wpmDoIt(Comms, autoAllocatedOnStack, + sizeof(autoAllocatedOnStack), + autoAllocatedOnStack + sizeof(int), + 1, + "no bytes with int sized guards outside on stack"); + } + + +EXIT: + /* Tell the parent that we are done */ + if (!DeleteFile(Comms.valuesFileName)) + { + Trace("helper: DeleteFile failed so parent (test1) is unlikely " + "to exit cleanly\n"); + } + PEDANTIC(ResetEvent, (Comms.hEvToHelper)); + if (!SetEvent(Comms.hEvFromHelper)) + { + Trace("helper: SetEvent failed so parent (test1) is unlikely " + "to exit cleanly\n"); + } + + free(pTarget); + PEDANTIC(CloseHandle, (Comms.hEvToHelper)); + PEDANTIC(CloseHandle, (Comms.hEvFromHelper)); + + if (!success) + { + Fail(""); + } + + PAL_Terminate(); + + return success ? PASS : FAIL; +} diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.c b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.c deleted file mode 100644 index 8de029d973..0000000000 --- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.c +++ /dev/null @@ -1,189 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================= -** -** Source: test1.c -** -** Purpose: Create a child process and some events for communications with it. -** When the child gets back to us with a memory location and a length, -** Call WriteProcessMemory on this location and check to see that it -** writes successfully. -** -** -**============================================================*/ - -#define UNICODE - -#include "commonconsts.h" - -#include - -int __cdecl main(int argc, char *argv[]) -{ - - PROCESS_INFORMATION pi; - STARTUPINFO si; - HANDLE hEvToHelper; - HANDLE hEvFromHelper; - DWORD dwExitCode; - - - DWORD dwRet; - char cmdComposeBuf[MAX_PATH]; - PWCHAR uniString; - - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - /* Create the signals we need for cross process communication */ - hEvToHelper = CreateEvent(NULL, TRUE, FALSE, szcToHelperEvName); - if (!hEvToHelper) - { - Fail("WriteProcessMemory: CreateEvent of '%S' failed. " - "GetLastError() returned %d.\n", szcToHelperEvName, - GetLastError()); - } - if (GetLastError() == ERROR_ALREADY_EXISTS) - { - Fail("WriteProcessMemory: CreateEvent of '%S' failed. " - "(already exists!)\n", szcToHelperEvName); - } - hEvFromHelper = CreateEvent(NULL, TRUE, FALSE, szcFromHelperEvName); - if (!hEvToHelper) - { - Fail("WriteProcessMemory: CreateEvent of '%S' failed. " - "GetLastError() returned %d.\n", szcFromHelperEvName, - GetLastError()); - } - if (GetLastError() == ERROR_ALREADY_EXISTS) - { - Fail("WriteProcessMemory: CreateEvent of '%S' failed. " - "(already exists!)\n", szcFromHelperEvName); - } - ResetEvent(hEvFromHelper); - ResetEvent(hEvToHelper); - - if (!sprintf(cmdComposeBuf, "helper %s", commsFileName)) - { - Fail("Could not convert command line\n"); - } - uniString = convert(cmdComposeBuf); - - ZeroMemory( &si, sizeof(si) ); - si.cb = sizeof(si); - ZeroMemory( &pi, sizeof(pi) ); - - /* Create a new process. This is the process that will ask for - * memory munging */ - if(!CreateProcess( NULL, uniString, NULL, NULL, - FALSE, 0, NULL, NULL, &si, &pi)) - { - Trace("ERROR: CreateProcess failed to load executable '%S'. " - "GetLastError() returned %u.\n", - uniString, GetLastError()); - free(uniString); - Fail(""); - } - free(uniString); - - while(1) - { - FILE *commsFile; - char* pSrcMemory; - char* pDestMemory; - int Count; - SIZE_T wpmCount; - char incomingCMDBuffer[MAX_PATH + 1]; - - /* wait until the helper tells us that it has given us - * something to do */ - dwRet = WaitForSingleObject(hEvFromHelper, TIMEOUT); - if (dwRet != WAIT_OBJECT_0) - { - Trace("test1 WaitForSingleObjectTest: WaitForSingleObject " - "failed (%u)\n", GetLastError()); - break; /* no more work incoming */ - } - - /* get the parameters to test WriteProcessMemory with */ - if (!(commsFile = fopen(commsFileName, "r"))) - { - /* no file means there is no more work */ - break; - } - if ( NULL == fgets(incomingCMDBuffer, MAX_PATH, commsFile)) - { - Fail ("unable to read from communication file %s " - "for reasons %u & %u\n", - errno, GetLastError()); - } - PEDANTIC1(fclose,(commsFile)); - sscanf(incomingCMDBuffer, "%u %u", &pDestMemory, &Count); - if (argc > 1) - { - Trace("Preparing to write to %u bytes @ %u ('%s')\n", - Count, pDestMemory, incomingCMDBuffer); - } - - /* compose some data to write to the client process */ - if (!(pSrcMemory = malloc(Count))) - { - Trace("could not dynamically allocate memory to copy from " - "for reasons %u & %u\n", - errno, GetLastError()); - goto doneIteration; - } - memset(pSrcMemory, nextValue, Count); - - /* do the work */ - dwRet = WriteProcessMemory(pi.hProcess, - pDestMemory, - pSrcMemory, - Count, - &wpmCount); - if (!dwRet) - { - Trace("%s: Problem: on a write to %u bytes @ %u ('%s')\n", - argv[0], Count, pDestMemory, incomingCMDBuffer); - Trace("test1 WriteProcessMemory returned a%u(!=0) (GLE=%u)\n", - GetLastError()); - } - if(Count != wpmCount) - { - Trace("%s: Problem: on a write to %u bytes @ %u ('%s')\n", - argv[0], Count, pDestMemory, incomingCMDBuffer); - Trace("The number of bytes written should have been " - "%u, but was reported as %u.\n", Count, wpmCount); - } - free(pSrcMemory); - - doneIteration: - PEDANTIC(ResetEvent, (hEvFromHelper)); - PEDANTIC(SetEvent, (hEvToHelper)); - } - - /* wait for the child process to complete */ - WaitForSingleObject ( pi.hProcess, TIMEOUT ); - /* this may return a failure code on a success path */ - - /* check the exit code from the process */ - if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) ) - { - Trace( "GetExitCodeProcess call failed with error code %u\n", - GetLastError() ); - dwExitCode = FAIL; - } - - - PEDANTIC(CloseHandle, (hEvToHelper)); - PEDANTIC(CloseHandle, (hEvFromHelper)); - PEDANTIC(CloseHandle, (pi.hThread)); - PEDANTIC(CloseHandle, (pi.hProcess)); - - PAL_TerminateEx(dwExitCode); - return dwExitCode; -} diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.cpp b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.cpp new file mode 100644 index 0000000000..f390c10c72 --- /dev/null +++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.cpp @@ -0,0 +1,189 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================= +** +** Source: test1.c +** +** Purpose: Create a child process and some events for communications with it. +** When the child gets back to us with a memory location and a length, +** Call WriteProcessMemory on this location and check to see that it +** writes successfully. +** +** +**============================================================*/ + +#define UNICODE + +#include "commonconsts.h" + +#include + +int __cdecl main(int argc, char *argv[]) +{ + + PROCESS_INFORMATION pi; + STARTUPINFO si; + HANDLE hEvToHelper; + HANDLE hEvFromHelper; + DWORD dwExitCode; + + + DWORD dwRet; + char cmdComposeBuf[MAX_PATH]; + PWCHAR uniString; + + if(0 != (PAL_Initialize(argc, argv))) + { + return FAIL; + } + + /* Create the signals we need for cross process communication */ + hEvToHelper = CreateEvent(NULL, TRUE, FALSE, szcToHelperEvName); + if (!hEvToHelper) + { + Fail("WriteProcessMemory: CreateEvent of '%S' failed. " + "GetLastError() returned %d.\n", szcToHelperEvName, + GetLastError()); + } + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + Fail("WriteProcessMemory: CreateEvent of '%S' failed. " + "(already exists!)\n", szcToHelperEvName); + } + hEvFromHelper = CreateEvent(NULL, TRUE, FALSE, szcFromHelperEvName); + if (!hEvToHelper) + { + Fail("WriteProcessMemory: CreateEvent of '%S' failed. " + "GetLastError() returned %d.\n", szcFromHelperEvName, + GetLastError()); + } + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + Fail("WriteProcessMemory: CreateEvent of '%S' failed. " + "(already exists!)\n", szcFromHelperEvName); + } + ResetEvent(hEvFromHelper); + ResetEvent(hEvToHelper); + + if (!sprintf_s(cmdComposeBuf, _countof(cmdComposeBuf), "helper %s", commsFileName)) + { + Fail("Could not convert command line\n"); + } + uniString = convert(cmdComposeBuf); + + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory( &pi, sizeof(pi) ); + + /* Create a new process. This is the process that will ask for + * memory munging */ + if(!CreateProcess( NULL, uniString, NULL, NULL, + FALSE, 0, NULL, NULL, &si, &pi)) + { + Trace("ERROR: CreateProcess failed to load executable '%S'. " + "GetLastError() returned %u.\n", + uniString, GetLastError()); + free(uniString); + Fail(""); + } + free(uniString); + + while(1) + { + FILE *commsFile; + char* pSrcMemory; + char* pDestMemory; + int Count; + SIZE_T wpmCount; + char incomingCMDBuffer[MAX_PATH + 1]; + + /* wait until the helper tells us that it has given us + * something to do */ + dwRet = WaitForSingleObject(hEvFromHelper, TIMEOUT); + if (dwRet != WAIT_OBJECT_0) + { + Trace("test1 WaitForSingleObjectTest: WaitForSingleObject " + "failed (%u)\n", GetLastError()); + break; /* no more work incoming */ + } + + /* get the parameters to test WriteProcessMemory with */ + if (!(commsFile = fopen(commsFileName, "r"))) + { + /* no file means there is no more work */ + break; + } + if ( NULL == fgets(incomingCMDBuffer, MAX_PATH, commsFile)) + { + Fail ("unable to read from communication file %s " + "for reasons %u & %u\n", + errno, GetLastError()); + } + PEDANTIC1(fclose,(commsFile)); + sscanf(incomingCMDBuffer, "%u %u", &pDestMemory, &Count); + if (argc > 1) + { + Trace("Preparing to write to %u bytes @ %u ('%s')\n", + Count, pDestMemory, incomingCMDBuffer); + } + + /* compose some data to write to the client process */ + if (!(pSrcMemory = (char*)malloc(Count))) + { + Trace("could not dynamically allocate memory to copy from " + "for reasons %u & %u\n", + errno, GetLastError()); + goto doneIteration; + } + memset(pSrcMemory, nextValue, Count); + + /* do the work */ + dwRet = WriteProcessMemory(pi.hProcess, + pDestMemory, + pSrcMemory, + Count, + &wpmCount); + if (!dwRet) + { + Trace("%s: Problem: on a write to %u bytes @ %u ('%s')\n", + argv[0], Count, pDestMemory, incomingCMDBuffer); + Trace("test1 WriteProcessMemory returned a%u(!=0) (GLE=%u)\n", + GetLastError()); + } + if(Count != wpmCount) + { + Trace("%s: Problem: on a write to %u bytes @ %u ('%s')\n", + argv[0], Count, pDestMemory, incomingCMDBuffer); + Trace("The number of bytes written should have been " + "%u, but was reported as %u.\n", Count, wpmCount); + } + free(pSrcMemory); + + doneIteration: + PEDANTIC(ResetEvent, (hEvFromHelper)); + PEDANTIC(SetEvent, (hEvToHelper)); + } + + /* wait for the child process to complete */ + WaitForSingleObject ( pi.hProcess, TIMEOUT ); + /* this may return a failure code on a success path */ + + /* check the exit code from the process */ + if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) ) + { + Trace( "GetExitCodeProcess call failed with error code %u\n", + GetLastError() ); + dwExitCode = FAIL; + } + + + PEDANTIC(CloseHandle, (hEvToHelper)); + PEDANTIC(CloseHandle, (hEvFromHelper)); + PEDANTIC(CloseHandle, (pi.hThread)); + PEDANTIC(CloseHandle, (pi.hProcess)); + + PAL_TerminateEx(dwExitCode); + return dwExitCode; +} -- cgit v1.2.3