[CRT_APITEST]
[reactos.git] / rostests / apitests / crt / static_construct.cpp
index cdc27ea..3f8ff9a 100644 (file)
@@ -3,6 +3,7 @@
  * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
  * PURPOSE:         Test for static C++ object construction
  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
+ *                  Mark Jansen
  */
 
 #include <apitest.h>
@@ -101,8 +102,127 @@ TestDllStartup(VOID)
     ok(values.dtor_counter == 7879, "dtor_counter = %d\n", values.dtor_counter);
 }
 
+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;
+
+#define MAPPING_NAME L"crt_apitest_static_construct"
+
+static void map_memory()
+{
+    if (g_FileMapping)
+        return;
+
+    g_FileMapping = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, MAPPING_NAME);
+    if (g_FileMapping)
+    {
+        g_CreatedFileMapping = FALSE;
+    }
+    else
+    {
+        g_FileMapping = CreateFileMappingW(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 = static_cast<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;
+    }
+}
+
+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
+TestStaticDestruct(VOID)
+{
+    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 == NULL)
+    {
+        skip("Can't proceed without file mapping\n");
+        return;
+    }
+    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);
+
+    WCHAR path[MAX_PATH];
+    // we just need an extra argument to tell the test it's only running to increment the dtor count :)
+    GetModuleFileNameW(NULL, path, _countof(path));
+    WCHAR buf[MAX_PATH+40];
+    StringCchPrintfW(buf, _countof(buf), L"\"%ls\" static_construct dummy", path);
+
+    STARTUPINFOW si = { sizeof(si) };
+    PROCESS_INFORMATION pi;
+    BOOL created = CreateProcessW(NULL, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+    ok(created, "Expected CreateProcess to succeed\n");
+    if (created)
+    {
+        winetest_wait_child_process(pi.hProcess);
+        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)
+    {
+        // 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");
+        return;
+    }
+    
     TestInitStatic();
     TestDllStartup();
+    TestStaticDestruct();
 }