summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr/error
diff options
context:
space:
mode:
Diffstat (limited to 'winpr/libwinpr/error')
-rw-r--r--winpr/libwinpr/error/CMakeLists.txt22
-rw-r--r--winpr/libwinpr/error/ModuleOptions.cmake9
-rw-r--r--winpr/libwinpr/error/error.c99
-rw-r--r--winpr/libwinpr/error/test/CMakeLists.txt26
-rw-r--r--winpr/libwinpr/error/test/TestErrorSetLastError.c135
5 files changed, 291 insertions, 0 deletions
diff --git a/winpr/libwinpr/error/CMakeLists.txt b/winpr/libwinpr/error/CMakeLists.txt
new file mode 100644
index 0000000..a240131
--- /dev/null
+++ b/winpr/libwinpr/error/CMakeLists.txt
@@ -0,0 +1,22 @@
+# WinPR: Windows Portable Runtime
+# libwinpr-error cmake build script
+#
+# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+winpr_module_add(error.c)
+
+if(BUILD_TESTING)
+ add_subdirectory(test)
+endif()
diff --git a/winpr/libwinpr/error/ModuleOptions.cmake b/winpr/libwinpr/error/ModuleOptions.cmake
new file mode 100644
index 0000000..b455bd7
--- /dev/null
+++ b/winpr/libwinpr/error/ModuleOptions.cmake
@@ -0,0 +1,9 @@
+
+set(MINWIN_LAYER "1")
+set(MINWIN_GROUP "core")
+set(MINWIN_MAJOR_VERSION "1")
+set(MINWIN_MINOR_VERSION "1")
+set(MINWIN_SHORT_NAME "errorhandling")
+set(MINWIN_LONG_NAME "Error Handling Functions")
+set(MODULE_LIBRARY_NAME "api-ms-win-${MINWIN_GROUP}-${MINWIN_SHORT_NAME}-l${MINWIN_LAYER}-${MINWIN_MAJOR_VERSION}-${MINWIN_MINOR_VERSION}")
+
diff --git a/winpr/libwinpr/error/error.c b/winpr/libwinpr/error/error.c
new file mode 100644
index 0000000..7746d02
--- /dev/null
+++ b/winpr/libwinpr/error/error.c
@@ -0,0 +1,99 @@
+/**
+ * WinPR: Windows Portable Runtime
+ * Error Handling Functions
+ *
+ * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <winpr/config.h>
+
+#include <winpr/error.h>
+
+#ifndef _WIN32
+
+#include <stdio.h>
+
+#include <winpr/nt.h>
+
+UINT GetErrorMode(void)
+{
+ return 0;
+}
+
+UINT SetErrorMode(UINT uMode)
+{
+ return 0;
+}
+
+DWORD GetLastError(VOID)
+{
+ PTEB pt = NtCurrentTeb();
+ if (pt)
+ {
+ return pt->LastErrorValue;
+ }
+ return ERROR_OUTOFMEMORY;
+}
+
+VOID SetLastError(DWORD dwErrCode)
+{
+ PTEB pt = NtCurrentTeb();
+ if (pt)
+ {
+ pt->LastErrorValue = dwErrCode;
+ }
+}
+
+VOID RestoreLastError(DWORD dwErrCode)
+{
+}
+
+VOID RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments,
+ CONST ULONG_PTR* lpArguments)
+{
+}
+
+LONG UnhandledExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo)
+{
+ return 0;
+}
+
+LPTOP_LEVEL_EXCEPTION_FILTER
+SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
+{
+ return NULL;
+}
+
+PVOID AddVectoredExceptionHandler(ULONG First, PVECTORED_EXCEPTION_HANDLER Handler)
+{
+ return NULL;
+}
+
+ULONG RemoveVectoredExceptionHandler(PVOID Handle)
+{
+ return 0;
+}
+
+PVOID AddVectoredContinueHandler(ULONG First, PVECTORED_EXCEPTION_HANDLER Handler)
+{
+ return NULL;
+}
+
+ULONG RemoveVectoredContinueHandler(PVOID Handle)
+{
+ return 0;
+}
+
+#endif
diff --git a/winpr/libwinpr/error/test/CMakeLists.txt b/winpr/libwinpr/error/test/CMakeLists.txt
new file mode 100644
index 0000000..83b16e1
--- /dev/null
+++ b/winpr/libwinpr/error/test/CMakeLists.txt
@@ -0,0 +1,26 @@
+
+set(MODULE_NAME "TestError")
+set(MODULE_PREFIX "TEST_ERROR")
+
+set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
+
+set(${MODULE_PREFIX}_TESTS
+ TestErrorSetLastError.c)
+
+create_test_sourcelist(${MODULE_PREFIX}_SRCS
+ ${${MODULE_PREFIX}_DRIVER}
+ ${${MODULE_PREFIX}_TESTS})
+
+add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
+
+target_link_libraries(${MODULE_NAME} winpr)
+
+set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
+
+foreach(test ${${MODULE_PREFIX}_TESTS})
+ get_filename_component(TestName ${test} NAME_WE)
+ add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
+endforeach()
+
+set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
+
diff --git a/winpr/libwinpr/error/test/TestErrorSetLastError.c b/winpr/libwinpr/error/test/TestErrorSetLastError.c
new file mode 100644
index 0000000..a3d57af
--- /dev/null
+++ b/winpr/libwinpr/error/test/TestErrorSetLastError.c
@@ -0,0 +1,135 @@
+/**
+ * CTest for winpr's SetLastError/GetLastError
+ *
+ * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2013 Thincast Technologies GmbH
+ * Copyright 2013 Norbert Federa <norbert.federa@thincast.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <winpr/crt.h>
+#include <winpr/wlog.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+#include <winpr/interlocked.h>
+
+#include <winpr/error.h>
+
+static int status = 0;
+
+static LONG* pLoopCount = NULL;
+static BOOL bStopTest = FALSE;
+
+static DWORD WINAPI test_error_thread(LPVOID arg)
+{
+ int id = 0;
+ DWORD dwErrorSet = 0;
+ DWORD dwErrorGet = 0;
+
+ id = (int)(size_t)arg;
+
+ do
+ {
+ dwErrorSet = (DWORD)abs(rand()) + 1;
+ SetLastError(dwErrorSet);
+ if ((dwErrorGet = GetLastError()) != dwErrorSet)
+ {
+ printf("GetLastError() failure (thread %d): Expected: 0x%08" PRIX32
+ ", Actual: 0x%08" PRIX32 "\n",
+ id, dwErrorSet, dwErrorGet);
+ if (!status)
+ status = -1;
+ break;
+ }
+ InterlockedIncrement(pLoopCount);
+ } while (!status && !bStopTest);
+
+ return 0;
+}
+
+int TestErrorSetLastError(int argc, char* argv[])
+{
+ DWORD error = 0;
+ HANDLE threads[4];
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ /* We must initialize WLog here. It will check for settings
+ * in the environment and if the variables are not set, the last
+ * error state is changed... */
+ WLog_GetRoot();
+
+ SetLastError(ERROR_ACCESS_DENIED);
+
+ error = GetLastError();
+
+ if (error != ERROR_ACCESS_DENIED)
+ {
+ printf("GetLastError() failure: Expected: 0x%08X, Actual: 0x%08" PRIX32 "\n",
+ ERROR_ACCESS_DENIED, error);
+ return -1;
+ }
+
+ pLoopCount = winpr_aligned_malloc(sizeof(LONG), sizeof(LONG));
+ if (!pLoopCount)
+ {
+ printf("Unable to allocate memory\n");
+ return -1;
+ }
+ *pLoopCount = 0;
+
+ for (int i = 0; i < 4; i++)
+ {
+ if (!(threads[i] = CreateThread(NULL, 0, test_error_thread, (void*)(size_t)0, 0, NULL)))
+ {
+ printf("Failed to create thread #%d\n", i);
+ return -1;
+ }
+ }
+
+ // let the threads run for at least 0.2 seconds
+ Sleep(200);
+ bStopTest = TRUE;
+
+ WaitForSingleObject(threads[0], INFINITE);
+ WaitForSingleObject(threads[1], INFINITE);
+ WaitForSingleObject(threads[2], INFINITE);
+ WaitForSingleObject(threads[3], INFINITE);
+
+ CloseHandle(threads[0]);
+ CloseHandle(threads[1]);
+ CloseHandle(threads[2]);
+ CloseHandle(threads[3]);
+
+ error = GetLastError();
+
+ if (error != ERROR_ACCESS_DENIED)
+ {
+ printf("GetLastError() failure: Expected: 0x%08X, Actual: 0x%08" PRIX32 "\n",
+ ERROR_ACCESS_DENIED, error);
+ return -1;
+ }
+
+ if (*pLoopCount < 4)
+ {
+ printf("Error: unexpected loop count\n");
+ return -1;
+ }
+
+ printf("Completed %" PRId32 " iterations.\n", *pLoopCount);
+ winpr_aligned_free(pLoopCount);
+
+ return status;
+}