[SFC_APITEST] Initial test for SfcIsFileProtected and SfcGetFiles 897/head
authorMark Jansen <mark.jansen@reactos.org>
Sun, 25 Nov 2018 18:52:20 +0000 (19:52 +0100)
committerMark Jansen <mark.jansen@reactos.org>
Wed, 12 Dec 2018 18:33:44 +0000 (19:33 +0100)
modules/rostests/apitests/CMakeLists.txt
modules/rostests/apitests/sfc/CMakeLists.txt [new file with mode: 0644]
modules/rostests/apitests/sfc/SfcGetFiles.c [new file with mode: 0644]
modules/rostests/apitests/sfc/SfcIsFileProtected.c [new file with mode: 0644]
modules/rostests/apitests/sfc/testlist.c [new file with mode: 0644]

index 5312b28..ec50485 100644 (file)
@@ -29,6 +29,7 @@ add_subdirectory(pefile)
 add_subdirectory(powrprof)
 add_subdirectory(sdk)
 add_subdirectory(setupapi)
+add_subdirectory(sfc)
 add_subdirectory(shell32)
 add_subdirectory(shlwapi)
 add_subdirectory(spoolss)
diff --git a/modules/rostests/apitests/sfc/CMakeLists.txt b/modules/rostests/apitests/sfc/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1d51f0b
--- /dev/null
@@ -0,0 +1,10 @@
+
+list(APPEND SOURCE
+    SfcGetFiles.c
+    SfcIsFileProtected.c
+    testlist.c)
+
+add_executable(sfc_apitest ${SOURCE})
+set_module_type(sfc_apitest win32cui)
+add_importlibs(sfc_apitest msvcrt user32 kernel32 ntdll)
+add_rostests_file(TARGET sfc_apitest)
diff --git a/modules/rostests/apitests/sfc/SfcGetFiles.c b/modules/rostests/apitests/sfc/SfcGetFiles.c
new file mode 100644 (file)
index 0000000..edcf3cb
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * PROJECT:     ReactOS api tests
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Test for SfcGetFiles
+ * COPYRIGHT:   Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
+ */
+
+#include <apitest.h>
+#include <strsafe.h>
+#include <ndk/umtypes.h>
+
+typedef struct _PROTECT_FILE_ENTRY {
+    PWSTR SourceFileName;
+    PWSTR FileName;
+    PWSTR InfName;
+} PROTECT_FILE_ENTRY, *PPROTECT_FILE_ENTRY;
+
+NTSTATUS (WINAPI *SfcGetFiles)(PPROTECT_FILE_ENTRY* ProtFileData, PULONG FileCount);
+
+PCWSTR wszEnvVars[] =
+{
+    L"%systemroot%",
+    L"%commonprogramfiles%",
+    L"%ProgramFiles%",
+    L"%systemdrive%"
+};
+
+static void Test_GetFiles()
+{
+    PPROTECT_FILE_ENTRY FileData;
+    PCWSTR Ptr;
+    ULONG FileCount, n, j;
+    NTSTATUS Status;
+
+    Status = SfcGetFiles(&FileData, &FileCount);
+    ok(NT_SUCCESS(Status), "SfcGetFiles failed: 0x%lx\n", Status);
+
+    if (!NT_SUCCESS(Status))
+        return;
+
+    for (n = 0; n < FileCount; ++n)
+    {
+        PPROTECT_FILE_ENTRY Entry = FileData + n;
+
+        ok(Entry->FileName != NULL, "Entry %lu without FileName!", n);
+        if (Entry->FileName)
+        {
+            Ptr = NULL;
+            for (j = 0; j < _countof(wszEnvVars); ++j)
+            {
+                Ptr = wcsstr(Entry->FileName, wszEnvVars[j]);
+                if (Ptr)
+                    break;
+            }
+            ok(Ptr != NULL, "Expected to find one match from wszEnvVars in %s\n", wine_dbgstr_w(Entry->FileName));
+        }
+        if (Entry->InfName)
+        {
+            Ptr = wcsstr(Entry->InfName, L".inf");
+            ok(Ptr == (Entry->InfName + wcslen(Entry->InfName) - 4),
+               ".inf not found in %s\n", wine_dbgstr_w(Entry->InfName));
+        }
+    }
+}
+
+START_TEST(SfcGetFiles)
+{
+    HMODULE mod;
+
+    mod = LoadLibraryA("sfcfiles.dll");
+    if (!mod)
+    {
+        skip("sfcfiles.dll not found\n");
+        return;
+    }
+
+    SfcGetFiles = (void*)GetProcAddress(mod, "SfcGetFiles");
+    ok(SfcGetFiles != NULL, "Function not exported!\n");
+    if (!SfcGetFiles)
+        return;
+
+    Test_GetFiles();
+}
diff --git a/modules/rostests/apitests/sfc/SfcIsFileProtected.c b/modules/rostests/apitests/sfc/SfcIsFileProtected.c
new file mode 100644 (file)
index 0000000..6bcf7e9
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * PROJECT:     ReactOS api tests
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Test for SfcIsFileProtected
+ * COPYRIGHT:   Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
+ */
+
+#include <apitest.h>
+#include <strsafe.h>
+#include <ndk/umtypes.h>
+#include <ndk/rtlfuncs.h>
+
+BOOL (WINAPI *SfcIsFileProtected)(HANDLE  RpcHandle,LPCWSTR ProtFileName);
+static DWORD g_WinVersion;
+
+typedef struct _osrange
+{
+    DWORD Min;
+    DWORD Max;
+} osrange;
+
+typedef struct _testdata
+{
+    PCWSTR Path;
+    BOOL Expand;
+    osrange Success;
+} testdata;
+
+
+#define _WIN32_WINNT_MINVER 0x0001
+
+#define MAKERANGE(from, to) \
+    { _WIN32_WINNT_ ## from, _WIN32_WINNT_ ## to }
+
+#define PASS(from, to) \
+    MAKERANGE(from, to)
+
+static testdata tests[] =
+{
+    { L"%systemroot%\\system32\\kernel32.dll", TRUE,                PASS(MINVER, WIN10) },
+    { L"%SYSTEMROOT%\\SYSTEM32\\KERNEL32.DLL", TRUE,                PASS(MINVER, WIN10) },
+    /* Paths are normalized on newer windows */
+    { L"%systemroot%//system32\\kernel32.dll", TRUE,                PASS(VISTA, WIN10) },
+    { L"%systemroot%\\system32\\..\\system32\\kernel32.dll", TRUE,  PASS(VISTA, WIN10) },
+
+    /* These are rejected as-is */
+    { L"kernel32.dll", FALSE,                                       PASS(MINVER, MINVER) },
+    { L"%systemroot%//system32\\kernel32.dll", FALSE,               PASS(MINVER, MINVER) },
+    /* Environment strings are expanded on older windows */
+    { L"%systemroot%\\system32\\kernel32.dll", FALSE,               PASS(MINVER, WS03) },
+    { L"%SYSTEMROOT%\\SYSTEM32\\KERNEL32.DLL", FALSE,               PASS(MINVER, WS03) },
+
+    /* Show some files under SFC protection */
+    { L"%systemroot%\\system32\\user32.dll", TRUE,                  PASS(MINVER, WIN10) },
+    { L"%systemroot%\\system32\\shell32.dll", TRUE,                 PASS(MINVER, WIN10) },
+    { L"%systemroot%\\system32\\browseui.dll", TRUE,                PASS(MINVER, WIN10) },
+    { L"%systemroot%\\system32\\apphelp.dll", TRUE,                 PASS(MINVER, WIN10) },
+    { L"%systemroot%\\system32\\sfc.dll", TRUE,                     PASS(MINVER, WIN10) },
+    { L"%systemroot%\\system32\\sfc_os.dll", TRUE,                  PASS(MINVER, WIN10) },
+    { L"%systemroot%\\system32\\sdbinst.exe", TRUE,                 PASS(MINVER, WIN10) },
+    { L"%systemroot%\\AppPatch\\sysmain.sdb", TRUE,                 PASS(MINVER, WIN10) },
+    { L"%systemroot%\\fonts\\tahoma.ttf", TRUE,                     PASS(MINVER, WIN10) },
+    { L"%systemroot%\\fonts\\tahomabd.ttf", TRUE,                   PASS(MINVER, WIN10) },
+    { L"%systemroot%\\system32\\ntoskrnl.exe", TRUE,                PASS(MINVER, WIN10) },
+    { L"%systemroot%\\system32\\c_1252.nls", TRUE,                  PASS(MINVER, WIN10) },
+    { L"%systemroot%\\NOTEPAD.EXE", TRUE,                           PASS(MINVER, WIN10) },
+};
+
+
+static void Test_ProtectedFiles()
+{
+    ULONG n;
+    BOOL Protected;
+    WCHAR Buffer[MAX_PATH * 3];
+
+    for (n = 0; n < _countof(tests); ++n)
+    {
+        if (tests[n].Expand)
+            ExpandEnvironmentStringsW(tests[n].Path, Buffer, _countof(Buffer));
+        else
+            StringCchCopyW(Buffer, _countof(Buffer), tests[n].Path);
+
+        Protected = SfcIsFileProtected(NULL, Buffer);
+
+        if (g_WinVersion >= tests[n].Success.Min && g_WinVersion <= tests[n].Success.Max)
+        {
+            ok(Protected, "[%lu,0x%04lx]: Failed: %S\n", n, g_WinVersion, Buffer);
+        }
+        else
+        {
+            ok(!Protected, "[%lu,0x%04lx]: Succeeded: %S\n", n, g_WinVersion, Buffer);
+        }
+    }
+}
+
+
+START_TEST(SfcIsFileProtected)
+{
+    RTL_OSVERSIONINFOW rtlinfo = { sizeof(rtlinfo) };
+    HMODULE mod;
+
+    mod = LoadLibraryA("sfc_os.dll");
+    ok(mod != NULL, "Unable to load sfc_os: 0x%lu\n", GetLastError());
+    if (!mod)
+        return;
+
+    SfcIsFileProtected = (void*)GetProcAddress(mod, "SfcIsFileProtected");
+    ok(SfcIsFileProtected != NULL, "Unable to resolve SfcIsFileProtected: 0x%lu\n", GetLastError());
+    if (!SfcIsFileProtected)
+        return;
+
+    RtlGetVersion(&rtlinfo);
+    g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion;
+
+    Test_ProtectedFiles();
+}
diff --git a/modules/rostests/apitests/sfc/testlist.c b/modules/rostests/apitests/sfc/testlist.c
new file mode 100644 (file)
index 0000000..d75f811
--- /dev/null
@@ -0,0 +1,12 @@
+#define STANDALONE
+#include <apitest.h>
+
+extern void func_SfcGetFiles(void);
+extern void func_SfcIsFileProtected(void);
+
+const struct test winetest_testlist[] =
+{
+    { "SfcGetFiles", func_SfcGetFiles },
+    { "SfcIsFileProtected", func_SfcIsFileProtected },
+    { 0, 0 }
+};