1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for atexit
5 * PROGRAMMER: Timo Kreuzer <timo.kreuzer@reactos.org>
6 */
7
8 #include <apitest.h>
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <ntndk.h>
13
14 int g_sequence = 0;
15 HANDLE g_hSemaphore;
16
exitfunc1(void)17 void exitfunc1(void)
18 {
19 ok_int(g_sequence, 1);
20 g_sequence++;
21 ReleaseSemaphore(g_hSemaphore, 1, NULL);
22 }
23
exitfunc2(void)24 void exitfunc2(void)
25 {
26 ok_int(g_sequence, 2);
27 g_sequence++;
28 ReleaseSemaphore(g_hSemaphore, 1, NULL);
29 }
30
exitfunc3(void)31 void exitfunc3(void)
32 {
33 ok_int(g_sequence, 0);
34 g_sequence++;
35 ReleaseSemaphore(g_hSemaphore, 1, NULL);
36 printf("exitfunc3\n");
37 }
38
39 typedef int (__cdecl *PFN_atexit)(void (__cdecl*)(void));
40
Test_atexit()41 void Test_atexit()
42 {
43 HMODULE hmod;
44 PFN_atexit patexit;
45
46 /* Open the named sempahore to count atexit callbacks */
47 g_hSemaphore = OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, FALSE, "atext_apitest_sempahore");
48 ok(g_hSemaphore != NULL, "couldn't open semaphore.\n");
49
50 /* Load atexit from msvcrt.dll */
51 hmod = GetModuleHandleA("msvcrt.dll");
52 patexit = (PFN_atexit)GetProcAddress(hmod, "atexit");
53 ok(patexit != NULL, "failed to get atexit from msvcrt.dll\n");
54
55 /* Register 3 exit functions, the second one in msvcrt. */
56 ok_int(atexit(exitfunc1), 0);
57 if (patexit != NULL)
58 {
59 ok_int(patexit(exitfunc2), 0);
60 }
61 ok_int(atexit(exitfunc3), 0);
62 }
63
START_TEST(atexit)64 START_TEST(atexit)
65 {
66 CHAR Buffer[MAX_PATH];
67 PSTR CommandLine;
68 int result;
69 HANDLE hSemaphore;
70 SEMAPHORE_BASIC_INFORMATION SemInfo;
71 NTSTATUS Status;
72
73 /* Check recursive call */
74 CommandLine = GetCommandLineA();
75 if (strstr(CommandLine, "-run") != NULL)
76 {
77 Test_atexit();
78 return;
79 }
80
81 /* Create a named semaphore to count atexit callbacks in remote process */
82 hSemaphore = CreateSemaphoreA(NULL, 1, 20, "atext_apitest_sempahore");
83
84 /* Run the actual test in a new process */
85 sprintf(Buffer, "%s -run", CommandLine);
86 result = system(Buffer);
87 ok_int(result, 0);
88
89 /* Check the new semaphore state */
90 Status = NtQuerySemaphore(hSemaphore, SemaphoreBasicInformation, &SemInfo, sizeof(SemInfo), NULL);
91 ok(NT_SUCCESS(Status), "NtQuerySemaphore failed: 0x%lx\n", Status);
92 ok_int(SemInfo.CurrentCount, 4);
93 }
94