--- /dev/null
+/*
+ * PROJECT: ReactOS api tests
+ * LICENSE: GPLv2+ - See COPYING in the top level directory
+ * PURPOSE: Test for SaferIdentifyLevel
+ * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
+ */
+
+#define WIN32_NO_STATUS
+#include <wine/test.h>
+#include <windows.h>
+#include <ndk/ntndk.h>
+#include <winsafer.h>
+
+#define StartSeh() ExceptionStatus = STATUS_SUCCESS; _SEH2_TRY {
+#define EndSeh(ExpectedStatus) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok(ExceptionStatus == ExpectedStatus, "Exception %lx, expected %lx\n", ExceptionStatus, ExpectedStatus)
+
+#define InvalidPointer ((PVOID)0x5555555555555555ULL)
+
+#define SaferIdentifyLevel(c, p, h, r) SaferIdentifyLevel(c, (PSAFER_CODE_PROPERTIES)(p), h, r)
+
+START_TEST(SaferIdentifyLevel)
+{
+ NTSTATUS ExceptionStatus;
+ BOOL ret;
+ DWORD error;
+ SAFER_LEVEL_HANDLE handle;
+ SAFER_CODE_PROPERTIES_V2 props[16];
+
+ StartSeh()
+ SetLastError(0xbadbad00);
+ ret = SaferIdentifyLevel(0, NULL, NULL, NULL);
+ error = GetLastError();
+ ok(ret == FALSE, "ret = %d\n", ret);
+ ok(error == ERROR_NOACCESS, "error = %lu\n", error);
+ EndSeh(STATUS_SUCCESS);
+
+ StartSeh()
+ (VOID)SaferIdentifyLevel(0, NULL, &handle, NULL);
+ EndSeh(STATUS_ACCESS_VIOLATION);
+
+ StartSeh()
+ ZeroMemory(props, sizeof(props));
+ SetLastError(0xbadbad00);
+ ret = SaferIdentifyLevel(16, props, &handle, NULL);
+ error = GetLastError();
+ ok(ret == FALSE, "ret = %d\n", ret);
+ ok(error == ERROR_BAD_LENGTH, "error = %lu\n", error);
+ EndSeh(STATUS_SUCCESS);
+
+ StartSeh()
+ ZeroMemory(props, sizeof(props));
+ SetLastError(0xbadbad00);
+ ret = SaferIdentifyLevel(1, props, NULL, NULL);
+ error = GetLastError();
+ ok(ret == FALSE, "ret = %d\n", ret);
+ ok(error == ERROR_NOACCESS, "error = %lu\n", error);
+ EndSeh(STATUS_SUCCESS);
+
+ StartSeh()
+ handle = InvalidPointer;
+ ZeroMemory(props, sizeof(props));
+ SetLastError(0xbadbad00);
+ ret = SaferIdentifyLevel(1, props, &handle, NULL);
+ error = GetLastError();
+ ok(ret == FALSE, "ret = %d\n", ret);
+ ok(handle == InvalidPointer, "handle = %p\n", handle);
+ ok(error == ERROR_BAD_LENGTH, "error = %lu\n", error);
+ if (handle && handle != InvalidPointer)
+ SaferCloseLevel(handle);
+ EndSeh(STATUS_SUCCESS);
+
+ /* Struct sizes */
+ StartSeh()
+ handle = InvalidPointer;
+ ZeroMemory(props, sizeof(props));
+ props[0].cbSize = sizeof(SAFER_CODE_PROPERTIES_V1);
+ SetLastError(0xbadbad00);
+ ret = SaferIdentifyLevel(1, props, &handle, NULL);
+ error = GetLastError();
+ ok(ret == TRUE, "ret = %d\n", ret);
+ ok(handle != NULL && handle != INVALID_HANDLE_VALUE && handle != InvalidPointer, "handle = %p\n", handle);
+ ok(error == 0xbadbad00, "error = %lu\n", error);
+ if (handle && handle != InvalidPointer)
+ {
+ ret = SaferCloseLevel(handle);
+ ok(ret == TRUE, "ret = %d\n", ret);
+ }
+ EndSeh(STATUS_SUCCESS);
+
+ StartSeh()
+ handle = InvalidPointer;
+ ZeroMemory(props, sizeof(props));
+ props[0].cbSize = sizeof(SAFER_CODE_PROPERTIES_V2);
+ SetLastError(0xbadbad00);
+ ret = SaferIdentifyLevel(1, props, &handle, NULL);
+ error = GetLastError();
+ ok(ret == FALSE, "ret = %d\n", ret);
+ ok(handle == InvalidPointer, "handle = %p\n", handle);
+ ok(error == ERROR_BAD_LENGTH, "error = %lu\n", error);
+ if (handle && handle != InvalidPointer)
+ SaferCloseLevel(handle);
+ EndSeh(STATUS_SUCCESS);
+
+ /* Test SaferCloseLevel too */
+ StartSeh()
+ ret = SaferCloseLevel(NULL);
+ error = GetLastError();
+ ok(ret == FALSE, "ret = %d\n", ret);
+ ok(error == ERROR_INVALID_HANDLE, "error = %lu\n", error);
+ EndSeh(STATUS_SUCCESS);
+
+ StartSeh()
+ ret = SaferCloseLevel(INVALID_HANDLE_VALUE);
+ error = GetLastError();
+ ok(ret == FALSE, "ret = %d\n", ret);
+ ok(error == ERROR_INVALID_HANDLE, "error = %lu\n", error);
+ EndSeh(STATUS_SUCCESS);
+
+ StartSeh()
+ ret = SaferCloseLevel(InvalidPointer);
+ error = GetLastError();
+ ok(ret == FALSE, "ret = %d\n", ret);
+ ok(error == ERROR_INVALID_HANDLE, "error = %lu\n", error);
+ EndSeh(STATUS_SUCCESS);
+}