FreeRDP
Loading...
Searching...
No Matches
TestErrorSetLastError.c
1
21#include <winpr/crt.h>
22#include <winpr/crypto.h>
23#include <winpr/wlog.h>
24#include <winpr/synch.h>
25#include <winpr/thread.h>
26#include <winpr/interlocked.h>
27
28#include <winpr/error.h>
29
30static int status = 0;
31
32static LONG* pLoopCount = nullptr;
33static BOOL bStopTest = FALSE;
34
35static UINT32 prand(UINT32 max)
36{
37 UINT32 tmp = 0;
38 if (max <= 1)
39 return 1;
40 if (winpr_RAND(&tmp, sizeof(tmp)) < 0)
41 {
42 (void)fprintf(stderr, "winpr_RAND failing, retry...\n");
43 // NOLINTNEXTLINE(concurrency-mt-unsafe)
44 exit(-1);
45 }
46 return tmp % (max - 1) + 1;
47}
48
49static DWORD WINAPI test_error_thread(LPVOID arg)
50{
51 int id = 0;
52 DWORD dwErrorSet = 0;
53 DWORD dwErrorGet = 0;
54
55 id = (int)(size_t)arg;
56
57 do
58 {
59 dwErrorSet = prand(UINT32_MAX - 1) + 1;
60 SetLastError(dwErrorSet);
61 if ((dwErrorGet = GetLastError()) != dwErrorSet)
62 {
63 printf("GetLastError() failure (thread %d): Expected: 0x%08" PRIX32
64 ", Actual: 0x%08" PRIX32 "\n",
65 id, dwErrorSet, dwErrorGet);
66 if (!status)
67 status = -1;
68 break;
69 }
70 InterlockedIncrement(pLoopCount);
71 } while (!status && !bStopTest);
72
73 return 0;
74}
75
76int TestErrorSetLastError(int argc, char* argv[])
77{
78 DWORD error = 0;
79 HANDLE threads[4];
80
81 WINPR_UNUSED(argc);
82 WINPR_UNUSED(argv);
83
84 /* We must initialize WLog here. It will check for settings
85 * in the environment and if the variables are not set, the last
86 * error state is changed... */
87 WLog_GetRoot();
88
89 SetLastError(ERROR_ACCESS_DENIED);
90
91 error = GetLastError();
92
93 if (error != ERROR_ACCESS_DENIED)
94 {
95 printf("GetLastError() failure: Expected: 0x%08X, Actual: 0x%08" PRIX32 "\n",
96 ERROR_ACCESS_DENIED, error);
97 return -1;
98 }
99
100 pLoopCount = winpr_aligned_malloc(sizeof(LONG), sizeof(LONG));
101 if (!pLoopCount)
102 {
103 printf("Unable to allocate memory\n");
104 return -1;
105 }
106 *pLoopCount = 0;
107
108 for (int i = 0; i < 4; i++)
109 {
110 if (!(threads[i] =
111 CreateThread(nullptr, 0, test_error_thread, (void*)(size_t)0, 0, nullptr)))
112 {
113 printf("Failed to create thread #%d\n", i);
114 return -1;
115 }
116 }
117
118 // let the threads run for at least 0.2 seconds
119 Sleep(200);
120 bStopTest = TRUE;
121
122 (void)WaitForSingleObject(threads[0], INFINITE);
123 (void)WaitForSingleObject(threads[1], INFINITE);
124 (void)WaitForSingleObject(threads[2], INFINITE);
125 (void)WaitForSingleObject(threads[3], INFINITE);
126
127 (void)CloseHandle(threads[0]);
128 (void)CloseHandle(threads[1]);
129 (void)CloseHandle(threads[2]);
130 (void)CloseHandle(threads[3]);
131
132 error = GetLastError();
133
134 if (error != ERROR_ACCESS_DENIED)
135 {
136 printf("GetLastError() failure: Expected: 0x%08X, Actual: 0x%08" PRIX32 "\n",
137 ERROR_ACCESS_DENIED, error);
138 return -1;
139 }
140
141 if (*pLoopCount < 4)
142 {
143 printf("Error: unexpected loop count\n");
144 return -1;
145 }
146
147 printf("Completed %" PRId32 " iterations.\n", *pLoopCount);
148 winpr_aligned_free(pLoopCount);
149
150 return status;
151}