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