Index: apitests/crt/static_construct.cpp =================================================================== --- apitests/crt/static_construct.cpp (revision 69993) +++ apitests/crt/static_construct.cpp (working copy) @@ -3,11 +3,76 @@ * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory * PURPOSE: Test for static C++ object construction * PROGRAMMER: Thomas Faber + * Mark Jansen */ #include #include "dll_startup.h" +#include +struct shared_memory +{ + int init_count; + int uninit_count; +}; + + +static HANDLE g_FileMapping = NULL; +static BOOL g_CreatedFileMapping = FALSE; +static shared_memory* g_Memory = NULL; + + +#if defined(TEST_MSVCRT) +#define MAPPING_NAME "msvcrt_static_init_test" +#elif defined(TEST_STATIC_CRT) +#define MAPPING_NAME "crt_static_init_test" +#endif + + +static void map_memory() +{ + if (!g_FileMapping) + { + g_FileMapping = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, MAPPING_NAME); + if (g_FileMapping) + { + g_CreatedFileMapping = FALSE; + } + else + { + g_FileMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shared_memory), MAPPING_NAME); + g_CreatedFileMapping = TRUE; + } + if (g_FileMapping == NULL) + { + skip("Could not map shared memory\n"); + return; + } + g_Memory = (shared_memory*)MapViewOfFile(g_FileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(shared_memory)); + if (g_Memory == NULL) + { + skip("Could not map view of shared memory\n"); + CloseHandle(g_FileMapping); + g_FileMapping = NULL; + } + if (g_CreatedFileMapping) + ZeroMemory(g_Memory, sizeof(shared_memory)); + } +} + +static void unmap_memory() +{ + // we do not clean the mapping in the child, since we want to count all dtor's! + if (g_FileMapping && g_CreatedFileMapping) + { + UnmapViewOfFile(g_Memory); + CloseHandle(g_FileMapping); + g_Memory = NULL; + g_FileMapping = NULL; + } +} + + extern "C" { extern int static_init_counter; @@ -35,8 +100,26 @@ } } init_static; -START_TEST(static_construct) +static struct shared_mem_static { + shared_mem_static() + { + map_memory(); + if (g_Memory) + g_Memory->init_count++; + } + + ~shared_mem_static() + { + if (g_Memory) + g_Memory->uninit_count++; + unmap_memory(); + } + +} shared_mem_static; + +static void RunTest() +{ ok(static_init_counter_at_startup == 123, "static_init_counter at startup: %d\n", static_init_counter_at_startup); ok(static_construct_counter_at_startup == 789, "static_construct_counter at startup: %d\n", static_construct_counter_at_startup); ok(m_uninit_at_startup == 0, "init_static.m_uninit at startup: %d\n", m_uninit_at_startup); @@ -85,4 +168,53 @@ ok(values.static_construct_counter == 5657, "static_construct_counter = %d\n", values.static_construct_counter); ok(values.dtor_counter_at_detach == 7878, "dtor_counter_at_detach = %d\n", values.dtor_counter_at_detach); ok(values.dtor_counter == 7879, "dtor_counter = %d\n", values.dtor_counter); + + ok(g_Memory != NULL, "Expected the mapping to be in place\n"); + ok(g_CreatedFileMapping == TRUE, "Expected to create a new shared section!\n"); + if (g_Memory) + { + ok(g_Memory->init_count == 1, "Expected init_count to be 1, was: %d\n", g_Memory->init_count); + ok(g_Memory->uninit_count == 0, "Expected uninit_count to be 0, was: %d\n", g_Memory->uninit_count); + + + char path[MAX_PATH]; + // we just need an extra argument to tell the test it's only running to increment the dtor count :) + GetModuleFileNameA(NULL, path, _countof(path)); + char buf[MAX_PATH+40]; + StringCchPrintfA(buf, _countof(buf), "\"%s\" static_construct dummy", path); + + STARTUPINFO si = { sizeof(si), 0 }; + PROCESS_INFORMATION pi; + BOOL created = CreateProcessA(NULL, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(created, "Expected CreateProcess to succeed\n"); + if (created) + { + WaitForSingleObject(pi.hProcess, INFINITE); + DWORD exit_code = 0xdeadbeef; + GetExitCodeProcess(pi.hProcess, &exit_code); + ok(exit_code == 0, "Expected the process to exit with exitcode 0, was: %lu\n", exit_code); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + ok(g_Memory->init_count == 2, "Expected init_count to be 2, was: %d\n", g_Memory->init_count); + ok(g_Memory->uninit_count == 1, "Expected uninit_count to be 1, was: %d\n", g_Memory->uninit_count); + } + } } + +START_TEST(static_construct) +{ + char **argv; + int argc = winetest_get_mainargs(&argv); + + if (argc < 3) + { + RunTest(); + } + else + { + // we are just here to increment the reference count in the shared section! + ok(g_Memory != NULL, "Expected the shared memory to be mapped!\n"); + ok(g_CreatedFileMapping == FALSE, "Expected the shared memory to be created by my parent!\n"); + } +} +