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>
28#include <winpr/error.h>
32static LONG* pLoopCount =
nullptr;
33static BOOL bStopTest = FALSE;
35static UINT32 prand(UINT32 max)
40 if (winpr_RAND(&tmp,
sizeof(tmp)) < 0)
42 (void)fprintf(stderr,
"winpr_RAND failing, retry...\n");
46 return tmp % (max - 1) + 1;
49static DWORD WINAPI test_error_thread(LPVOID arg)
55 id = (int)(
size_t)arg;
59 dwErrorSet = prand(UINT32_MAX - 1) + 1;
60 SetLastError(dwErrorSet);
61 if ((dwErrorGet = GetLastError()) != dwErrorSet)
63 printf(
"GetLastError() failure (thread %d): Expected: 0x%08" PRIX32
64 ", Actual: 0x%08" PRIX32
"\n",
65 id, dwErrorSet, dwErrorGet);
70 InterlockedIncrement(pLoopCount);
71 }
while (!status && !bStopTest);
76int TestErrorSetLastError(
int argc,
char* argv[])
89 SetLastError(ERROR_ACCESS_DENIED);
91 error = GetLastError();
93 if (error != ERROR_ACCESS_DENIED)
95 printf(
"GetLastError() failure: Expected: 0x%08X, Actual: 0x%08" PRIX32
"\n",
96 ERROR_ACCESS_DENIED, error);
100 pLoopCount = winpr_aligned_malloc(
sizeof(LONG),
sizeof(LONG));
103 printf(
"Unable to allocate memory\n");
108 for (
int i = 0; i < 4; i++)
111 CreateThread(
nullptr, 0, test_error_thread, (
void*)(
size_t)0, 0,
nullptr)))
113 printf(
"Failed to create thread #%d\n", i);
122 (void)WaitForSingleObject(threads[0], INFINITE);
123 (void)WaitForSingleObject(threads[1], INFINITE);
124 (void)WaitForSingleObject(threads[2], INFINITE);
125 (void)WaitForSingleObject(threads[3], INFINITE);
127 (void)CloseHandle(threads[0]);
128 (void)CloseHandle(threads[1]);
129 (void)CloseHandle(threads[2]);
130 (void)CloseHandle(threads[3]);
132 error = GetLastError();
134 if (error != ERROR_ACCESS_DENIED)
136 printf(
"GetLastError() failure: Expected: 0x%08X, Actual: 0x%08" PRIX32
"\n",
137 ERROR_ACCESS_DENIED, error);
143 printf(
"Error: unexpected loop count\n");
147 printf(
"Completed %" PRId32
" iterations.\n", *pLoopCount);
148 winpr_aligned_free(pLoopCount);