FreeRDP
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 
30 static int status = 0;
31 
32 static LONG* pLoopCount = NULL;
33 static BOOL bStopTest = FALSE;
34 
35 static 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 
44 static 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 
71 int 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 }