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 if (!WLog_GetRoot())
88 return -1;
89
90 SetLastError(ERROR_ACCESS_DENIED);
91
92 error = GetLastError();
93
94 if (error != ERROR_ACCESS_DENIED)
95 {
96 printf("GetLastError() failure: Expected: 0x%08X, Actual: 0x%08" PRIX32 "\n",
97 ERROR_ACCESS_DENIED, error);
98 return -1;
99 }
100
101 pLoopCount = winpr_aligned_calloc(1, sizeof(LONG), sizeof(LONG));
102 if (!pLoopCount)
103 {
104 printf("Unable to allocate memory\n");
105 return -1;
106 }
107 *pLoopCount = 0;
108
109 for (int i = 0; i < 4; i++)
110 {
111 if (!(threads[i] =
112 CreateThread(nullptr, 0, test_error_thread, (void*)(size_t)0, 0, nullptr)))
113 {
114 printf("Failed to create thread #%d\n", i);
115 return -1;
116 }
117 }
118
119 // let the threads run for at least 0.2 seconds
120 Sleep(200);
121 bStopTest = TRUE;
122
123 (void)WaitForSingleObject(threads[0], INFINITE);
124 (void)WaitForSingleObject(threads[1], INFINITE);
125 (void)WaitForSingleObject(threads[2], INFINITE);
126 (void)WaitForSingleObject(threads[3], INFINITE);
127
128 (void)CloseHandle(threads[0]);
129 (void)CloseHandle(threads[1]);
130 (void)CloseHandle(threads[2]);
131 (void)CloseHandle(threads[3]);
132
133 error = GetLastError();
134
135 if (error != ERROR_ACCESS_DENIED)
136 {
137 printf("GetLastError() failure: Expected: 0x%08X, Actual: 0x%08" PRIX32 "\n",
138 ERROR_ACCESS_DENIED, error);
139 return -1;
140 }
141
142 if (*pLoopCount < 4)
143 {
144 printf("Error: unexpected loop count\n");
145 return -1;
146 }
147
148 printf("Completed %" PRId32 " iterations.\n", *pLoopCount);
149 winpr_aligned_free(pLoopCount);
150
151 return status;
152}