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 --- .../threading/DuplicateHandle/CMakeLists.txt | 1 - .../threading/DuplicateHandle/test1/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test1/test1.c | 152 --------- .../threading/DuplicateHandle/test1/test1.cpp | 152 +++++++++ .../DuplicateHandle/test10/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test10/test10.c | 239 -------------- .../threading/DuplicateHandle/test10/test10.cpp | 239 ++++++++++++++ .../DuplicateHandle/test11/CMakeLists.txt | 4 +- .../DuplicateHandle/test11/childprocess.c | 74 ----- .../DuplicateHandle/test11/childprocess.cpp | 74 +++++ .../threading/DuplicateHandle/test11/test11.c | 364 --------------------- .../threading/DuplicateHandle/test11/test11.cpp | 364 +++++++++++++++++++++ .../DuplicateHandle/test12/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test12/test12.c | 129 -------- .../threading/DuplicateHandle/test12/test12.cpp | 129 ++++++++ .../threading/DuplicateHandle/test2/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test2/test2.c | 96 ------ .../threading/DuplicateHandle/test2/test2.cpp | 96 ++++++ .../threading/DuplicateHandle/test3/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test3/test3.c | 123 ------- .../threading/DuplicateHandle/test3/test3.cpp | 123 +++++++ .../threading/DuplicateHandle/test4/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test4/test4.c | 239 -------------- .../threading/DuplicateHandle/test4/test4.cpp | 239 ++++++++++++++ .../threading/DuplicateHandle/test5/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test5/test5.c | 145 -------- .../threading/DuplicateHandle/test5/test5.cpp | 145 ++++++++ .../threading/DuplicateHandle/test6/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test6/test6.c | 146 --------- .../threading/DuplicateHandle/test6/test6.cpp | 146 +++++++++ .../threading/DuplicateHandle/test7/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test7/test7.c | 149 --------- .../threading/DuplicateHandle/test7/test7.cpp | 149 +++++++++ .../threading/DuplicateHandle/test8/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test8/test8.c | 164 ---------- .../threading/DuplicateHandle/test8/test8.cpp | 164 ++++++++++ .../threading/DuplicateHandle/test9/CMakeLists.txt | 2 +- .../threading/DuplicateHandle/test9/test9.c | 127 ------- .../threading/DuplicateHandle/test9/test9.cpp | 127 +++++++ 39 files changed, 2160 insertions(+), 2161 deletions(-) delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.cpp delete mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.c create mode 100644 src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.cpp (limited to 'src/pal/tests/palsuite/threading/DuplicateHandle') diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/CMakeLists.txt index b908c1246b..9d5fc53a2d 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/CMakeLists.txt @@ -11,5 +11,4 @@ add_subdirectory(test5) add_subdirectory(test6) add_subdirectory(test7) add_subdirectory(test8) -add_subdirectory(test9) diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test1/CMakeLists.txt index 04588b75fe..18b1927a4e 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test1/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test1/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test1.c + test1.cpp ) add_executable(paltest_duplicatehandle_test1 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.c deleted file mode 100644 index e080e98ae8..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.c +++ /dev/null @@ -1,152 +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 (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function. -** This test will create two handles to file, one to write and -** one to read what was written. Test on a closed handle and a -** NULL handle, both should fail. -** -** -**===================================================================*/ -#include - -int __cdecl main(int argc, char **argv) -{ - HANDLE hFile; - HANDLE hDupFile; - char buf[256]; - char teststr[] = "A uNiQuE tEsT sTrInG"; - char lpFileName[] = "testfile.txt"; - DWORD dwBytesWritten; - DWORD dwBytesRead; - BOOL bRetVal; - - /*Initalize the PAL*/ - if ((PAL_Initialize(argc,argv)) != 0) - { - return (FAIL); - } - - /*Create a file handle with CreateFile*/ - hFile = CreateFile(lpFileName, - GENERIC_WRITE|GENERIC_READ, - FILE_SHARE_WRITE|FILE_SHARE_READ, - NULL, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - Fail("ERROR: %u :unable to create file \"%s\".\n", - GetLastError(), - lpFileName); - } - - /*Write test string to the file.*/ - bRetVal = WriteFile(hFile, // handle to file - teststr, // data buffer - strlen(teststr), // number of bytes to write - &dwBytesWritten, // number of bytes written - NULL); // overlapped buffer - - if (bRetVal == FALSE) - { - Trace("ERROR: %u : unable to write to file handle " - "hFile=0x%lx\n", - GetLastError(), - hFile); - CloseHandle(hFile); - Fail(""); - } - - /*Create a duplicate handle with DuplicateHandle.*/ - if (!(DuplicateHandle( - GetCurrentProcess(), - hFile, - GetCurrentProcess(), - &hDupFile, - GENERIC_READ|GENERIC_WRITE, - FALSE, - DUPLICATE_SAME_ACCESS))) - { - Trace("ERROR: %u : Fail to create the duplicate handle" - " to hFile=0x%lx\n", - GetLastError(), - hFile); - CloseHandle(hFile); - Fail(""); - } - - memset(buf, 0, 256); - - /*Read from the Duplicated handle.*/ - bRetVal = ReadFile(hDupFile, - buf, - 256, - &dwBytesRead, - NULL); - if (bRetVal == FALSE) - { - Trace("ERROR: %u :unable to read from file handle " - "hFile=0x%lx\n", - GetLastError(), - hFile); - CloseHandle(hFile); - CloseHandle(hDupFile); - Fail(""); - } - - /*Compare what was written to what was read.*/ - if (memcmp(teststr, buf, dwBytesRead) != 0) - { - Trace("ERROR: expected %s, got %s\n", teststr, buf); - CloseHandle(hFile); - CloseHandle(hDupFile); - Fail(""); - } - - /*Close the handles*/ - CloseHandle(hFile); - CloseHandle(hDupFile); - - /*Failure test: Create DuplicateHandle to a closed handle*/ - if ((DuplicateHandle( - GetCurrentProcess(), - hFile, - GetCurrentProcess(), - &hDupFile, - GENERIC_READ|GENERIC_WRITE, - FALSE, - DUPLICATE_SAME_ACCESS))) - { - Fail("ERROR: %u :Created a duplicate handle to" - " a closed handle hFile=0x%lx\n", - GetLastError(), - hFile); - } - - /*Failure test: Create DuplicateHandle to a NULL handle*/ - hFile = NULL; - if ((DuplicateHandle( - GetCurrentProcess(), - hFile, - GetCurrentProcess(), - &hDupFile, - GENERIC_READ|GENERIC_WRITE, - FALSE, - DUPLICATE_SAME_ACCESS))) - { - Fail("ERROR: %u :Created a duplicate handle to " - " a NULL handle hFile=0x%lx\n", - GetLastError(), - hFile); - } - - PAL_Terminate(); - return (PASS); -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.cpp new file mode 100644 index 0000000000..e080e98ae8 --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.cpp @@ -0,0 +1,152 @@ +// 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 (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function. +** This test will create two handles to file, one to write and +** one to read what was written. Test on a closed handle and a +** NULL handle, both should fail. +** +** +**===================================================================*/ +#include + +int __cdecl main(int argc, char **argv) +{ + HANDLE hFile; + HANDLE hDupFile; + char buf[256]; + char teststr[] = "A uNiQuE tEsT sTrInG"; + char lpFileName[] = "testfile.txt"; + DWORD dwBytesWritten; + DWORD dwBytesRead; + BOOL bRetVal; + + /*Initalize the PAL*/ + if ((PAL_Initialize(argc,argv)) != 0) + { + return (FAIL); + } + + /*Create a file handle with CreateFile*/ + hFile = CreateFile(lpFileName, + GENERIC_WRITE|GENERIC_READ, + FILE_SHARE_WRITE|FILE_SHARE_READ, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + Fail("ERROR: %u :unable to create file \"%s\".\n", + GetLastError(), + lpFileName); + } + + /*Write test string to the file.*/ + bRetVal = WriteFile(hFile, // handle to file + teststr, // data buffer + strlen(teststr), // number of bytes to write + &dwBytesWritten, // number of bytes written + NULL); // overlapped buffer + + if (bRetVal == FALSE) + { + Trace("ERROR: %u : unable to write to file handle " + "hFile=0x%lx\n", + GetLastError(), + hFile); + CloseHandle(hFile); + Fail(""); + } + + /*Create a duplicate handle with DuplicateHandle.*/ + if (!(DuplicateHandle( + GetCurrentProcess(), + hFile, + GetCurrentProcess(), + &hDupFile, + GENERIC_READ|GENERIC_WRITE, + FALSE, + DUPLICATE_SAME_ACCESS))) + { + Trace("ERROR: %u : Fail to create the duplicate handle" + " to hFile=0x%lx\n", + GetLastError(), + hFile); + CloseHandle(hFile); + Fail(""); + } + + memset(buf, 0, 256); + + /*Read from the Duplicated handle.*/ + bRetVal = ReadFile(hDupFile, + buf, + 256, + &dwBytesRead, + NULL); + if (bRetVal == FALSE) + { + Trace("ERROR: %u :unable to read from file handle " + "hFile=0x%lx\n", + GetLastError(), + hFile); + CloseHandle(hFile); + CloseHandle(hDupFile); + Fail(""); + } + + /*Compare what was written to what was read.*/ + if (memcmp(teststr, buf, dwBytesRead) != 0) + { + Trace("ERROR: expected %s, got %s\n", teststr, buf); + CloseHandle(hFile); + CloseHandle(hDupFile); + Fail(""); + } + + /*Close the handles*/ + CloseHandle(hFile); + CloseHandle(hDupFile); + + /*Failure test: Create DuplicateHandle to a closed handle*/ + if ((DuplicateHandle( + GetCurrentProcess(), + hFile, + GetCurrentProcess(), + &hDupFile, + GENERIC_READ|GENERIC_WRITE, + FALSE, + DUPLICATE_SAME_ACCESS))) + { + Fail("ERROR: %u :Created a duplicate handle to" + " a closed handle hFile=0x%lx\n", + GetLastError(), + hFile); + } + + /*Failure test: Create DuplicateHandle to a NULL handle*/ + hFile = NULL; + if ((DuplicateHandle( + GetCurrentProcess(), + hFile, + GetCurrentProcess(), + &hDupFile, + GENERIC_READ|GENERIC_WRITE, + FALSE, + DUPLICATE_SAME_ACCESS))) + { + Fail("ERROR: %u :Created a duplicate handle to " + " a NULL handle hFile=0x%lx\n", + GetLastError(), + hFile); + } + + PAL_Terminate(); + return (PASS); +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test10/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test10/CMakeLists.txt index ba16252cb4..98c7a273dc 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test10/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test10/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test10.c + test10.cpp ) add_executable(paltest_duplicatehandle_test10 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.c deleted file mode 100644 index 108d748de6..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.c +++ /dev/null @@ -1,239 +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: test10.c (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function. -** This tests the operation of a duplicated Semaphore handle -** -** -**===================================================================*/ - -#include - -enum wait_results -{ - WR_WAITING, - WR_GOT_MUTEX, - WR_TIMED_OUT, - WR_RELEASED -}; - - -volatile int t1_result=WR_WAITING; -volatile int t2_result=WR_WAITING; - - -DWORD PALAPI ThreadTest1(LPVOID lpParam) -{ - DWORD dwWait; - - dwWait = WaitForSingleObject((HANDLE)lpParam, 0); - if (dwWait == WAIT_OBJECT_0) - { - /* tell the main thread we got the mutex */ - t1_result=WR_GOT_MUTEX; - - /* wait for main thread to tell us to release the mutex */ - while(WR_GOT_MUTEX == t1_result) - Sleep(1); - ReleaseSemaphore((HANDLE)lpParam, 1, NULL); - - /* tell the main thread we released the mutex */ - t1_result = WR_RELEASED; - } - else - { - t1_result = WR_TIMED_OUT; - } - return 0; -} - -DWORD PALAPI ThreadTest2(LPVOID lpParam) -{ - DWORD dwWait; - - dwWait = WaitForSingleObject((HANDLE)lpParam, 0 ); - if (dwWait == WAIT_OBJECT_0) - { - ReleaseSemaphore((HANDLE)lpParam, 1, NULL); - t2_result = WR_GOT_MUTEX; - } - else - { - t2_result = WR_TIMED_OUT; - } - - return 0; -} - - -int __cdecl main(int argc, char **argv) -{ - - HANDLE hDupSemaphore; - HANDLE hSemaphore; - HANDLE hThread; - HANDLE hThread2; - BOOL bDupHandle=FALSE; - DWORD dwThreadId = 0; - - if ((PAL_Initialize(argc,argv)) != 0) - { - return(FAIL); - } - - hSemaphore = CreateSemaphoreW( NULL, - 1, - 1, - NULL); - if (hSemaphore == NULL) - { - Fail("PALSUITE ERROR:%u: Unable to create mutex\n", - GetLastError()); - } - - /*Create Duplicate of the Semaphore above*/ - bDupHandle = DuplicateHandle(GetCurrentProcess(), - hSemaphore, - GetCurrentProcess(), - &hDupSemaphore, - GENERIC_READ|GENERIC_WRITE, - FALSE, - DUPLICATE_SAME_ACCESS); - if (!bDupHandle) - { - Trace("PALSUITE ERROR:%u: Created the duplicate handle to " - "closed event handle hSemaphore=0x%lx\n", - GetLastError(), - hSemaphore); - CloseHandle(hSemaphore); - Fail(""); - } - - /*Create a thread to test the Semaphore*/ - hThread = CreateThread(NULL, - 0, - &ThreadTest1, - hSemaphore, - 0, - &dwThreadId); - if (hThread == NULL) - { - Trace("PALSUITE ERROR:%u: unable to create thread\n", - GetLastError()); - CloseHandle(hSemaphore); - CloseHandle(hDupSemaphore); - Fail(""); - } - - /* wait until thread has taken the mutex */ - while (WR_WAITING == t1_result) - Sleep(1); - - if(WR_TIMED_OUT == t1_result) - { - Trace("PALSUITE ERROR: %u: thread couldn't acquire the semaphore\n", - GetLastError()); - CloseHandle(hSemaphore); - CloseHandle(hDupSemaphore); - CloseHandle(hThread); - Fail(""); - } - - /*Create a second thread to use the Semaphore's duplicate handle*/ - /*This thread should block since the Semaphore is owned by another - thread*/ - hThread2 = CreateThread(NULL, - 0, - &ThreadTest2, - hDupSemaphore, - 0, - &dwThreadId); - - if (hThread2 == NULL) - { - Trace("PALSUITE ERROR:%u: unable to create thread\n", - GetLastError()); - CloseHandle(hSemaphore); - CloseHandle(hDupSemaphore); - CloseHandle(hThread); - Fail(""); - } - - /* wait until thread has tried to take the mutex */ - while (WR_WAITING == t2_result) - Sleep(1); - - if (WR_TIMED_OUT != t2_result ) - { - Trace("PALSUITE ERROR:%u: Able to take mutex %#x while its " - "duplicate %#x is held\n", GetLastError(), hDupSemaphore, - hSemaphore); - CloseHandle(hSemaphore); - CloseHandle(hDupSemaphore); - CloseHandle(hThread); - CloseHandle(hThread2); - Fail(""); - } - - /* reset second thread status */ - t2_result = WR_WAITING; - - /* tell thread 1 to release the mutex */ - t1_result = WR_WAITING; - - /* wait for thread 1 to release the mutex */ - while (WR_WAITING == t1_result) - Sleep(1); - - CloseHandle(hThread2); - - /*Re-Create the second thread to reuse the duplicated Semaphore*/ - /*Since the Semaphore has since been released, the thread should - put WR_GOT_MUTEX into t2_result */ - hThread2 = CreateThread(NULL, - 0, - &ThreadTest2, - hDupSemaphore, - 0, - &dwThreadId); - - if (hThread2 == NULL) - { - Trace("PALSUITE ERROR:%u: unable to create thread\n", - GetLastError()); - CloseHandle(hSemaphore); - CloseHandle(hDupSemaphore); - CloseHandle(hThread); - Fail(""); - } - - /* wait until thread has taken the semaphore */ - while (WR_WAITING == t2_result) - Sleep(1); - - if (WR_GOT_MUTEX != t2_result ) - { - Trace("PALSUITE ERROR:%u: Unable to take semaphore %#x after its" - " duplicate %#x was released\n", GetLastError(), hDupSemaphore, - hSemaphore); - CloseHandle(hSemaphore); - CloseHandle(hDupSemaphore); - CloseHandle(hThread); - CloseHandle(hThread2); - Fail(""); - } - - /*Cleanup.*/ - CloseHandle(hSemaphore); - CloseHandle(hDupSemaphore); - CloseHandle(hThread); - CloseHandle(hThread2); - - PAL_Terminate(); - return (PASS); -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.cpp new file mode 100644 index 0000000000..108d748de6 --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.cpp @@ -0,0 +1,239 @@ +// 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: test10.c (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function. +** This tests the operation of a duplicated Semaphore handle +** +** +**===================================================================*/ + +#include + +enum wait_results +{ + WR_WAITING, + WR_GOT_MUTEX, + WR_TIMED_OUT, + WR_RELEASED +}; + + +volatile int t1_result=WR_WAITING; +volatile int t2_result=WR_WAITING; + + +DWORD PALAPI ThreadTest1(LPVOID lpParam) +{ + DWORD dwWait; + + dwWait = WaitForSingleObject((HANDLE)lpParam, 0); + if (dwWait == WAIT_OBJECT_0) + { + /* tell the main thread we got the mutex */ + t1_result=WR_GOT_MUTEX; + + /* wait for main thread to tell us to release the mutex */ + while(WR_GOT_MUTEX == t1_result) + Sleep(1); + ReleaseSemaphore((HANDLE)lpParam, 1, NULL); + + /* tell the main thread we released the mutex */ + t1_result = WR_RELEASED; + } + else + { + t1_result = WR_TIMED_OUT; + } + return 0; +} + +DWORD PALAPI ThreadTest2(LPVOID lpParam) +{ + DWORD dwWait; + + dwWait = WaitForSingleObject((HANDLE)lpParam, 0 ); + if (dwWait == WAIT_OBJECT_0) + { + ReleaseSemaphore((HANDLE)lpParam, 1, NULL); + t2_result = WR_GOT_MUTEX; + } + else + { + t2_result = WR_TIMED_OUT; + } + + return 0; +} + + +int __cdecl main(int argc, char **argv) +{ + + HANDLE hDupSemaphore; + HANDLE hSemaphore; + HANDLE hThread; + HANDLE hThread2; + BOOL bDupHandle=FALSE; + DWORD dwThreadId = 0; + + if ((PAL_Initialize(argc,argv)) != 0) + { + return(FAIL); + } + + hSemaphore = CreateSemaphoreW( NULL, + 1, + 1, + NULL); + if (hSemaphore == NULL) + { + Fail("PALSUITE ERROR:%u: Unable to create mutex\n", + GetLastError()); + } + + /*Create Duplicate of the Semaphore above*/ + bDupHandle = DuplicateHandle(GetCurrentProcess(), + hSemaphore, + GetCurrentProcess(), + &hDupSemaphore, + GENERIC_READ|GENERIC_WRITE, + FALSE, + DUPLICATE_SAME_ACCESS); + if (!bDupHandle) + { + Trace("PALSUITE ERROR:%u: Created the duplicate handle to " + "closed event handle hSemaphore=0x%lx\n", + GetLastError(), + hSemaphore); + CloseHandle(hSemaphore); + Fail(""); + } + + /*Create a thread to test the Semaphore*/ + hThread = CreateThread(NULL, + 0, + &ThreadTest1, + hSemaphore, + 0, + &dwThreadId); + if (hThread == NULL) + { + Trace("PALSUITE ERROR:%u: unable to create thread\n", + GetLastError()); + CloseHandle(hSemaphore); + CloseHandle(hDupSemaphore); + Fail(""); + } + + /* wait until thread has taken the mutex */ + while (WR_WAITING == t1_result) + Sleep(1); + + if(WR_TIMED_OUT == t1_result) + { + Trace("PALSUITE ERROR: %u: thread couldn't acquire the semaphore\n", + GetLastError()); + CloseHandle(hSemaphore); + CloseHandle(hDupSemaphore); + CloseHandle(hThread); + Fail(""); + } + + /*Create a second thread to use the Semaphore's duplicate handle*/ + /*This thread should block since the Semaphore is owned by another + thread*/ + hThread2 = CreateThread(NULL, + 0, + &ThreadTest2, + hDupSemaphore, + 0, + &dwThreadId); + + if (hThread2 == NULL) + { + Trace("PALSUITE ERROR:%u: unable to create thread\n", + GetLastError()); + CloseHandle(hSemaphore); + CloseHandle(hDupSemaphore); + CloseHandle(hThread); + Fail(""); + } + + /* wait until thread has tried to take the mutex */ + while (WR_WAITING == t2_result) + Sleep(1); + + if (WR_TIMED_OUT != t2_result ) + { + Trace("PALSUITE ERROR:%u: Able to take mutex %#x while its " + "duplicate %#x is held\n", GetLastError(), hDupSemaphore, + hSemaphore); + CloseHandle(hSemaphore); + CloseHandle(hDupSemaphore); + CloseHandle(hThread); + CloseHandle(hThread2); + Fail(""); + } + + /* reset second thread status */ + t2_result = WR_WAITING; + + /* tell thread 1 to release the mutex */ + t1_result = WR_WAITING; + + /* wait for thread 1 to release the mutex */ + while (WR_WAITING == t1_result) + Sleep(1); + + CloseHandle(hThread2); + + /*Re-Create the second thread to reuse the duplicated Semaphore*/ + /*Since the Semaphore has since been released, the thread should + put WR_GOT_MUTEX into t2_result */ + hThread2 = CreateThread(NULL, + 0, + &ThreadTest2, + hDupSemaphore, + 0, + &dwThreadId); + + if (hThread2 == NULL) + { + Trace("PALSUITE ERROR:%u: unable to create thread\n", + GetLastError()); + CloseHandle(hSemaphore); + CloseHandle(hDupSemaphore); + CloseHandle(hThread); + Fail(""); + } + + /* wait until thread has taken the semaphore */ + while (WR_WAITING == t2_result) + Sleep(1); + + if (WR_GOT_MUTEX != t2_result ) + { + Trace("PALSUITE ERROR:%u: Unable to take semaphore %#x after its" + " duplicate %#x was released\n", GetLastError(), hDupSemaphore, + hSemaphore); + CloseHandle(hSemaphore); + CloseHandle(hDupSemaphore); + CloseHandle(hThread); + CloseHandle(hThread2); + Fail(""); + } + + /*Cleanup.*/ + CloseHandle(hSemaphore); + CloseHandle(hDupSemaphore); + CloseHandle(hThread); + CloseHandle(hThread2); + + PAL_Terminate(); + return (PASS); +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/CMakeLists.txt index 68ce7b23fb..f47f9bc350 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(TESTSOURCES - test11.c + test11.cpp ) add_executable(paltest_duplicatehandle_test11 @@ -20,7 +20,7 @@ target_link_libraries(paltest_duplicatehandle_test11 set(HELPERSOURCES - childprocess.c + childprocess.cpp ) add_executable(paltest_duplicatehandle_test11_child diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.c deleted file mode 100644 index d5b310e46c..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.c +++ /dev/null @@ -1,74 +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: childprocess.c -** -** Purpose: Test to ensure DuplicateHandle works properly. -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** CreateMutexW -** WaitForSingleObject -** CloseHandle -** -** -**=========================================================*/ - -#include -#include "myexitcode.h" - - -int __cdecl main( int argc, char **argv ) -{ - HANDLE hMutex; - WCHAR wszMutexName[] = { 'T','E','S','T','1','1','\0' }; - DWORD dwRet; - int i; - - /* initialize the PAL */ - if( PAL_Initialize(argc, argv) != 0 ) - { - return( FAIL ); - } - - /* open a mutex to synchronize with the parent process */ - hMutex = CreateMutexW( NULL, FALSE, wszMutexName ); - if( hMutex == NULL ) - { - Fail( "ERROR:%lu:CreateMutex() call failed\r\n", GetLastError() ); - } - - /* acquire the mutex lock */ - dwRet = WaitForSingleObject( hMutex, 10000 ); - if( dwRet != WAIT_OBJECT_0 ) - { - Trace( "ERROR:WaitForSingleObject() returned %lu, " - "expected WAIT_OBJECT_0", - dwRet ); - if( ! CloseHandle( hMutex ) ) - { - Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); - } - Fail( "test failed\n" ); - } - - - /* simulate some activity */ - for( i=0; i<50000; i++ ) - ; - - /* close our mutex handle */ - if( ! CloseHandle( hMutex ) ) - { - Fail( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); - } - - /* terminate the PAL */ - PAL_Terminate(); - - /* return the predefined exit code */ - return TEST_EXIT_CODE; -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.cpp new file mode 100644 index 0000000000..d5b310e46c --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.cpp @@ -0,0 +1,74 @@ +// 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: childprocess.c +** +** Purpose: Test to ensure DuplicateHandle works properly. +** +** Dependencies: PAL_Initialize +** PAL_Terminate +** CreateMutexW +** WaitForSingleObject +** CloseHandle +** +** +**=========================================================*/ + +#include +#include "myexitcode.h" + + +int __cdecl main( int argc, char **argv ) +{ + HANDLE hMutex; + WCHAR wszMutexName[] = { 'T','E','S','T','1','1','\0' }; + DWORD dwRet; + int i; + + /* initialize the PAL */ + if( PAL_Initialize(argc, argv) != 0 ) + { + return( FAIL ); + } + + /* open a mutex to synchronize with the parent process */ + hMutex = CreateMutexW( NULL, FALSE, wszMutexName ); + if( hMutex == NULL ) + { + Fail( "ERROR:%lu:CreateMutex() call failed\r\n", GetLastError() ); + } + + /* acquire the mutex lock */ + dwRet = WaitForSingleObject( hMutex, 10000 ); + if( dwRet != WAIT_OBJECT_0 ) + { + Trace( "ERROR:WaitForSingleObject() returned %lu, " + "expected WAIT_OBJECT_0", + dwRet ); + if( ! CloseHandle( hMutex ) ) + { + Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); + } + Fail( "test failed\n" ); + } + + + /* simulate some activity */ + for( i=0; i<50000; i++ ) + ; + + /* close our mutex handle */ + if( ! CloseHandle( hMutex ) ) + { + Fail( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); + } + + /* terminate the PAL */ + PAL_Terminate(); + + /* return the predefined exit code */ + return TEST_EXIT_CODE; +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.c deleted file mode 100644 index b05244c4b8..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.c +++ /dev/null @@ -1,364 +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: test11.c -** -** Purpose: -** -** Test to ensure proper operation of the DuplicateHandle API. -** The test launches a trivial child process, then opens -** a handle to it using OpenProcess. It then duplicates that -** handle and uses it to wait for the child process to terminate, -** and then checks the exit code of the child process in order to -** verify that it was in fact a handle to the correct -** process. The test tries to duplicate the handle again after -** the process has been closed, to verify that failure ensues. -** -** Dependencies: PAL_Initialize -** PAL_Terminate -** Fail -** ZeroMemory -** GetCurrentDirectoryW -** CreateProcessW -** WaitForSingleObject -** CreateMutexW -** ReleaseMutex -** CloseHandle -** GetLastError -** strlen -** strncpy -** -** -**===========================================================================*/ -#include -#include "myexitcode.h" - - -static const char* rgchPathDelim = "\\"; - - -int -mkAbsoluteFilename( LPSTR dirName, - DWORD dwDirLength, - LPCSTR fileName, - DWORD dwFileLength, - LPSTR absPathName ) -{ - DWORD sizeDN, sizeFN, sizeAPN; - - sizeDN = strlen( dirName ); - sizeFN = strlen( fileName ); - sizeAPN = (sizeDN + 1 + sizeFN + 1); - - /* ensure ((dirName + DELIM + fileName + \0) =< _MAX_PATH ) */ - if( sizeAPN > _MAX_PATH ) - { - return ( 0 ); - } - - strncpy( absPathName, dirName, dwDirLength +1 ); - strncpy( absPathName, rgchPathDelim, 2 ); - strncpy( absPathName, fileName, dwFileLength +1 ); - - return (sizeAPN); - -} - - -int __cdecl main( int argc, char **argv ) - -{ - const char* rgchChildFile = "childprocess"; - - STARTUPINFO si; - PROCESS_INFORMATION pi; - - DWORD dwError; - DWORD dwExitCode; - DWORD dwFileLength; - DWORD dwDirLength; - DWORD dwSize; - DWORD dwRet; - - HANDLE hMutex; - HANDLE hChildProcess; - HANDLE hDupChildProcess; - - char rgchDirName[_MAX_DIR]; - char absPathBuf[_MAX_PATH]; - char* rgchAbsPathName; - - BOOL ret = FAIL; - BOOL bChildDone = FALSE; - WCHAR wszMutexName[] = { 'T','E','S','T','1','1','\0' }; - - /* initialize the PAL */ - if( PAL_Initialize(argc, argv) != 0 ) - { - return( FAIL ); - } - - /* create a mutex to synchronize with the child process */ - hMutex = CreateMutexW( NULL, TRUE, wszMutexName ); - if( hMutex == NULL ) - { - Fail( "ERROR:%lu:CreateMutex() call failed\r\n", GetLastError() ); - } - - /* zero our process and startup info structures */ - ZeroMemory( &si, sizeof(si) ); - si.cb = sizeof( si ); - ZeroMemory( &pi, sizeof(pi) ); - - /* build the absolute path to the child process */ - rgchAbsPathName = &absPathBuf[0]; - dwFileLength = strlen( rgchChildFile ); - - dwDirLength = GetCurrentDirectory( _MAX_PATH, rgchDirName ); - if( dwDirLength == 0 ) - { - dwError = GetLastError(); - if( ReleaseMutex( hMutex ) == 0 ) - { - Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); - } - if( CloseHandle( hMutex ) == 0 ) - { - Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); - } - Fail( "GetCurrentDirectory call failed with error code %d\n", - dwError ); - } - - dwSize = mkAbsoluteFilename( rgchDirName, - dwDirLength, - rgchChildFile, - dwFileLength, - rgchAbsPathName ); - if( dwSize == 0 ) - { - if( ReleaseMutex( hMutex ) == 0 ) - { - Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); - } - if( CloseHandle( hMutex ) == 0 ) - { - Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); - } - Fail( "Palsuite Code: mkAbsoluteFilename() call failed. Could ", - "not build absolute path name to file\n. Exiting.\n" ); - } - - /* launch the child process */ - if( !CreateProcess( NULL, /* module name to execute */ - rgchAbsPathName, /* command line */ - NULL, /* process handle not */ - /* inheritable */ - NULL, /* thread handle not */ - /*inheritable */ - FALSE, /* handle inheritance */ - CREATE_NEW_CONSOLE, /* dwCreationFlags */ - NULL, /* use parent's environment */ - NULL, /* use parent's starting */ - /* directory */ - &si, /* startup info struct */ - &pi ) /* process info struct */ - ) - { - dwError = GetLastError(); - if( ReleaseMutex( hMutex ) == 0 ) - { - Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); - } - if( CloseHandle( hMutex ) == 0 ) - { - Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); - } - Fail( "CreateProcess call failed with error code %d\n", - dwError ); - } - - /* open another handle to the child process */ - hChildProcess = OpenProcess( PROCESS_ALL_ACCESS, /* access */ - FALSE, /* inheritable */ - pi.dwProcessId /* process id */ - ); - if( hChildProcess == NULL ) - { - dwError = GetLastError(); - if( ReleaseMutex( hMutex ) == 0 ) - { - Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); - } - Trace( "ERROR:%lu:OpenProcess call failed\n", dwError ); - goto cleanup3; - } - - /* duplicate the child process handle */ - if( ! DuplicateHandle( GetCurrentProcess(), - hChildProcess, - GetCurrentProcess(), - &hDupChildProcess, - GENERIC_READ|GENERIC_WRITE, - FALSE, - DUPLICATE_SAME_ACCESS) ) - { - Trace( "ERROR:%lu:DuplicateHandle() call failed\n", GetLastError() ); - if( ReleaseMutex( hMutex ) == 0 ) - { - Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); - } - goto cleanup2; - } - - /* release the mutex so the child can proceed */ - if( ReleaseMutex( hMutex ) == 0 ) - { - Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); - goto cleanup1; - } - - /* wait for the child process to complete, using the new handle */ - dwRet = WaitForSingleObject( hDupChildProcess, 10000 ); - if( dwRet != WAIT_OBJECT_0 ) - { - Trace( "ERROR:WaitForSingleObject call returned %lu, " - "expected WAIT_OBJECT_0", - dwRet ); - goto cleanup1; - } - - /* remember that we waited until the child was finished */ - bChildDone = TRUE; - - /* check the exit code from the process -- this is a bit of an */ - /* extra verification that we opened the correct process handle */ - if( ! GetExitCodeProcess( hDupChildProcess, &dwExitCode ) ) - { - Trace( "ERROR:%lu:GetExitCodeProcess call failed\n", GetLastError() ); - goto cleanup1; - } - - /* verification */ - if( (dwExitCode & 0xFF) != (TEST_EXIT_CODE & 0xFF) ) - { - Trace( "GetExitCodeProcess returned an incorrect exit code %d, " - "expected value is %d\n", - (dwExitCode & 0xFF), - (TEST_EXIT_CODE & 0xFF)); - goto cleanup1; - } - - /* close the duplicate handle */ - if( ! CloseHandle( hDupChildProcess ) ) - { - Trace( "ERROR:%lu:CloseHandle call failed\n", GetLastError() ); - goto cleanup2; - } - - /* close the child process handle */ - if( ! CloseHandle ( hChildProcess ) ) - { - Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); - goto cleanup3; - } - - /* try to call duplicate handle on the closed child process handle */ - if( DuplicateHandle( GetCurrentProcess(), - hChildProcess, - GetCurrentProcess(), - &hDupChildProcess, - GENERIC_READ|GENERIC_WRITE, - FALSE, - DUPLICATE_SAME_ACCESS) ) - { - Trace( "ERROR:%lu:DuplicateHandle call succeeded on " - "a closed process handle, expected ERROR_INVALID_HANDLE\n" ); - if( ! CloseHandle( hDupChildProcess ) ) - { - Trace( "ERROR:%lu:CloseHandle call failed\n", GetLastError() ); - } - goto cleanup3; - } - - /* verify that the last error was ERROR_INVALID_HANDLE */ - dwRet = GetLastError(); - if( dwRet != ERROR_INVALID_HANDLE ) - { - Trace( "ERROR:DuplicateHandle returned %lu, " - "expected ERROR_INVALID_HANDLE\n", - dwRet ); - goto cleanup3; - } - - - /* success if we get here */ - ret = PASS; - - /* skip the cleanup stuff that's already done */ - goto cleanup3; - - -cleanup1: - /* close our duplicate handle */ - if( ! CloseHandle( hDupChildProcess ) ) - { - Trace( "ERROR:%lu:CloseHandle call failed\n", GetLastError() ); - ret = FAIL; - } - -cleanup2: - /* wait on the child process to complete if necessary */ - if( ! bChildDone ) - { - dwRet = WaitForSingleObject( hChildProcess, 10000 ); - if( dwRet != WAIT_OBJECT_0 ) - { - Trace( "ERROR:WaitForSingleObject call returned %lu, " - "expected WAIT_OBJECT_0", - dwRet ); - ret = FAIL; - } - } - - /* close our child process handle */ - if( CloseHandle ( hChildProcess ) == 0 ) - { - Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); - ret = FAIL; - } - -cleanup3: - /* close all our other handles */ - if( CloseHandle ( pi.hProcess ) == 0 ) - { - Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); - ret = FAIL; - } - if( CloseHandle ( pi.hThread ) == 0 ) - { - Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); - ret = FAIL; - } - if( CloseHandle( hMutex ) == 0 ) - { - Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); - ret = FAIL; - } - - if( ret == FAIL ) - { - Fail( "test failed\n" ); - } - - - - /* terminate the PAL */ - PAL_Terminate(); - - /* return success */ - return PASS; -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.cpp new file mode 100644 index 0000000000..b05244c4b8 --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.cpp @@ -0,0 +1,364 @@ +// 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: test11.c +** +** Purpose: +** +** Test to ensure proper operation of the DuplicateHandle API. +** The test launches a trivial child process, then opens +** a handle to it using OpenProcess. It then duplicates that +** handle and uses it to wait for the child process to terminate, +** and then checks the exit code of the child process in order to +** verify that it was in fact a handle to the correct +** process. The test tries to duplicate the handle again after +** the process has been closed, to verify that failure ensues. +** +** Dependencies: PAL_Initialize +** PAL_Terminate +** Fail +** ZeroMemory +** GetCurrentDirectoryW +** CreateProcessW +** WaitForSingleObject +** CreateMutexW +** ReleaseMutex +** CloseHandle +** GetLastError +** strlen +** strncpy +** +** +**===========================================================================*/ +#include +#include "myexitcode.h" + + +static const char* rgchPathDelim = "\\"; + + +int +mkAbsoluteFilename( LPSTR dirName, + DWORD dwDirLength, + LPCSTR fileName, + DWORD dwFileLength, + LPSTR absPathName ) +{ + DWORD sizeDN, sizeFN, sizeAPN; + + sizeDN = strlen( dirName ); + sizeFN = strlen( fileName ); + sizeAPN = (sizeDN + 1 + sizeFN + 1); + + /* ensure ((dirName + DELIM + fileName + \0) =< _MAX_PATH ) */ + if( sizeAPN > _MAX_PATH ) + { + return ( 0 ); + } + + strncpy( absPathName, dirName, dwDirLength +1 ); + strncpy( absPathName, rgchPathDelim, 2 ); + strncpy( absPathName, fileName, dwFileLength +1 ); + + return (sizeAPN); + +} + + +int __cdecl main( int argc, char **argv ) + +{ + const char* rgchChildFile = "childprocess"; + + STARTUPINFO si; + PROCESS_INFORMATION pi; + + DWORD dwError; + DWORD dwExitCode; + DWORD dwFileLength; + DWORD dwDirLength; + DWORD dwSize; + DWORD dwRet; + + HANDLE hMutex; + HANDLE hChildProcess; + HANDLE hDupChildProcess; + + char rgchDirName[_MAX_DIR]; + char absPathBuf[_MAX_PATH]; + char* rgchAbsPathName; + + BOOL ret = FAIL; + BOOL bChildDone = FALSE; + WCHAR wszMutexName[] = { 'T','E','S','T','1','1','\0' }; + + /* initialize the PAL */ + if( PAL_Initialize(argc, argv) != 0 ) + { + return( FAIL ); + } + + /* create a mutex to synchronize with the child process */ + hMutex = CreateMutexW( NULL, TRUE, wszMutexName ); + if( hMutex == NULL ) + { + Fail( "ERROR:%lu:CreateMutex() call failed\r\n", GetLastError() ); + } + + /* zero our process and startup info structures */ + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof( si ); + ZeroMemory( &pi, sizeof(pi) ); + + /* build the absolute path to the child process */ + rgchAbsPathName = &absPathBuf[0]; + dwFileLength = strlen( rgchChildFile ); + + dwDirLength = GetCurrentDirectory( _MAX_PATH, rgchDirName ); + if( dwDirLength == 0 ) + { + dwError = GetLastError(); + if( ReleaseMutex( hMutex ) == 0 ) + { + Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); + } + if( CloseHandle( hMutex ) == 0 ) + { + Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); + } + Fail( "GetCurrentDirectory call failed with error code %d\n", + dwError ); + } + + dwSize = mkAbsoluteFilename( rgchDirName, + dwDirLength, + rgchChildFile, + dwFileLength, + rgchAbsPathName ); + if( dwSize == 0 ) + { + if( ReleaseMutex( hMutex ) == 0 ) + { + Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); + } + if( CloseHandle( hMutex ) == 0 ) + { + Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); + } + Fail( "Palsuite Code: mkAbsoluteFilename() call failed. Could ", + "not build absolute path name to file\n. Exiting.\n" ); + } + + /* launch the child process */ + if( !CreateProcess( NULL, /* module name to execute */ + rgchAbsPathName, /* command line */ + NULL, /* process handle not */ + /* inheritable */ + NULL, /* thread handle not */ + /*inheritable */ + FALSE, /* handle inheritance */ + CREATE_NEW_CONSOLE, /* dwCreationFlags */ + NULL, /* use parent's environment */ + NULL, /* use parent's starting */ + /* directory */ + &si, /* startup info struct */ + &pi ) /* process info struct */ + ) + { + dwError = GetLastError(); + if( ReleaseMutex( hMutex ) == 0 ) + { + Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); + } + if( CloseHandle( hMutex ) == 0 ) + { + Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); + } + Fail( "CreateProcess call failed with error code %d\n", + dwError ); + } + + /* open another handle to the child process */ + hChildProcess = OpenProcess( PROCESS_ALL_ACCESS, /* access */ + FALSE, /* inheritable */ + pi.dwProcessId /* process id */ + ); + if( hChildProcess == NULL ) + { + dwError = GetLastError(); + if( ReleaseMutex( hMutex ) == 0 ) + { + Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); + } + Trace( "ERROR:%lu:OpenProcess call failed\n", dwError ); + goto cleanup3; + } + + /* duplicate the child process handle */ + if( ! DuplicateHandle( GetCurrentProcess(), + hChildProcess, + GetCurrentProcess(), + &hDupChildProcess, + GENERIC_READ|GENERIC_WRITE, + FALSE, + DUPLICATE_SAME_ACCESS) ) + { + Trace( "ERROR:%lu:DuplicateHandle() call failed\n", GetLastError() ); + if( ReleaseMutex( hMutex ) == 0 ) + { + Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); + } + goto cleanup2; + } + + /* release the mutex so the child can proceed */ + if( ReleaseMutex( hMutex ) == 0 ) + { + Trace( "ERROR:%lu:ReleaseMutex() call failed\n", GetLastError() ); + goto cleanup1; + } + + /* wait for the child process to complete, using the new handle */ + dwRet = WaitForSingleObject( hDupChildProcess, 10000 ); + if( dwRet != WAIT_OBJECT_0 ) + { + Trace( "ERROR:WaitForSingleObject call returned %lu, " + "expected WAIT_OBJECT_0", + dwRet ); + goto cleanup1; + } + + /* remember that we waited until the child was finished */ + bChildDone = TRUE; + + /* check the exit code from the process -- this is a bit of an */ + /* extra verification that we opened the correct process handle */ + if( ! GetExitCodeProcess( hDupChildProcess, &dwExitCode ) ) + { + Trace( "ERROR:%lu:GetExitCodeProcess call failed\n", GetLastError() ); + goto cleanup1; + } + + /* verification */ + if( (dwExitCode & 0xFF) != (TEST_EXIT_CODE & 0xFF) ) + { + Trace( "GetExitCodeProcess returned an incorrect exit code %d, " + "expected value is %d\n", + (dwExitCode & 0xFF), + (TEST_EXIT_CODE & 0xFF)); + goto cleanup1; + } + + /* close the duplicate handle */ + if( ! CloseHandle( hDupChildProcess ) ) + { + Trace( "ERROR:%lu:CloseHandle call failed\n", GetLastError() ); + goto cleanup2; + } + + /* close the child process handle */ + if( ! CloseHandle ( hChildProcess ) ) + { + Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); + goto cleanup3; + } + + /* try to call duplicate handle on the closed child process handle */ + if( DuplicateHandle( GetCurrentProcess(), + hChildProcess, + GetCurrentProcess(), + &hDupChildProcess, + GENERIC_READ|GENERIC_WRITE, + FALSE, + DUPLICATE_SAME_ACCESS) ) + { + Trace( "ERROR:%lu:DuplicateHandle call succeeded on " + "a closed process handle, expected ERROR_INVALID_HANDLE\n" ); + if( ! CloseHandle( hDupChildProcess ) ) + { + Trace( "ERROR:%lu:CloseHandle call failed\n", GetLastError() ); + } + goto cleanup3; + } + + /* verify that the last error was ERROR_INVALID_HANDLE */ + dwRet = GetLastError(); + if( dwRet != ERROR_INVALID_HANDLE ) + { + Trace( "ERROR:DuplicateHandle returned %lu, " + "expected ERROR_INVALID_HANDLE\n", + dwRet ); + goto cleanup3; + } + + + /* success if we get here */ + ret = PASS; + + /* skip the cleanup stuff that's already done */ + goto cleanup3; + + +cleanup1: + /* close our duplicate handle */ + if( ! CloseHandle( hDupChildProcess ) ) + { + Trace( "ERROR:%lu:CloseHandle call failed\n", GetLastError() ); + ret = FAIL; + } + +cleanup2: + /* wait on the child process to complete if necessary */ + if( ! bChildDone ) + { + dwRet = WaitForSingleObject( hChildProcess, 10000 ); + if( dwRet != WAIT_OBJECT_0 ) + { + Trace( "ERROR:WaitForSingleObject call returned %lu, " + "expected WAIT_OBJECT_0", + dwRet ); + ret = FAIL; + } + } + + /* close our child process handle */ + if( CloseHandle ( hChildProcess ) == 0 ) + { + Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); + ret = FAIL; + } + +cleanup3: + /* close all our other handles */ + if( CloseHandle ( pi.hProcess ) == 0 ) + { + Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); + ret = FAIL; + } + if( CloseHandle ( pi.hThread ) == 0 ) + { + Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); + ret = FAIL; + } + if( CloseHandle( hMutex ) == 0 ) + { + Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); + ret = FAIL; + } + + if( ret == FAIL ) + { + Fail( "test failed\n" ); + } + + + + /* terminate the PAL */ + PAL_Terminate(); + + /* return success */ + return PASS; +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test12/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test12/CMakeLists.txt index 961a9c64e6..6a50a13265 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test12/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test12/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test12.c + test12.cpp ) add_executable(paltest_duplicatehandle_test12 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.c deleted file mode 100644 index 519194bc3a..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.c +++ /dev/null @@ -1,129 +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: test12.c (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function. -** This test will create handle to file (to write) and close it, -** then call duplicate handle to read what was written. -** -** -**===================================================================*/ -#include - -int __cdecl main(int argc, char **argv) -{ - HANDLE hFile; - HANDLE hDupFile; - char buf[256]; - char teststr[] = "A uNiQuE tEsT sTrInG"; - char lpFileName[] = "testfile.txt"; - DWORD dwBytesWritten; - DWORD dwBytesRead; - BOOL bRetVal; - - /*Initalize the PAL*/ - if ((PAL_Initialize(argc,argv)) != 0) - { - return (FAIL); - } - - /*Create a file handle with CreateFile*/ - hFile = CreateFile(lpFileName, - GENERIC_WRITE|GENERIC_READ, - FILE_SHARE_WRITE|FILE_SHARE_READ, - NULL, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - Fail("ERROR: %u :unable to create file \"%s\".\n", - GetLastError(), - lpFileName); - } - - /*Write test string to the file.*/ - bRetVal = WriteFile(hFile, // handle to file - teststr, // data buffer - strlen(teststr), // number of bytes to write - &dwBytesWritten, // number of bytes written - NULL); // overlapped buffer - - if (bRetVal == FALSE) - { - Trace("ERROR: %u : unable to write to file handle " - "hFile=0x%lx\n", - GetLastError(), - hFile); - CloseHandle(hFile); - Fail(""); - } - - /*Create a duplicate handle with DuplicateHandle.*/ - if (!(DuplicateHandle( - GetCurrentProcess(), - hFile, - GetCurrentProcess(), - &hDupFile, - GENERIC_READ|GENERIC_WRITE, - FALSE, - DUPLICATE_SAME_ACCESS))) - { - Trace("ERROR: %u : Fail to create the duplicate handle" - " to hFile=0x%lx\n", - GetLastError(), - hFile); - CloseHandle(hFile); - Fail(""); - } - - if( !CloseHandle(hFile) ) - { - Fail("Duplicate Handle:Unable to close original file: Error[%u]\n", GetLastError()); - } - - memset(buf, 0, 256); - - /*Read from the Duplicated handle.*/ - bRetVal = ReadFile(hDupFile, - buf, - 256, - &dwBytesRead, - NULL); - if (bRetVal == FALSE) - { - Trace("ERROR: %u :unable to read from file handle " - "hFile=0x%lx\n", - GetLastError(), - hDupFile); - CloseHandle(hDupFile); - Fail(""); - } - - /*Compare what was written to what was read.*/ - if (memcmp(teststr, buf, dwBytesRead) != 0) - { - Trace("ERROR: expected %s, got %s\n", teststr, buf); - CloseHandle(hDupFile); - Fail(""); - } - - /*Close the handles*/ - CloseHandle(hDupFile); - - bRetVal = DeleteFileA(lpFileName); - if (bRetVal != TRUE) - { - Trace("Error:%u: DuplicateHandle, DeleteFileA: Couldn't delete DeleteFileA's" - " %s\n", GetLastError(), lpFileName); - Fail(""); - } - - - PAL_Terminate(); - return (PASS); -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.cpp new file mode 100644 index 0000000000..519194bc3a --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.cpp @@ -0,0 +1,129 @@ +// 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: test12.c (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function. +** This test will create handle to file (to write) and close it, +** then call duplicate handle to read what was written. +** +** +**===================================================================*/ +#include + +int __cdecl main(int argc, char **argv) +{ + HANDLE hFile; + HANDLE hDupFile; + char buf[256]; + char teststr[] = "A uNiQuE tEsT sTrInG"; + char lpFileName[] = "testfile.txt"; + DWORD dwBytesWritten; + DWORD dwBytesRead; + BOOL bRetVal; + + /*Initalize the PAL*/ + if ((PAL_Initialize(argc,argv)) != 0) + { + return (FAIL); + } + + /*Create a file handle with CreateFile*/ + hFile = CreateFile(lpFileName, + GENERIC_WRITE|GENERIC_READ, + FILE_SHARE_WRITE|FILE_SHARE_READ, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + Fail("ERROR: %u :unable to create file \"%s\".\n", + GetLastError(), + lpFileName); + } + + /*Write test string to the file.*/ + bRetVal = WriteFile(hFile, // handle to file + teststr, // data buffer + strlen(teststr), // number of bytes to write + &dwBytesWritten, // number of bytes written + NULL); // overlapped buffer + + if (bRetVal == FALSE) + { + Trace("ERROR: %u : unable to write to file handle " + "hFile=0x%lx\n", + GetLastError(), + hFile); + CloseHandle(hFile); + Fail(""); + } + + /*Create a duplicate handle with DuplicateHandle.*/ + if (!(DuplicateHandle( + GetCurrentProcess(), + hFile, + GetCurrentProcess(), + &hDupFile, + GENERIC_READ|GENERIC_WRITE, + FALSE, + DUPLICATE_SAME_ACCESS))) + { + Trace("ERROR: %u : Fail to create the duplicate handle" + " to hFile=0x%lx\n", + GetLastError(), + hFile); + CloseHandle(hFile); + Fail(""); + } + + if( !CloseHandle(hFile) ) + { + Fail("Duplicate Handle:Unable to close original file: Error[%u]\n", GetLastError()); + } + + memset(buf, 0, 256); + + /*Read from the Duplicated handle.*/ + bRetVal = ReadFile(hDupFile, + buf, + 256, + &dwBytesRead, + NULL); + if (bRetVal == FALSE) + { + Trace("ERROR: %u :unable to read from file handle " + "hFile=0x%lx\n", + GetLastError(), + hDupFile); + CloseHandle(hDupFile); + Fail(""); + } + + /*Compare what was written to what was read.*/ + if (memcmp(teststr, buf, dwBytesRead) != 0) + { + Trace("ERROR: expected %s, got %s\n", teststr, buf); + CloseHandle(hDupFile); + Fail(""); + } + + /*Close the handles*/ + CloseHandle(hDupFile); + + bRetVal = DeleteFileA(lpFileName); + if (bRetVal != TRUE) + { + Trace("Error:%u: DuplicateHandle, DeleteFileA: Couldn't delete DeleteFileA's" + " %s\n", GetLastError(), lpFileName); + Fail(""); + } + + + PAL_Terminate(); + return (PASS); +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test2/CMakeLists.txt index 06529a6204..9faa58a271 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test2/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test2/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test2.c + test2.cpp ) add_executable(paltest_duplicatehandle_test2 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.c deleted file mode 100644 index d1411e62d9..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.c +++ /dev/null @@ -1,96 +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: test2.c (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function. -** This will test duplication of an CreateEvent handle. Test an -** event in a signaled state to wait, and then set the duplicate -** to nonsignaled state and perform the wait again. The wait on -** the event should fail. Test the duplication of closed and NULL -** events, these should fail. -** -** -**===================================================================*/ -#include - -int __cdecl main(int argc, char **argv) -{ - HANDLE hEvent; - HANDLE hDupEvent; - - /*Initalize the PAL.*/ - if ((PAL_Initialize(argc,argv)) != 0) - { - return (FAIL); - } - - /*Create an Event, and set it in the signaled state.*/ - hEvent = CreateEvent(0, TRUE, TRUE, 0); - if (hEvent == NULL) - { - Fail("ERROR: %u :unable to create event\n", - GetLastError()); - } - - /*Create a duplicate Event handle.*/ - if (!(DuplicateHandle(GetCurrentProcess(), - hEvent,GetCurrentProcess(), - &hDupEvent, - GENERIC_READ|GENERIC_WRITE, - FALSE, DUPLICATE_SAME_ACCESS))) - { - Trace("ERROR: %u :Fail to create the duplicate handle" - " to hEvent=0x%lx\n", - GetLastError(), - hEvent); - CloseHandle(hEvent); - Fail(""); - } - - /*Perform wait on Event that is in signaled state.*/ - if ((WaitForSingleObject(hEvent, 1000)) != WAIT_OBJECT_0) - { - Trace("ERROR: %u :WaitForSignalObject on Event=0x%lx set to " - " signaled state failed", - GetLastError(), - hEvent); - CloseHandle(hEvent); - CloseHandle(hDupEvent); - Fail(""); - } - - /*Set the Duplicate Event handle to nonsignaled state.*/ - if ((ResetEvent(hDupEvent)) == 0) - { - Trace("ERROR: %u :unable to reset dup event\n", - GetLastError()); - CloseHandle(hEvent); - CloseHandle(hDupEvent); - Fail(""); - } - - /*Perform wait on Event that is in signaled state.*/ - if ((WaitForSingleObject(hEvent, 1000)) == WAIT_OBJECT_0) - { - Trace("ERROR: %u: WaitForSignalObject succeeded on Event=0x%lx " - " when Duplicate Event=0x%lx set to nonsignaled state" - " succeeded\n", - GetLastError(), - hEvent, - hDupEvent); - CloseHandle(hEvent); - CloseHandle(hDupEvent); - Fail(""); - } - - /*Close handles to events.*/ - CloseHandle(hEvent); - CloseHandle(hDupEvent); - - PAL_Terminate(); - return (PASS); -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.cpp new file mode 100644 index 0000000000..d1411e62d9 --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.cpp @@ -0,0 +1,96 @@ +// 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: test2.c (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function. +** This will test duplication of an CreateEvent handle. Test an +** event in a signaled state to wait, and then set the duplicate +** to nonsignaled state and perform the wait again. The wait on +** the event should fail. Test the duplication of closed and NULL +** events, these should fail. +** +** +**===================================================================*/ +#include + +int __cdecl main(int argc, char **argv) +{ + HANDLE hEvent; + HANDLE hDupEvent; + + /*Initalize the PAL.*/ + if ((PAL_Initialize(argc,argv)) != 0) + { + return (FAIL); + } + + /*Create an Event, and set it in the signaled state.*/ + hEvent = CreateEvent(0, TRUE, TRUE, 0); + if (hEvent == NULL) + { + Fail("ERROR: %u :unable to create event\n", + GetLastError()); + } + + /*Create a duplicate Event handle.*/ + if (!(DuplicateHandle(GetCurrentProcess(), + hEvent,GetCurrentProcess(), + &hDupEvent, + GENERIC_READ|GENERIC_WRITE, + FALSE, DUPLICATE_SAME_ACCESS))) + { + Trace("ERROR: %u :Fail to create the duplicate handle" + " to hEvent=0x%lx\n", + GetLastError(), + hEvent); + CloseHandle(hEvent); + Fail(""); + } + + /*Perform wait on Event that is in signaled state.*/ + if ((WaitForSingleObject(hEvent, 1000)) != WAIT_OBJECT_0) + { + Trace("ERROR: %u :WaitForSignalObject on Event=0x%lx set to " + " signaled state failed", + GetLastError(), + hEvent); + CloseHandle(hEvent); + CloseHandle(hDupEvent); + Fail(""); + } + + /*Set the Duplicate Event handle to nonsignaled state.*/ + if ((ResetEvent(hDupEvent)) == 0) + { + Trace("ERROR: %u :unable to reset dup event\n", + GetLastError()); + CloseHandle(hEvent); + CloseHandle(hDupEvent); + Fail(""); + } + + /*Perform wait on Event that is in signaled state.*/ + if ((WaitForSingleObject(hEvent, 1000)) == WAIT_OBJECT_0) + { + Trace("ERROR: %u: WaitForSignalObject succeeded on Event=0x%lx " + " when Duplicate Event=0x%lx set to nonsignaled state" + " succeeded\n", + GetLastError(), + hEvent, + hDupEvent); + CloseHandle(hEvent); + CloseHandle(hDupEvent); + Fail(""); + } + + /*Close handles to events.*/ + CloseHandle(hEvent); + CloseHandle(hDupEvent); + + PAL_Terminate(); + return (PASS); +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test3/CMakeLists.txt index 7f961c2213..b161b928d3 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test3/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test3/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test3.c + test3.cpp ) add_executable(paltest_duplicatehandle_test3 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.c deleted file mode 100644 index fc91b5ec22..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.c +++ /dev/null @@ -1,123 +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: test3.c (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function. -** This will test duplication of an OpenEvent handle. Test an -** event in a signaled state to wait, and then set the duplicate -** to nonsignaled state and perform the wait again. The wait on -** the event should fail. Test the duplication of closed and NULL -** events, these should fail. -** -** -**===================================================================*/ -#include - -int __cdecl main(int argc, char **argv) -{ - HANDLE hCreateEvent; - HANDLE hOpenEvent; - HANDLE hDupEvent; - WCHAR lpEventName[]={'E','v','e','n','t','\0'}; - - /*Initialize the PAL.*/ - if ((PAL_Initialize(argc,argv)) != 0) - { - return (FAIL); - } - - /*Create an Event, and set it in the signaled state.*/ - hCreateEvent = CreateEventW(0, - TRUE, - TRUE, - lpEventName); - if (hCreateEvent == NULL) - { - Fail("ERROR: %u :unable to create event %s\n", - GetLastError(), - lpEventName); - } - - /*Open another handle to hCreateHandle with OpenEvent*/ - hOpenEvent = OpenEventW(EVENT_ALL_ACCESS, - TRUE, - lpEventName); - if (hOpenEvent == NULL) - { - Trace("ERROR: %u :unable to create handle with OpenEvent to %s\n", - GetLastError(), - lpEventName); - CloseHandle(hCreateEvent); - Fail(""); - } - - /*Create a duplicate Event handle*/ - if (!(DuplicateHandle(GetCurrentProcess(), - hOpenEvent, - GetCurrentProcess(), - &hDupEvent, - GENERIC_READ|GENERIC_WRITE, - FALSE, - DUPLICATE_SAME_ACCESS))) - { - Trace("ERROR: %u :Fail to create the duplicate handle" - " to hCreateEvent=0x%lx\n", - GetLastError(), - hCreateEvent); - CloseHandle(hCreateEvent); - CloseHandle(hOpenEvent); - Fail(""); - } - - /*Perform wait on Event that is in signaled state*/ - if ((WaitForSingleObject(hOpenEvent, 1000)) != WAIT_OBJECT_0) - { - Trace("ERROR: %u :WaitForSignalObject on hOpenEvent=0x%lx set to " - " signaled state failed\n", - GetLastError(), - hOpenEvent); - CloseHandle(hCreateEvent); - CloseHandle(hOpenEvent); - CloseHandle(hDupEvent); - Fail(""); - } - - /*Set the Duplicate Event handle to nonsignaled state*/ - if ((ResetEvent(hDupEvent)) == 0) - { - Trace("ERROR: %u: unable to reset hDupEvent=0x%lx\n", - GetLastError(), - hDupEvent); - CloseHandle(hCreateEvent); - CloseHandle(hOpenEvent); - CloseHandle(hDupEvent); - Fail(""); - } - - /*Perform wait on Event that is in signaled state*/ - if ((WaitForSingleObject(hOpenEvent, 1000)) == WAIT_OBJECT_0) - { - Trace("ERROR: %u :WaitForSignalObject succeeded on hOpenEvent=0x%lx " - " when Duplicate hDupEvent=0x%lx set to nonsignaled state" - " succeeded\n", - GetLastError(), - hOpenEvent, - hDupEvent); - CloseHandle(hCreateEvent); - CloseHandle(hOpenEvent); - CloseHandle(hDupEvent); - Fail(""); - } - - /*Close handles the events*/ - CloseHandle(hCreateEvent); - CloseHandle(hOpenEvent); - CloseHandle(hDupEvent); - - PAL_Terminate(); - return (PASS); -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.cpp new file mode 100644 index 0000000000..fc91b5ec22 --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.cpp @@ -0,0 +1,123 @@ +// 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: test3.c (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function. +** This will test duplication of an OpenEvent handle. Test an +** event in a signaled state to wait, and then set the duplicate +** to nonsignaled state and perform the wait again. The wait on +** the event should fail. Test the duplication of closed and NULL +** events, these should fail. +** +** +**===================================================================*/ +#include + +int __cdecl main(int argc, char **argv) +{ + HANDLE hCreateEvent; + HANDLE hOpenEvent; + HANDLE hDupEvent; + WCHAR lpEventName[]={'E','v','e','n','t','\0'}; + + /*Initialize the PAL.*/ + if ((PAL_Initialize(argc,argv)) != 0) + { + return (FAIL); + } + + /*Create an Event, and set it in the signaled state.*/ + hCreateEvent = CreateEventW(0, + TRUE, + TRUE, + lpEventName); + if (hCreateEvent == NULL) + { + Fail("ERROR: %u :unable to create event %s\n", + GetLastError(), + lpEventName); + } + + /*Open another handle to hCreateHandle with OpenEvent*/ + hOpenEvent = OpenEventW(EVENT_ALL_ACCESS, + TRUE, + lpEventName); + if (hOpenEvent == NULL) + { + Trace("ERROR: %u :unable to create handle with OpenEvent to %s\n", + GetLastError(), + lpEventName); + CloseHandle(hCreateEvent); + Fail(""); + } + + /*Create a duplicate Event handle*/ + if (!(DuplicateHandle(GetCurrentProcess(), + hOpenEvent, + GetCurrentProcess(), + &hDupEvent, + GENERIC_READ|GENERIC_WRITE, + FALSE, + DUPLICATE_SAME_ACCESS))) + { + Trace("ERROR: %u :Fail to create the duplicate handle" + " to hCreateEvent=0x%lx\n", + GetLastError(), + hCreateEvent); + CloseHandle(hCreateEvent); + CloseHandle(hOpenEvent); + Fail(""); + } + + /*Perform wait on Event that is in signaled state*/ + if ((WaitForSingleObject(hOpenEvent, 1000)) != WAIT_OBJECT_0) + { + Trace("ERROR: %u :WaitForSignalObject on hOpenEvent=0x%lx set to " + " signaled state failed\n", + GetLastError(), + hOpenEvent); + CloseHandle(hCreateEvent); + CloseHandle(hOpenEvent); + CloseHandle(hDupEvent); + Fail(""); + } + + /*Set the Duplicate Event handle to nonsignaled state*/ + if ((ResetEvent(hDupEvent)) == 0) + { + Trace("ERROR: %u: unable to reset hDupEvent=0x%lx\n", + GetLastError(), + hDupEvent); + CloseHandle(hCreateEvent); + CloseHandle(hOpenEvent); + CloseHandle(hDupEvent); + Fail(""); + } + + /*Perform wait on Event that is in signaled state*/ + if ((WaitForSingleObject(hOpenEvent, 1000)) == WAIT_OBJECT_0) + { + Trace("ERROR: %u :WaitForSignalObject succeeded on hOpenEvent=0x%lx " + " when Duplicate hDupEvent=0x%lx set to nonsignaled state" + " succeeded\n", + GetLastError(), + hOpenEvent, + hDupEvent); + CloseHandle(hCreateEvent); + CloseHandle(hOpenEvent); + CloseHandle(hDupEvent); + Fail(""); + } + + /*Close handles the events*/ + CloseHandle(hCreateEvent); + CloseHandle(hOpenEvent); + CloseHandle(hDupEvent); + + PAL_Terminate(); + return (PASS); +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test4/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test4/CMakeLists.txt index c3040d09ec..901151f4eb 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test4/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test4/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test4.c + test4.cpp ) add_executable(paltest_duplicatehandle_test4 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.c deleted file mode 100644 index 14a72db461..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.c +++ /dev/null @@ -1,239 +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: test4.c (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function. -** This test duplication of a Mutex handle. The test will comprise -** of creating a Mutex and its duplicate and create a thread that -** will get ownership. Another thread will be create that will -** attempt to get ownership of the duplicate Mutex, this will -** fail, since the Mutex is owned by another thread. The Mutex -** will be released and then the thread will attempt to get -** ownership of the duplicate Mutex, this will succeed. -** -** -**===================================================================*/ -#include - -enum wait_results -{ - WR_WAITING, - WR_GOT_MUTEX, - WR_TIMED_OUT, - WR_RELEASED -}; - - -volatile int t1_result=WR_WAITING; -volatile int t2_result=WR_WAITING; - - -DWORD PALAPI ThreadTest1(LPVOID lpParam) -{ - DWORD dwWait; - - dwWait = WaitForSingleObject((HANDLE)lpParam, 0); - if (dwWait == WAIT_OBJECT_0) - { - /* tell the main thread we got the mutex */ - t1_result=WR_GOT_MUTEX; - - /* wait for main thread to tell us to release the mutex */ - while(WR_GOT_MUTEX == t1_result) - Sleep(1); - ReleaseMutex((HANDLE)lpParam); - - /* tell the main thread we released the mutex */ - t1_result = WR_RELEASED; - } - else - { - t1_result = WR_TIMED_OUT; - } - return 0; -} - -DWORD PALAPI ThreadTest2(LPVOID lpParam) -{ - DWORD dwWait; - - dwWait = WaitForSingleObject((HANDLE)lpParam, 0 ); - if (dwWait == WAIT_OBJECT_0) - { - ReleaseMutex((HANDLE)lpParam); - t2_result = WR_GOT_MUTEX; - } - else - { - t2_result = WR_TIMED_OUT; - } - - return 0; -} - - -int __cdecl main(int argc, char **argv) -{ - - HANDLE hDupMutex; - HANDLE hMutex; - HANDLE hThread; - HANDLE hThread2; - BOOL bDupHandle=FALSE; - DWORD dwThreadId = 0; - - if ((PAL_Initialize(argc,argv)) != 0) - { - return(FAIL); - } - - /*Create Mutex without ownership*/ - hMutex = CreateMutexW(NULL, // no security attributes - FALSE, // initially not owned - NULL); // name of mutex - if (hMutex == NULL) - { - Fail("ERROR:%u: Unable to create mutex\n", - GetLastError()); - } - - /*Create Duplicate of the Mutex above*/ - bDupHandle = DuplicateHandle(GetCurrentProcess(), - hMutex, - GetCurrentProcess(), - &hDupMutex, - GENERIC_READ|GENERIC_WRITE, - FALSE, - DUPLICATE_SAME_ACCESS); - if (!bDupHandle) - { - Trace("ERROR:%u: Created the duplicate handle to " - "closed event handle hMutex=0x%lx\n", - GetLastError(), - hMutex); - CloseHandle(hMutex); - Fail(""); - } - - /*Create a thread to test the Mutex*/ - hThread = CreateThread(NULL, - 0, - &ThreadTest1, - hMutex, - 0, - &dwThreadId); - if (hThread == NULL) - { - Trace("ERROR:%u: unable to create thread\n", - GetLastError()); - CloseHandle(hMutex); - CloseHandle(hDupMutex); - Fail(""); - } - - /* wait until thread has taken the mutex */ - while (WR_WAITING == t1_result) - Sleep(1); - - if(WR_TIMED_OUT == t1_result) - { - Trace("ERROR: %u: thread 1 couldn't acquire the mutex\n"); - CloseHandle(hMutex); - CloseHandle(hDupMutex); - CloseHandle(hThread); - Fail(""); - } - - /*Create a second thread to use the duplicate Mutex*/ - /*This should fail since the Mutex is owned hThread*/ - hThread2 = CreateThread(NULL, - 0, - &ThreadTest2, - hDupMutex, - 0, - &dwThreadId); - - if (hThread2 == NULL) - { - Trace("ERROR:%u: unable to create thread\n", - GetLastError()); - CloseHandle(hMutex); - CloseHandle(hDupMutex); - CloseHandle(hThread); - Fail(""); - } - - /* wait until thread has tried to take the mutex */ - while (WR_WAITING == t2_result) - Sleep(1); - - if (WR_TIMED_OUT != t2_result ) - { - Trace("ERROR:%u: Able to take mutex %#x while its duplicate %#x is " - "held\n", hDupMutex, hMutex); - CloseHandle(hMutex); - CloseHandle(hDupMutex); - CloseHandle(hThread); - CloseHandle(hThread2); - Fail(""); - } - - /* reset second thread status */ - t2_result = WR_WAITING; - - /* tell thread 1 to release the mutex */ - t1_result = WR_WAITING; - - /* wait for thread 1 to release the mutex */ - while (WR_WAITING == t1_result) - Sleep(1); - - CloseHandle(hThread2); - - /*Re-Create the second thread to reuse the duplicated Mutex*/ - /*This test should pass, the Mutex has since been released*/ - hThread2 = CreateThread(NULL, - 0, - &ThreadTest2, - hDupMutex, - 0, - &dwThreadId); - - if (hThread2 == NULL) - { - Trace("ERROR:%u: unable to create thread\n", - GetLastError()); - CloseHandle(hMutex); - CloseHandle(hDupMutex); - CloseHandle(hThread); - Fail(""); - } - - /* wait until thread has taken the mutex */ - while (WR_WAITING == t2_result) - Sleep(1); - - if (WR_GOT_MUTEX != t2_result ) - { - Trace("ERROR:%u: Unable to take mutex %#x after its duplicate %#x was " - "released\n", hDupMutex, hMutex); - CloseHandle(hMutex); - CloseHandle(hDupMutex); - CloseHandle(hThread); - CloseHandle(hThread2); - Fail(""); - } - - /*Cleanup.*/ - CloseHandle(hMutex); - CloseHandle(hDupMutex); - CloseHandle(hThread); - CloseHandle(hThread2); - - PAL_Terminate(); - return (PASS); -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.cpp new file mode 100644 index 0000000000..14a72db461 --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.cpp @@ -0,0 +1,239 @@ +// 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: test4.c (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function. +** This test duplication of a Mutex handle. The test will comprise +** of creating a Mutex and its duplicate and create a thread that +** will get ownership. Another thread will be create that will +** attempt to get ownership of the duplicate Mutex, this will +** fail, since the Mutex is owned by another thread. The Mutex +** will be released and then the thread will attempt to get +** ownership of the duplicate Mutex, this will succeed. +** +** +**===================================================================*/ +#include + +enum wait_results +{ + WR_WAITING, + WR_GOT_MUTEX, + WR_TIMED_OUT, + WR_RELEASED +}; + + +volatile int t1_result=WR_WAITING; +volatile int t2_result=WR_WAITING; + + +DWORD PALAPI ThreadTest1(LPVOID lpParam) +{ + DWORD dwWait; + + dwWait = WaitForSingleObject((HANDLE)lpParam, 0); + if (dwWait == WAIT_OBJECT_0) + { + /* tell the main thread we got the mutex */ + t1_result=WR_GOT_MUTEX; + + /* wait for main thread to tell us to release the mutex */ + while(WR_GOT_MUTEX == t1_result) + Sleep(1); + ReleaseMutex((HANDLE)lpParam); + + /* tell the main thread we released the mutex */ + t1_result = WR_RELEASED; + } + else + { + t1_result = WR_TIMED_OUT; + } + return 0; +} + +DWORD PALAPI ThreadTest2(LPVOID lpParam) +{ + DWORD dwWait; + + dwWait = WaitForSingleObject((HANDLE)lpParam, 0 ); + if (dwWait == WAIT_OBJECT_0) + { + ReleaseMutex((HANDLE)lpParam); + t2_result = WR_GOT_MUTEX; + } + else + { + t2_result = WR_TIMED_OUT; + } + + return 0; +} + + +int __cdecl main(int argc, char **argv) +{ + + HANDLE hDupMutex; + HANDLE hMutex; + HANDLE hThread; + HANDLE hThread2; + BOOL bDupHandle=FALSE; + DWORD dwThreadId = 0; + + if ((PAL_Initialize(argc,argv)) != 0) + { + return(FAIL); + } + + /*Create Mutex without ownership*/ + hMutex = CreateMutexW(NULL, // no security attributes + FALSE, // initially not owned + NULL); // name of mutex + if (hMutex == NULL) + { + Fail("ERROR:%u: Unable to create mutex\n", + GetLastError()); + } + + /*Create Duplicate of the Mutex above*/ + bDupHandle = DuplicateHandle(GetCurrentProcess(), + hMutex, + GetCurrentProcess(), + &hDupMutex, + GENERIC_READ|GENERIC_WRITE, + FALSE, + DUPLICATE_SAME_ACCESS); + if (!bDupHandle) + { + Trace("ERROR:%u: Created the duplicate handle to " + "closed event handle hMutex=0x%lx\n", + GetLastError(), + hMutex); + CloseHandle(hMutex); + Fail(""); + } + + /*Create a thread to test the Mutex*/ + hThread = CreateThread(NULL, + 0, + &ThreadTest1, + hMutex, + 0, + &dwThreadId); + if (hThread == NULL) + { + Trace("ERROR:%u: unable to create thread\n", + GetLastError()); + CloseHandle(hMutex); + CloseHandle(hDupMutex); + Fail(""); + } + + /* wait until thread has taken the mutex */ + while (WR_WAITING == t1_result) + Sleep(1); + + if(WR_TIMED_OUT == t1_result) + { + Trace("ERROR: %u: thread 1 couldn't acquire the mutex\n"); + CloseHandle(hMutex); + CloseHandle(hDupMutex); + CloseHandle(hThread); + Fail(""); + } + + /*Create a second thread to use the duplicate Mutex*/ + /*This should fail since the Mutex is owned hThread*/ + hThread2 = CreateThread(NULL, + 0, + &ThreadTest2, + hDupMutex, + 0, + &dwThreadId); + + if (hThread2 == NULL) + { + Trace("ERROR:%u: unable to create thread\n", + GetLastError()); + CloseHandle(hMutex); + CloseHandle(hDupMutex); + CloseHandle(hThread); + Fail(""); + } + + /* wait until thread has tried to take the mutex */ + while (WR_WAITING == t2_result) + Sleep(1); + + if (WR_TIMED_OUT != t2_result ) + { + Trace("ERROR:%u: Able to take mutex %#x while its duplicate %#x is " + "held\n", hDupMutex, hMutex); + CloseHandle(hMutex); + CloseHandle(hDupMutex); + CloseHandle(hThread); + CloseHandle(hThread2); + Fail(""); + } + + /* reset second thread status */ + t2_result = WR_WAITING; + + /* tell thread 1 to release the mutex */ + t1_result = WR_WAITING; + + /* wait for thread 1 to release the mutex */ + while (WR_WAITING == t1_result) + Sleep(1); + + CloseHandle(hThread2); + + /*Re-Create the second thread to reuse the duplicated Mutex*/ + /*This test should pass, the Mutex has since been released*/ + hThread2 = CreateThread(NULL, + 0, + &ThreadTest2, + hDupMutex, + 0, + &dwThreadId); + + if (hThread2 == NULL) + { + Trace("ERROR:%u: unable to create thread\n", + GetLastError()); + CloseHandle(hMutex); + CloseHandle(hDupMutex); + CloseHandle(hThread); + Fail(""); + } + + /* wait until thread has taken the mutex */ + while (WR_WAITING == t2_result) + Sleep(1); + + if (WR_GOT_MUTEX != t2_result ) + { + Trace("ERROR:%u: Unable to take mutex %#x after its duplicate %#x was " + "released\n", hDupMutex, hMutex); + CloseHandle(hMutex); + CloseHandle(hDupMutex); + CloseHandle(hThread); + CloseHandle(hThread2); + Fail(""); + } + + /*Cleanup.*/ + CloseHandle(hMutex); + CloseHandle(hDupMutex); + CloseHandle(hThread); + CloseHandle(hThread2); + + PAL_Terminate(); + return (PASS); +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test5/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test5/CMakeLists.txt index bc468a4a75..94cd07f96f 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test5/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test5/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test5.c + test5.cpp ) add_executable(paltest_duplicatehandle_test5 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.c deleted file mode 100644 index a588928f00..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.c +++ /dev/null @@ -1,145 +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: test5.c (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function, -** with CreatePipe. This test will create a pipe and write to it, -** the duplicate the read handle and read what was written. -** -** Depends: WriteFile -** ReadFile -** memcmp -** CloseHandle -** -** -**===================================================================*/ - -#include - -const char* cTestString = "one fish, two fish, red fish, blue fish."; - -int __cdecl main(int argc, char **argv) -{ - HANDLE hReadPipe = NULL; - HANDLE hWritePipe = NULL; - HANDLE hDupPipe = NULL; - BOOL bRetVal = FALSE; - DWORD dwBytesWritten; - DWORD dwBytesRead; - char buffer[256]; - - SECURITY_ATTRIBUTES lpPipeAttributes; - - /*Initialize the PAL*/ - if ((PAL_Initialize(argc, argv)) != 0) - { - return (FAIL); - } - - /*Setup SECURITY_ATTRIBUTES structure for CreatePipe*/ - lpPipeAttributes.nLength = sizeof(lpPipeAttributes); - lpPipeAttributes.lpSecurityDescriptor = NULL; - lpPipeAttributes.bInheritHandle = TRUE; - - /*Create a Pipe*/ - bRetVal = CreatePipe(&hReadPipe, /* read handle*/ - &hWritePipe, /* write handle */ - &lpPipeAttributes,/* security attributes*/ - 0); /* pipe size*/ - if (bRetVal == FALSE) - { - Fail("ERROR:%u:Unable to create pipe\n", GetLastError()); - } - - /*Write to the write pipe handle*/ - bRetVal = WriteFile(hWritePipe, /* handle to write pipe*/ - cTestString, /* buffer to write*/ - strlen(cTestString),/* number of bytes to write*/ - &dwBytesWritten, /* number of bytes written*/ - NULL); /* overlapped buffer*/ - if (bRetVal == FALSE) - { - Trace("ERROR:%u:unable to write to write pipe handle " - "hWritePipe=0x%lx\n", GetLastError(), hWritePipe); - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - Fail(""); - } - - /*Duplicate the pipe handle*/ - if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/ - hReadPipe, /* handle to duplicate*/ - GetCurrentProcess(), /* target process handle*/ - &hDupPipe, /* duplicate handle*/ - GENERIC_READ|GENERIC_WRITE,/* requested access*/ - FALSE, /* handle inheritance*/ - DUPLICATE_SAME_ACCESS))) /* optional actions*/ - { - Trace("ERROR:%u:Fail to create the duplicate handle" - " to hReadPipe=0x%lx", - GetLastError(), - hReadPipe); - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - Fail(""); - } - - /*Read from the duplicated handle, 256 bytes, more bytes - than actually written. This will allow us to use the - value that ReadFile returns for comparision.*/ - bRetVal = ReadFile(hDupPipe, /* handle to read pipe*/ - buffer, /* buffer to write to*/ - 256, /* number of bytes to read*/ - &dwBytesRead, /* number of bytes read*/ - NULL); /* overlapped buffer*/ - if (bRetVal == FALSE) - { - Trace("ERROR:%u:unable read from the duplicated pipe " - "hDupPipe=0x%lx\n", - GetLastError(), - hDupPipe); - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - CloseHandle(hDupPipe); - Fail(""); - } - - /*Compare what was read with what was written.*/ - if ((memcmp(cTestString, buffer, dwBytesRead)) != 0) - { - Trace("ERROR:%u: read \"%s\" expected \"%s\" \n", - GetLastError(), - buffer, - cTestString); - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - CloseHandle(hDupPipe); - Fail(""); - } - - /*Compare values returned from WriteFile and ReadFile.*/ - if (dwBytesWritten != dwBytesRead) - { - Trace("ERROR:%u: WriteFile wrote \"%s\", but ReadFile read \"%s\"," - " these should be the same\n", - GetLastError(), - buffer, - cTestString); - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - CloseHandle(hDupPipe); - Fail(""); - } - - /*Cleanup.*/ - CloseHandle(hWritePipe); - CloseHandle(hReadPipe); - CloseHandle(hDupPipe); - - PAL_Terminate(); - return (PASS); -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.cpp new file mode 100644 index 0000000000..a588928f00 --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.cpp @@ -0,0 +1,145 @@ +// 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: test5.c (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function, +** with CreatePipe. This test will create a pipe and write to it, +** the duplicate the read handle and read what was written. +** +** Depends: WriteFile +** ReadFile +** memcmp +** CloseHandle +** +** +**===================================================================*/ + +#include + +const char* cTestString = "one fish, two fish, red fish, blue fish."; + +int __cdecl main(int argc, char **argv) +{ + HANDLE hReadPipe = NULL; + HANDLE hWritePipe = NULL; + HANDLE hDupPipe = NULL; + BOOL bRetVal = FALSE; + DWORD dwBytesWritten; + DWORD dwBytesRead; + char buffer[256]; + + SECURITY_ATTRIBUTES lpPipeAttributes; + + /*Initialize the PAL*/ + if ((PAL_Initialize(argc, argv)) != 0) + { + return (FAIL); + } + + /*Setup SECURITY_ATTRIBUTES structure for CreatePipe*/ + lpPipeAttributes.nLength = sizeof(lpPipeAttributes); + lpPipeAttributes.lpSecurityDescriptor = NULL; + lpPipeAttributes.bInheritHandle = TRUE; + + /*Create a Pipe*/ + bRetVal = CreatePipe(&hReadPipe, /* read handle*/ + &hWritePipe, /* write handle */ + &lpPipeAttributes,/* security attributes*/ + 0); /* pipe size*/ + if (bRetVal == FALSE) + { + Fail("ERROR:%u:Unable to create pipe\n", GetLastError()); + } + + /*Write to the write pipe handle*/ + bRetVal = WriteFile(hWritePipe, /* handle to write pipe*/ + cTestString, /* buffer to write*/ + strlen(cTestString),/* number of bytes to write*/ + &dwBytesWritten, /* number of bytes written*/ + NULL); /* overlapped buffer*/ + if (bRetVal == FALSE) + { + Trace("ERROR:%u:unable to write to write pipe handle " + "hWritePipe=0x%lx\n", GetLastError(), hWritePipe); + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + Fail(""); + } + + /*Duplicate the pipe handle*/ + if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/ + hReadPipe, /* handle to duplicate*/ + GetCurrentProcess(), /* target process handle*/ + &hDupPipe, /* duplicate handle*/ + GENERIC_READ|GENERIC_WRITE,/* requested access*/ + FALSE, /* handle inheritance*/ + DUPLICATE_SAME_ACCESS))) /* optional actions*/ + { + Trace("ERROR:%u:Fail to create the duplicate handle" + " to hReadPipe=0x%lx", + GetLastError(), + hReadPipe); + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + Fail(""); + } + + /*Read from the duplicated handle, 256 bytes, more bytes + than actually written. This will allow us to use the + value that ReadFile returns for comparision.*/ + bRetVal = ReadFile(hDupPipe, /* handle to read pipe*/ + buffer, /* buffer to write to*/ + 256, /* number of bytes to read*/ + &dwBytesRead, /* number of bytes read*/ + NULL); /* overlapped buffer*/ + if (bRetVal == FALSE) + { + Trace("ERROR:%u:unable read from the duplicated pipe " + "hDupPipe=0x%lx\n", + GetLastError(), + hDupPipe); + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + CloseHandle(hDupPipe); + Fail(""); + } + + /*Compare what was read with what was written.*/ + if ((memcmp(cTestString, buffer, dwBytesRead)) != 0) + { + Trace("ERROR:%u: read \"%s\" expected \"%s\" \n", + GetLastError(), + buffer, + cTestString); + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + CloseHandle(hDupPipe); + Fail(""); + } + + /*Compare values returned from WriteFile and ReadFile.*/ + if (dwBytesWritten != dwBytesRead) + { + Trace("ERROR:%u: WriteFile wrote \"%s\", but ReadFile read \"%s\"," + " these should be the same\n", + GetLastError(), + buffer, + cTestString); + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + CloseHandle(hDupPipe); + Fail(""); + } + + /*Cleanup.*/ + CloseHandle(hWritePipe); + CloseHandle(hReadPipe); + CloseHandle(hDupPipe); + + PAL_Terminate(); + return (PASS); +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test6/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test6/CMakeLists.txt index 20f7822b1e..a0dcae843c 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test6/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test6/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test6.c + test6.cpp ) add_executable(paltest_duplicatehandle_test6 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.c deleted file mode 100644 index 026f315a44..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.c +++ /dev/null @@ -1,146 +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: test6.c (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function, -** with CreatePipe. This test will create a pipe, then duplicate -** the write handle, write to the handle, and use the read to -** verify. -** -** Depends: WriteFile -** ReadFile -** memcmp -** CloseHandle -** -** -**===================================================================*/ - -#include - -const char* cTestString = "one fish, two fish, red fish, blue fish."; - -int __cdecl main(int argc, char **argv) -{ - HANDLE hReadPipe = NULL; - HANDLE hWritePipe = NULL; - HANDLE hDupPipe = NULL; - BOOL bRetVal = FALSE; - DWORD dwBytesWritten; - DWORD dwBytesRead; - char buffer[256]; - - SECURITY_ATTRIBUTES lpPipeAttributes; - - /*Initialize the PAL*/ - if ((PAL_Initialize(argc, argv)) != 0) - { - return (FAIL); - } - - /*Setup SECURITY_ATTRIBUTES structure for CreatePipe*/ - lpPipeAttributes.nLength = sizeof(lpPipeAttributes); - lpPipeAttributes.lpSecurityDescriptor = NULL; - lpPipeAttributes.bInheritHandle = TRUE; - - /*Create a Pipe*/ - bRetVal = CreatePipe(&hReadPipe, /* read handle*/ - &hWritePipe, /* write handle */ - &lpPipeAttributes,/* security attributes*/ - 0); /* pipe size*/ - if (bRetVal == FALSE) - { - Fail("ERROR: %ld :Unable to create pipe\n", GetLastError()); - } - - /*Duplicate the pipe handle*/ - if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/ - hWritePipe, /* handle to duplicate*/ - GetCurrentProcess(), /* target process handle*/ - &hDupPipe, /* duplicate handle*/ - GENERIC_READ|GENERIC_WRITE,/* requested access*/ - FALSE, /* handle inheritance*/ - DUPLICATE_SAME_ACCESS))) /* optional actions*/ - { - Trace("ERROR: %ld :Fail to create the duplicate handle" - " to hWritePipe=0x%lx", - GetLastError(), - hWritePipe); - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - Fail(""); - } - - /*Write to the duplicate write pipe handle*/ - bRetVal = WriteFile(hDupPipe, /* handle to write pipe*/ - cTestString, /* buffer to write*/ - strlen(cTestString),/* number of bytes to write*/ - &dwBytesWritten, /* number of bytes written*/ - NULL); /* overlapped buffer*/ - if (bRetVal == FALSE) - { - Trace("ERROR: %ld :unable to write to duplicate write pipe handle " - "hDupPipe=0x%lx\n", - GetLastError(), - hDupPipe); - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - CloseHandle(hDupPipe); - Fail(""); - } - - /*Read from the read handle, 256 bytes, more bytes - then actually written. This will give allow us to use - the value that ReadFile returns for comparision.*/ - bRetVal = ReadFile(hReadPipe, /* handle to read pipe*/ - buffer, /* buffer to write to*/ - 256, /* number of bytes to read*/ - &dwBytesRead, /* number of bytes read*/ - NULL); /* overlapped buffer*/ - if (bRetVal == FALSE) - { - Trace("ERROR: %ld : unable read hReadPipe=0x%lx\n", - GetLastError(), hReadPipe); - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - CloseHandle(hDupPipe); - Fail(""); - } - - /*Compare what was read with what was written.*/ - if ((memcmp(cTestString, buffer, dwBytesRead)) != 0) - { - Trace("ERROR: read \"%s\" expected \"%s\" \n", - buffer, - cTestString); - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - CloseHandle(hDupPipe); - Fail(""); - } - - /*Compare values returned from WriteFile and ReadFile.*/ - if (dwBytesWritten != dwBytesRead) - { - Trace("ERROR: WriteFile wrote \"%s\", but ReadFile read \"%s\"," - " these should be the same\n", - buffer, - cTestString); - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - CloseHandle(hDupPipe); - Fail(""); - } - - /*Cleanup.*/ - CloseHandle(hReadPipe); - CloseHandle(hWritePipe); - CloseHandle(hDupPipe); - - - PAL_Terminate(); - return (PASS); -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.cpp new file mode 100644 index 0000000000..026f315a44 --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.cpp @@ -0,0 +1,146 @@ +// 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: test6.c (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function, +** with CreatePipe. This test will create a pipe, then duplicate +** the write handle, write to the handle, and use the read to +** verify. +** +** Depends: WriteFile +** ReadFile +** memcmp +** CloseHandle +** +** +**===================================================================*/ + +#include + +const char* cTestString = "one fish, two fish, red fish, blue fish."; + +int __cdecl main(int argc, char **argv) +{ + HANDLE hReadPipe = NULL; + HANDLE hWritePipe = NULL; + HANDLE hDupPipe = NULL; + BOOL bRetVal = FALSE; + DWORD dwBytesWritten; + DWORD dwBytesRead; + char buffer[256]; + + SECURITY_ATTRIBUTES lpPipeAttributes; + + /*Initialize the PAL*/ + if ((PAL_Initialize(argc, argv)) != 0) + { + return (FAIL); + } + + /*Setup SECURITY_ATTRIBUTES structure for CreatePipe*/ + lpPipeAttributes.nLength = sizeof(lpPipeAttributes); + lpPipeAttributes.lpSecurityDescriptor = NULL; + lpPipeAttributes.bInheritHandle = TRUE; + + /*Create a Pipe*/ + bRetVal = CreatePipe(&hReadPipe, /* read handle*/ + &hWritePipe, /* write handle */ + &lpPipeAttributes,/* security attributes*/ + 0); /* pipe size*/ + if (bRetVal == FALSE) + { + Fail("ERROR: %ld :Unable to create pipe\n", GetLastError()); + } + + /*Duplicate the pipe handle*/ + if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/ + hWritePipe, /* handle to duplicate*/ + GetCurrentProcess(), /* target process handle*/ + &hDupPipe, /* duplicate handle*/ + GENERIC_READ|GENERIC_WRITE,/* requested access*/ + FALSE, /* handle inheritance*/ + DUPLICATE_SAME_ACCESS))) /* optional actions*/ + { + Trace("ERROR: %ld :Fail to create the duplicate handle" + " to hWritePipe=0x%lx", + GetLastError(), + hWritePipe); + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + Fail(""); + } + + /*Write to the duplicate write pipe handle*/ + bRetVal = WriteFile(hDupPipe, /* handle to write pipe*/ + cTestString, /* buffer to write*/ + strlen(cTestString),/* number of bytes to write*/ + &dwBytesWritten, /* number of bytes written*/ + NULL); /* overlapped buffer*/ + if (bRetVal == FALSE) + { + Trace("ERROR: %ld :unable to write to duplicate write pipe handle " + "hDupPipe=0x%lx\n", + GetLastError(), + hDupPipe); + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + CloseHandle(hDupPipe); + Fail(""); + } + + /*Read from the read handle, 256 bytes, more bytes + then actually written. This will give allow us to use + the value that ReadFile returns for comparision.*/ + bRetVal = ReadFile(hReadPipe, /* handle to read pipe*/ + buffer, /* buffer to write to*/ + 256, /* number of bytes to read*/ + &dwBytesRead, /* number of bytes read*/ + NULL); /* overlapped buffer*/ + if (bRetVal == FALSE) + { + Trace("ERROR: %ld : unable read hReadPipe=0x%lx\n", + GetLastError(), hReadPipe); + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + CloseHandle(hDupPipe); + Fail(""); + } + + /*Compare what was read with what was written.*/ + if ((memcmp(cTestString, buffer, dwBytesRead)) != 0) + { + Trace("ERROR: read \"%s\" expected \"%s\" \n", + buffer, + cTestString); + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + CloseHandle(hDupPipe); + Fail(""); + } + + /*Compare values returned from WriteFile and ReadFile.*/ + if (dwBytesWritten != dwBytesRead) + { + Trace("ERROR: WriteFile wrote \"%s\", but ReadFile read \"%s\"," + " these should be the same\n", + buffer, + cTestString); + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + CloseHandle(hDupPipe); + Fail(""); + } + + /*Cleanup.*/ + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + CloseHandle(hDupPipe); + + + PAL_Terminate(); + return (PASS); +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test7/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test7/CMakeLists.txt index df3fdf9ae0..a222331fe7 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test7/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test7/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test7.c + test7.cpp ) add_executable(paltest_duplicatehandle_test7 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.c deleted file mode 100644 index 0477291922..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.c +++ /dev/null @@ -1,149 +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: test7.c (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function, -** with a handle from CreateThread. The test will create a thread -** handle and its duplicate. Then get the priorities of the threads, -** set the priority of one and the change should be seen in the -** other. -** -** -**===================================================================*/ - -#include - -DWORD PALAPI CreateTestThread(LPVOID lpParam); - -int __cdecl main(int argc, char* argv[]) -{ - HANDLE hThread; - HANDLE hDupThread; - DWORD dwThreadId = 0; - LPTHREAD_START_ROUTINE lpStartAddress = &CreateTestThread; - - int threadPriority; - int duplicatePriority; - int finalPriority; - - /* Initialize the PAL.*/ - if ((PAL_Initialize(argc, argv)) != 0) - { - return (FAIL); - } - - /* Create a thread.*/ - hThread = CreateThread(NULL, /* SD*/ - (DWORD)0, /* initial stack size*/ - lpStartAddress, /* thread function*/ - NULL, /* thread argument*/ - (DWORD)0, /* creation option*/ - &dwThreadId); /* thread identifier*/ - if (hThread == NULL) - { - Fail("ERROR:%u: Unable to create thread.\n", - GetLastError()); - } - - /* Duplicate the thread handle.*/ - if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/ - hThread, /* handle to duplicate*/ - GetCurrentProcess(), /* target process handle*/ - &hDupThread, /* duplicate handle*/ - (DWORD)0, /* requested access*/ - FALSE, /* handle inheritance*/ - DUPLICATE_SAME_ACCESS))) /* optional actions*/ - { - Trace("ERROR: %ld :Fail to create the duplicate handle" - " to hThread=0x%lx", - GetLastError(), - hThread); - CloseHandle(hThread); - Fail(""); - } - - /* Get the priority of the thread.*/ - threadPriority = GetThreadPriority(hThread); - if(threadPriority != 0) - { - Trace("ERROR: Thread priority of hThread=0x%lx should be " - "set to normal THREAD_PRIORITY_NORMAL=%d\n", - hThread, - THREAD_PRIORITY_NORMAL); - CloseHandle(hThread); - CloseHandle(hDupThread); - Fail(""); - } - - /* Get the priority of the duplicated handle, and compare it to - * the priority of the original thread. Should be the same.*/ - duplicatePriority = GetThreadPriority(hThread); - if(duplicatePriority != threadPriority) - { - Trace("ERROR: Expected priority of hThread=0x%lx and hDupThread=0x%lx" - " to be the same. Priorities:hThread=\"%d\":hDupThread=\"%d\"\n", - hThread, - hDupThread, - threadPriority, - duplicatePriority); - CloseHandle(hThread); - CloseHandle(hDupThread); - Fail(""); - } - - /* Set the priority of the duplicate thread.*/ - if(!SetThreadPriority (hDupThread,THREAD_PRIORITY_HIGHEST)) - { - Trace("ERROR:%u: SetThreadPriority failed on hThread=0x%lx\n", - GetLastError(), - hDupThread); - CloseHandle(hThread); - CloseHandle(hDupThread); - Fail(""); - } - - /* Get the priority of the origianl thread, and - * compare it to what the duplicate was set to.*/ - finalPriority = GetThreadPriority(hThread); - if (finalPriority != THREAD_PRIORITY_HIGHEST) - { - Trace("ERROR: Expected priority of hThread=0x%lw and " - "hDupThread=0x%lw to be set the same. Priorities:" - "hThread=\"%d\":hDupThread=\"%d\".\n", - hThread, - hDupThread, - threadPriority, - duplicatePriority); - CloseHandle(hThread); - CloseHandle(hDupThread); - Fail(""); - } - - /* Wait on the original thread.*/ - if((WaitForSingleObject(hThread, 100)) != WAIT_OBJECT_0) - { - Trace("ERROR:%u: hThread=0x%lx is in a non-signalled " - "mode, yet created signalled.\n", - GetLastError(), - hThread); - CloseHandle(hThread); - CloseHandle(hDupThread); - Fail(""); - } - - /* Clean-up thread and Terminate the PAL.*/ - CloseHandle(hThread); - CloseHandle(hDupThread); - PAL_Terminate(); - return PASS; -} - -/*Thread testing function, only return '0'*/ -DWORD PALAPI CreateTestThread(LPVOID lpParam) -{ - return (DWORD)0; -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.cpp new file mode 100644 index 0000000000..0477291922 --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.cpp @@ -0,0 +1,149 @@ +// 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: test7.c (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function, +** with a handle from CreateThread. The test will create a thread +** handle and its duplicate. Then get the priorities of the threads, +** set the priority of one and the change should be seen in the +** other. +** +** +**===================================================================*/ + +#include + +DWORD PALAPI CreateTestThread(LPVOID lpParam); + +int __cdecl main(int argc, char* argv[]) +{ + HANDLE hThread; + HANDLE hDupThread; + DWORD dwThreadId = 0; + LPTHREAD_START_ROUTINE lpStartAddress = &CreateTestThread; + + int threadPriority; + int duplicatePriority; + int finalPriority; + + /* Initialize the PAL.*/ + if ((PAL_Initialize(argc, argv)) != 0) + { + return (FAIL); + } + + /* Create a thread.*/ + hThread = CreateThread(NULL, /* SD*/ + (DWORD)0, /* initial stack size*/ + lpStartAddress, /* thread function*/ + NULL, /* thread argument*/ + (DWORD)0, /* creation option*/ + &dwThreadId); /* thread identifier*/ + if (hThread == NULL) + { + Fail("ERROR:%u: Unable to create thread.\n", + GetLastError()); + } + + /* Duplicate the thread handle.*/ + if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/ + hThread, /* handle to duplicate*/ + GetCurrentProcess(), /* target process handle*/ + &hDupThread, /* duplicate handle*/ + (DWORD)0, /* requested access*/ + FALSE, /* handle inheritance*/ + DUPLICATE_SAME_ACCESS))) /* optional actions*/ + { + Trace("ERROR: %ld :Fail to create the duplicate handle" + " to hThread=0x%lx", + GetLastError(), + hThread); + CloseHandle(hThread); + Fail(""); + } + + /* Get the priority of the thread.*/ + threadPriority = GetThreadPriority(hThread); + if(threadPriority != 0) + { + Trace("ERROR: Thread priority of hThread=0x%lx should be " + "set to normal THREAD_PRIORITY_NORMAL=%d\n", + hThread, + THREAD_PRIORITY_NORMAL); + CloseHandle(hThread); + CloseHandle(hDupThread); + Fail(""); + } + + /* Get the priority of the duplicated handle, and compare it to + * the priority of the original thread. Should be the same.*/ + duplicatePriority = GetThreadPriority(hThread); + if(duplicatePriority != threadPriority) + { + Trace("ERROR: Expected priority of hThread=0x%lx and hDupThread=0x%lx" + " to be the same. Priorities:hThread=\"%d\":hDupThread=\"%d\"\n", + hThread, + hDupThread, + threadPriority, + duplicatePriority); + CloseHandle(hThread); + CloseHandle(hDupThread); + Fail(""); + } + + /* Set the priority of the duplicate thread.*/ + if(!SetThreadPriority (hDupThread,THREAD_PRIORITY_HIGHEST)) + { + Trace("ERROR:%u: SetThreadPriority failed on hThread=0x%lx\n", + GetLastError(), + hDupThread); + CloseHandle(hThread); + CloseHandle(hDupThread); + Fail(""); + } + + /* Get the priority of the origianl thread, and + * compare it to what the duplicate was set to.*/ + finalPriority = GetThreadPriority(hThread); + if (finalPriority != THREAD_PRIORITY_HIGHEST) + { + Trace("ERROR: Expected priority of hThread=0x%lw and " + "hDupThread=0x%lw to be set the same. Priorities:" + "hThread=\"%d\":hDupThread=\"%d\".\n", + hThread, + hDupThread, + threadPriority, + duplicatePriority); + CloseHandle(hThread); + CloseHandle(hDupThread); + Fail(""); + } + + /* Wait on the original thread.*/ + if((WaitForSingleObject(hThread, 100)) != WAIT_OBJECT_0) + { + Trace("ERROR:%u: hThread=0x%lx is in a non-signalled " + "mode, yet created signalled.\n", + GetLastError(), + hThread); + CloseHandle(hThread); + CloseHandle(hDupThread); + Fail(""); + } + + /* Clean-up thread and Terminate the PAL.*/ + CloseHandle(hThread); + CloseHandle(hDupThread); + PAL_Terminate(); + return PASS; +} + +/*Thread testing function, only return '0'*/ +DWORD PALAPI CreateTestThread(LPVOID lpParam) +{ + return (DWORD)0; +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test8/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test8/CMakeLists.txt index 15ec23d272..18ed969cb7 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test8/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test8/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test8.c + test8.cpp ) add_executable(paltest_duplicatehandle_test8 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.c deleted file mode 100644 index 6748c5dffd..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.c +++ /dev/null @@ -1,164 +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: test8.c (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function, -** with a handle from GetCurrentThread. The test will create a thread -** handle, get the current thread and its duplicate. Then get the -** priorities of the threads, set the priority of one and the change -** should be seen in the other. -** -** -**===================================================================*/ - -#include - -DWORD PALAPI CreateTestThread(LPVOID lpParam); - -int __cdecl main(int argc, char* argv[]) -{ - HANDLE hThread; - HANDLE hCurrentThread; - HANDLE hDupThread; - DWORD dwThreadId = 0; - LPTHREAD_START_ROUTINE lpStartAddress = &CreateTestThread; - - int threadPriority; - int duplicatePriority; - int finalPriority; - - /* Initialize the PAL.*/ - if ((PAL_Initialize(argc, argv)) != 0) - { - return (FAIL); - } - -#if !HAVE_SCHED_OTHER_ASSIGNABLE - /* Defining thread priority for SCHED_OTHER is implementation defined. - Some platforms like NetBSD cannot reassign it as they are dynamic. - */ - printf("paltest_duplicatehandle_test8 has been disabled on this platform\n"); -#else - - /* Create a thread.*/ - hThread = CreateThread(NULL, /* SD*/ - (DWORD)0, /* initial stack size*/ - lpStartAddress, /* thread function*/ - NULL, /* thread argument*/ - (DWORD)0, /* creation option*/ - &dwThreadId); /* thread identifier*/ - if (hThread == NULL) - { - Fail("ERROR:%u: Unable to create thread.\n", - GetLastError()); - } - - /*Get a psuedo handle to the current thread.*/ - hCurrentThread = GetCurrentThread(); - - /* Duplicate the psuedo thread handle.*/ - if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/ - hCurrentThread, /* handle to duplicate*/ - GetCurrentProcess(), /* target process handle*/ - &hDupThread, /* duplicate handle*/ - (DWORD)0, /* requested access*/ - FALSE, /* handle inheritance*/ - DUPLICATE_SAME_ACCESS))) /* optional actions*/ - { - Trace("ERROR: %ld :Fail to create the duplicate handle" - " to hThread=0x%lx", - GetLastError(), - hThread); - CloseHandle(hThread); - Fail(""); - } - - /* Get the priority of the thread.*/ - threadPriority = GetThreadPriority(hCurrentThread); - if(threadPriority != 0) - { - Trace("ERROR: Thread priority of hCurrentThread=0x%lx should be " - "set to normal THREAD_PRIORITY_NORMAL=%d\n", - hCurrentThread, - THREAD_PRIORITY_NORMAL); - CloseHandle(hThread); - CloseHandle(hDupThread); - Fail(""); - } - - /* Get the priority of the duplicated handle, and compare it to - * the priority of the original thread. Should be the same.*/ - duplicatePriority = GetThreadPriority(hCurrentThread); - if(duplicatePriority != threadPriority) - { - Trace("ERROR: Expected priority of hCurrentThread=0x%lx and " - "hDupThread=0x%lx to be the same. Priorities:hThread=" - "\"%d\":hDupThread=\"%d\"\n", - hCurrentThread, - hDupThread, - threadPriority, - duplicatePriority); - CloseHandle(hThread); - CloseHandle(hDupThread); - Fail(""); - } - - /* Set the priority of the original thread.*/ - if(!SetThreadPriority (hCurrentThread,THREAD_PRIORITY_HIGHEST)) - { - Trace("ERROR:%u: SetThreadPriority failed on hCurrentThread=0x%lx\n", - GetLastError(), - hCurrentThread); - CloseHandle(hThread); - CloseHandle(hDupThread); - Fail(""); - } - - /* Get the priority of the duplicate thread, and - * compare it to what the original was set to.*/ - finalPriority = GetThreadPriority(hDupThread); - if (finalPriority != THREAD_PRIORITY_HIGHEST) - { - Trace("ERROR: Expected priority of hCurrentThread=0x%lw and " - "hDupThread=0x%lw to be set the same. Priorities:" - "hCurrentThread=\"%d\":hDupThread=\"%d\".\n", - hCurrentThread, - hDupThread, - threadPriority, - duplicatePriority); - CloseHandle(hThread); - CloseHandle(hDupThread); - Fail(""); - } - - /* Wait on the original thread.*/ - if((WaitForSingleObject(hThread, 100)) != WAIT_OBJECT_0) - { - Trace("ERROR:%u: hCurrentThread=0x%lx is in a non-signalled " - "mode, yet created signalled.\n", - GetLastError(), - hThread); - CloseHandle(hThread); - CloseHandle(hDupThread); - Fail(""); - } - - /* Clean-up thread and Terminate the PAL.*/ - CloseHandle(hThread); - CloseHandle(hDupThread); - -#endif - - PAL_Terminate(); - return PASS; -} - -/*Thread testing function, only return '0'*/ -DWORD PALAPI CreateTestThread(LPVOID lpParam) -{ - return (DWORD)0; -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.cpp new file mode 100644 index 0000000000..6748c5dffd --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.cpp @@ -0,0 +1,164 @@ +// 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: test8.c (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function, +** with a handle from GetCurrentThread. The test will create a thread +** handle, get the current thread and its duplicate. Then get the +** priorities of the threads, set the priority of one and the change +** should be seen in the other. +** +** +**===================================================================*/ + +#include + +DWORD PALAPI CreateTestThread(LPVOID lpParam); + +int __cdecl main(int argc, char* argv[]) +{ + HANDLE hThread; + HANDLE hCurrentThread; + HANDLE hDupThread; + DWORD dwThreadId = 0; + LPTHREAD_START_ROUTINE lpStartAddress = &CreateTestThread; + + int threadPriority; + int duplicatePriority; + int finalPriority; + + /* Initialize the PAL.*/ + if ((PAL_Initialize(argc, argv)) != 0) + { + return (FAIL); + } + +#if !HAVE_SCHED_OTHER_ASSIGNABLE + /* Defining thread priority for SCHED_OTHER is implementation defined. + Some platforms like NetBSD cannot reassign it as they are dynamic. + */ + printf("paltest_duplicatehandle_test8 has been disabled on this platform\n"); +#else + + /* Create a thread.*/ + hThread = CreateThread(NULL, /* SD*/ + (DWORD)0, /* initial stack size*/ + lpStartAddress, /* thread function*/ + NULL, /* thread argument*/ + (DWORD)0, /* creation option*/ + &dwThreadId); /* thread identifier*/ + if (hThread == NULL) + { + Fail("ERROR:%u: Unable to create thread.\n", + GetLastError()); + } + + /*Get a psuedo handle to the current thread.*/ + hCurrentThread = GetCurrentThread(); + + /* Duplicate the psuedo thread handle.*/ + if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/ + hCurrentThread, /* handle to duplicate*/ + GetCurrentProcess(), /* target process handle*/ + &hDupThread, /* duplicate handle*/ + (DWORD)0, /* requested access*/ + FALSE, /* handle inheritance*/ + DUPLICATE_SAME_ACCESS))) /* optional actions*/ + { + Trace("ERROR: %ld :Fail to create the duplicate handle" + " to hThread=0x%lx", + GetLastError(), + hThread); + CloseHandle(hThread); + Fail(""); + } + + /* Get the priority of the thread.*/ + threadPriority = GetThreadPriority(hCurrentThread); + if(threadPriority != 0) + { + Trace("ERROR: Thread priority of hCurrentThread=0x%lx should be " + "set to normal THREAD_PRIORITY_NORMAL=%d\n", + hCurrentThread, + THREAD_PRIORITY_NORMAL); + CloseHandle(hThread); + CloseHandle(hDupThread); + Fail(""); + } + + /* Get the priority of the duplicated handle, and compare it to + * the priority of the original thread. Should be the same.*/ + duplicatePriority = GetThreadPriority(hCurrentThread); + if(duplicatePriority != threadPriority) + { + Trace("ERROR: Expected priority of hCurrentThread=0x%lx and " + "hDupThread=0x%lx to be the same. Priorities:hThread=" + "\"%d\":hDupThread=\"%d\"\n", + hCurrentThread, + hDupThread, + threadPriority, + duplicatePriority); + CloseHandle(hThread); + CloseHandle(hDupThread); + Fail(""); + } + + /* Set the priority of the original thread.*/ + if(!SetThreadPriority (hCurrentThread,THREAD_PRIORITY_HIGHEST)) + { + Trace("ERROR:%u: SetThreadPriority failed on hCurrentThread=0x%lx\n", + GetLastError(), + hCurrentThread); + CloseHandle(hThread); + CloseHandle(hDupThread); + Fail(""); + } + + /* Get the priority of the duplicate thread, and + * compare it to what the original was set to.*/ + finalPriority = GetThreadPriority(hDupThread); + if (finalPriority != THREAD_PRIORITY_HIGHEST) + { + Trace("ERROR: Expected priority of hCurrentThread=0x%lw and " + "hDupThread=0x%lw to be set the same. Priorities:" + "hCurrentThread=\"%d\":hDupThread=\"%d\".\n", + hCurrentThread, + hDupThread, + threadPriority, + duplicatePriority); + CloseHandle(hThread); + CloseHandle(hDupThread); + Fail(""); + } + + /* Wait on the original thread.*/ + if((WaitForSingleObject(hThread, 100)) != WAIT_OBJECT_0) + { + Trace("ERROR:%u: hCurrentThread=0x%lx is in a non-signalled " + "mode, yet created signalled.\n", + GetLastError(), + hThread); + CloseHandle(hThread); + CloseHandle(hDupThread); + Fail(""); + } + + /* Clean-up thread and Terminate the PAL.*/ + CloseHandle(hThread); + CloseHandle(hDupThread); + +#endif + + PAL_Terminate(); + return PASS; +} + +/*Thread testing function, only return '0'*/ +DWORD PALAPI CreateTestThread(LPVOID lpParam) +{ + return (DWORD)0; +} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test9/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test9/CMakeLists.txt index e4442e327c..0383a010ac 100644 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test9/CMakeLists.txt +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test9/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - test9.c + test9.cpp ) add_executable(paltest_duplicatehandle_test9 diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.c deleted file mode 100644 index f15871c57d..0000000000 --- a/src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.c +++ /dev/null @@ -1,127 +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: test9.c (DuplicateHandle) -** -** Purpose: Tests the PAL implementation of the DuplicateHandle function, -** with a handle from GetCurrentProcess. The test will create a -** process, duplicate it, then using ReadProcessMemory will -** read from the memory location of the CreateProcess process -** memory and the DuplicateHandle process memory. If the -** duplication is correct the memory will be the same for both. -** -** -**===================================================================*/ - -#include - -int __cdecl main(int argc, char* argv[]) -{ - HANDLE hProcess; - HANDLE hDupProcess; - char lpBuffer[64]; - char lpDupBuffer[64]; - SIZE_T lpNumberOfBytesRead; - SIZE_T lpDupNumberOfBytesRead; - char lpTestBuffer[] = "abcdefghijklmnopqrstuvwxyz"; - - /* Initalize the PAL. - */ - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - /* Initalize the buffers. - */ - ZeroMemory( &lpBuffer, sizeof(lpBuffer) ); - ZeroMemory( &lpDupBuffer, sizeof(lpDupBuffer) ); - - /* Get current proces, this will be duplicated. - */ - hProcess = GetCurrentProcess(); - if(hProcess == NULL) - { - Fail("ERROR: Unable to get the current process\n"); - } - - /* Duplicate the current process handle. - */ - if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/ - hProcess, /* handle to duplicate*/ - GetCurrentProcess(), /* target process handle*/ - &hDupProcess, /* duplicate handle*/ - (DWORD)0, /* requested access*/ - FALSE, /* handle inheritance*/ - DUPLICATE_SAME_ACCESS))) /* optional actions*/ - { - Trace("ERROR:%u: Failed to create the duplicate handle" - " to hProcess=0x%lx", - GetLastError(), - hProcess); - CloseHandle(hProcess); - Fail(""); - } - - /* Get memory read of the current process. - */ - if ((ReadProcessMemory(hDupProcess, &lpTestBuffer, - lpDupBuffer, sizeof(lpDupBuffer), &lpDupNumberOfBytesRead)) == 0) - { - Trace("ERROR:%u: Unable to read the process memory of " - "hDupProcess=0x%lx.\n", - GetLastError(), - hDupProcess); - CloseHandle(hProcess); - CloseHandle(hDupProcess); - Fail(""); - } - - /* Get read memory of the created process. - */ - if ((ReadProcessMemory(hProcess, &lpTestBuffer, - lpBuffer, sizeof(lpBuffer), &lpNumberOfBytesRead)) == 0) - { - Trace("ERROR:%u: Unable to read the process memory of " - "hProcess=0x%lx.\n", - GetLastError(), - hProcess); - CloseHandle(hProcess); - CloseHandle(hDupProcess); - Fail(""); - } - - /* Compare the number of bytes that were read by each - * ReadProcessMemory.*/ - if (lpDupNumberOfBytesRead != lpNumberOfBytesRead) - { - Trace("ERROR: ReadProcessMemory read different numbers of bytes " - "from duplicate process handles.\n"); - CloseHandle(hProcess); - CloseHandle(hDupProcess); - Fail(""); - } - - /* Compare the two buffers to make sure they are equal. - */ - if ((strcmp(lpBuffer, lpDupBuffer)) != 0) - { - Trace("ERROR: ReadProcessMemory read different numbers of bytes " - "from duplicate process handles. hProcess read \"%s\" and " - "hDupProcess read \"%s\"\n", - lpBuffer, - lpDupBuffer); - CloseHandle(hProcess); - CloseHandle(hDupProcess); - Fail(""); - } - - /* Clean-up thread and Terminate the PAL.*/ - CloseHandle(hProcess); - CloseHandle(hDupProcess); - PAL_Terminate(); - return PASS; -} diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.cpp b/src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.cpp new file mode 100644 index 0000000000..f15871c57d --- /dev/null +++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.cpp @@ -0,0 +1,127 @@ +// 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: test9.c (DuplicateHandle) +** +** Purpose: Tests the PAL implementation of the DuplicateHandle function, +** with a handle from GetCurrentProcess. The test will create a +** process, duplicate it, then using ReadProcessMemory will +** read from the memory location of the CreateProcess process +** memory and the DuplicateHandle process memory. If the +** duplication is correct the memory will be the same for both. +** +** +**===================================================================*/ + +#include + +int __cdecl main(int argc, char* argv[]) +{ + HANDLE hProcess; + HANDLE hDupProcess; + char lpBuffer[64]; + char lpDupBuffer[64]; + SIZE_T lpNumberOfBytesRead; + SIZE_T lpDupNumberOfBytesRead; + char lpTestBuffer[] = "abcdefghijklmnopqrstuvwxyz"; + + /* Initalize the PAL. + */ + if(0 != (PAL_Initialize(argc, argv))) + { + return FAIL; + } + + /* Initalize the buffers. + */ + ZeroMemory( &lpBuffer, sizeof(lpBuffer) ); + ZeroMemory( &lpDupBuffer, sizeof(lpDupBuffer) ); + + /* Get current proces, this will be duplicated. + */ + hProcess = GetCurrentProcess(); + if(hProcess == NULL) + { + Fail("ERROR: Unable to get the current process\n"); + } + + /* Duplicate the current process handle. + */ + if (!(DuplicateHandle(GetCurrentProcess(), /* source handle process*/ + hProcess, /* handle to duplicate*/ + GetCurrentProcess(), /* target process handle*/ + &hDupProcess, /* duplicate handle*/ + (DWORD)0, /* requested access*/ + FALSE, /* handle inheritance*/ + DUPLICATE_SAME_ACCESS))) /* optional actions*/ + { + Trace("ERROR:%u: Failed to create the duplicate handle" + " to hProcess=0x%lx", + GetLastError(), + hProcess); + CloseHandle(hProcess); + Fail(""); + } + + /* Get memory read of the current process. + */ + if ((ReadProcessMemory(hDupProcess, &lpTestBuffer, + lpDupBuffer, sizeof(lpDupBuffer), &lpDupNumberOfBytesRead)) == 0) + { + Trace("ERROR:%u: Unable to read the process memory of " + "hDupProcess=0x%lx.\n", + GetLastError(), + hDupProcess); + CloseHandle(hProcess); + CloseHandle(hDupProcess); + Fail(""); + } + + /* Get read memory of the created process. + */ + if ((ReadProcessMemory(hProcess, &lpTestBuffer, + lpBuffer, sizeof(lpBuffer), &lpNumberOfBytesRead)) == 0) + { + Trace("ERROR:%u: Unable to read the process memory of " + "hProcess=0x%lx.\n", + GetLastError(), + hProcess); + CloseHandle(hProcess); + CloseHandle(hDupProcess); + Fail(""); + } + + /* Compare the number of bytes that were read by each + * ReadProcessMemory.*/ + if (lpDupNumberOfBytesRead != lpNumberOfBytesRead) + { + Trace("ERROR: ReadProcessMemory read different numbers of bytes " + "from duplicate process handles.\n"); + CloseHandle(hProcess); + CloseHandle(hDupProcess); + Fail(""); + } + + /* Compare the two buffers to make sure they are equal. + */ + if ((strcmp(lpBuffer, lpDupBuffer)) != 0) + { + Trace("ERROR: ReadProcessMemory read different numbers of bytes " + "from duplicate process handles. hProcess read \"%s\" and " + "hDupProcess read \"%s\"\n", + lpBuffer, + lpDupBuffer); + CloseHandle(hProcess); + CloseHandle(hDupProcess); + Fail(""); + } + + /* Clean-up thread and Terminate the PAL.*/ + CloseHandle(hProcess); + CloseHandle(hDupProcess); + PAL_Terminate(); + return PASS; +} -- cgit v1.2.3