https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f4b7087a0e3c047c8a79b8c567f7b21c12d70375

commit f4b7087a0e3c047c8a79b8c567f7b21c12d70375
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Thu Apr 27 20:35:41 2023 +0900
Commit:     GitHub <[email protected]>
CommitDate: Thu Apr 27 20:35:41 2023 +0900

    [ADVPACK_APITEST] Add advpack_apitest:DelNode testcase (#5256)
    
    Preparation for advpack!DelNodeA/W functions implementation. CORE-13275, 
ROSTESTS-276
---
 modules/rostests/apitests/CMakeLists.txt         |   1 +
 modules/rostests/apitests/advpack/CMakeLists.txt |  10 +
 modules/rostests/apitests/advpack/DelNode.c      | 587 +++++++++++++++++++++++
 modules/rostests/apitests/advpack/testlist.c     |  18 +
 4 files changed, 616 insertions(+)

diff --git a/modules/rostests/apitests/CMakeLists.txt 
b/modules/rostests/apitests/CMakeLists.txt
index b9f10c04120..407b5955964 100644
--- a/modules/rostests/apitests/CMakeLists.txt
+++ b/modules/rostests/apitests/CMakeLists.txt
@@ -5,6 +5,7 @@ include_directories(include)
 
 add_subdirectory(acpi)
 add_subdirectory(advapi32)
+add_subdirectory(advpack)
 add_subdirectory(afd)
 add_subdirectory(apphelp)
 add_subdirectory(appshim)
diff --git a/modules/rostests/apitests/advpack/CMakeLists.txt 
b/modules/rostests/apitests/advpack/CMakeLists.txt
new file mode 100644
index 00000000000..a811f98e1b3
--- /dev/null
+++ b/modules/rostests/apitests/advpack/CMakeLists.txt
@@ -0,0 +1,10 @@
+
+list(APPEND SOURCE
+    DelNode.c
+    testlist.c)
+
+add_executable(advpack_apitest ${SOURCE})
+target_link_libraries(advpack_apitest wine ${PSEH_LIB})
+set_module_type(advpack_apitest win32cui)
+add_importlibs(advpack_apitest advpack msvcrt kernel32 ntdll)
+add_rostests_file(TARGET advpack_apitest)
diff --git a/modules/rostests/apitests/advpack/DelNode.c 
b/modules/rostests/apitests/advpack/DelNode.c
new file mode 100644
index 00000000000..7f968d5ab8f
--- /dev/null
+++ b/modules/rostests/apitests/advpack/DelNode.c
@@ -0,0 +1,587 @@
+/*
+ * PROJECT:     ReactOS API tests
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Test for advpack.dll DelNode function
+ * COPYRIGHT:   Copyright 2023 Katayama Hirofumi MZ 
<[email protected]>
+ */
+#include <apitest.h>
+
+#include <windef.h>
+#include <stdio.h>
+
+/* Flags for DelNode */
+#define ADN_DEL_IF_EMPTY            0x00000001
+#define ADN_DONT_DEL_SUBDIRS        0x00000002
+#define ADN_DONT_DEL_DIR            0x00000004
+#define ADN_DEL_UNC_PATHS           0x00000008
+
+/* DelNodeA and DelNodeW in advpack.dll */
+typedef HRESULT (WINAPI *DELNODEA)(LPCSTR, DWORD);
+typedef HRESULT (WINAPI *DELNODEW)(LPCWSTR, DWORD);
+
+static HINSTANCE s_hAdvPack = NULL;
+static DELNODEA s_pDelNodeA = NULL;
+static DELNODEW s_pDelNodeW = NULL;
+
+typedef struct
+{
+    const char *item;
+    BOOL is_dir;
+} NODEA;
+
+static const NODEA s_nodesA[] =
+{
+    { "dir1", TRUE },               /* 0 */
+    { "dir1\\dir2", TRUE },         /* 1 */
+    { "dir1\\dir2\\file1", FALSE }, /* 2 */
+};
+
+typedef struct
+{
+    const WCHAR *item;
+    BOOL is_dir;
+} NODEW;
+
+static const NODEW s_nodesW[] =
+{
+    { L"dir1", TRUE },               /* 0 */
+    { L"dir1\\dir2", TRUE },         /* 1 */
+    { L"dir1\\dir2\\file1", FALSE }, /* 2 */
+};
+
+typedef enum
+{
+    EAT_CREATE,
+    EAT_DELETE,
+    EAT_CHECK_EXIST,
+    EAT_CHECK_NON_EXIST,
+    EAT_CALL
+} ENTRY_ACTION_TYPE;
+
+typedef struct
+{
+    INT lineno;
+    INT node;
+    ENTRY_ACTION_TYPE action_type;
+    DWORD flags;
+    HRESULT ret;
+} ENTRY;
+
+/* TODO: ADN_DEL_UNC_PATHS */
+#define FLAGS0  0
+#define FLAGS1  ADN_DEL_IF_EMPTY
+#define FLAGS2  ADN_DONT_DEL_DIR
+#define FLAGS3  ADN_DONT_DEL_SUBDIRS
+#define FLAGS4  (ADN_DONT_DEL_DIR | ADN_DONT_DEL_SUBDIRS)
+#define FLAGS5  (ADN_DEL_IF_EMPTY | ADN_DONT_DEL_DIR)
+#define FLAGS6  (ADN_DEL_IF_EMPTY | ADN_DONT_DEL_SUBDIRS)
+#define FLAGS7  (ADN_DEL_IF_EMPTY | ADN_DONT_DEL_DIR | ADN_DONT_DEL_SUBDIRS)
+#define FLAGS8  0xFFFFFFFF
+
+/* The test entries */
+static const ENTRY s_entries[] =
+{
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 1, EAT_DELETE },
+    { __LINE__, 0, EAT_DELETE },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS0, S_OK },
+    { __LINE__, 0, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS1, E_FAIL },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS2, S_OK },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS3, S_OK },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS4, S_OK },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS5, E_FAIL },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS6, E_FAIL },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS7, E_FAIL },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS8, E_FAIL },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS0, S_OK },
+    { __LINE__, 0, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS1, E_FAIL },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS2, S_OK },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+    { __LINE__, 1, EAT_CHECK_NON_EXIST },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS3, S_OK },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS4, S_OK },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS5, E_FAIL },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS6, E_FAIL },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS7, E_FAIL },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 0, EAT_CREATE },
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 0, EAT_CALL, FLAGS8, E_FAIL },
+    { __LINE__, 0, EAT_CHECK_EXIST },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS0, S_OK },
+    { __LINE__, 1, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS1, E_FAIL },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS2, S_OK },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS3, S_OK },
+    { __LINE__, 1, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS4, S_OK },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS5, E_FAIL },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS6, E_FAIL },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS7, E_FAIL },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS8, E_FAIL },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+    { __LINE__, 2, EAT_CHECK_EXIST },
+
+    { __LINE__, 2, EAT_DELETE },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS0, S_OK },
+    { __LINE__, 1, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS1, S_OK },
+    { __LINE__, 1, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS2, S_OK },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS3, S_OK },
+    { __LINE__, 1, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS4, S_OK },
+    { __LINE__, 1, EAT_CHECK_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS5, S_OK },
+    { __LINE__, 1, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS6, S_OK },
+    { __LINE__, 1, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS7, S_OK },
+    { __LINE__, 1, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+    { __LINE__, 1, EAT_CALL, FLAGS8, S_OK },
+    { __LINE__, 1, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 1, EAT_CREATE },
+
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 2, EAT_CALL, FLAGS0, S_OK },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 2, EAT_CALL, FLAGS1, S_OK },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 2, EAT_CALL, FLAGS2, S_OK },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 2, EAT_CALL, FLAGS3, S_OK },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 2, EAT_CALL, FLAGS4, S_OK },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 2, EAT_CALL, FLAGS5, S_OK },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 2, EAT_CALL, FLAGS6, S_OK },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 2, EAT_CALL, FLAGS7, S_OK },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 2, EAT_CREATE },
+    { __LINE__, 2, EAT_CALL, FLAGS8, S_OK },
+    { __LINE__, 2, EAT_CHECK_NON_EXIST },
+
+    { __LINE__, 2, EAT_DELETE },
+    { __LINE__, 1, EAT_DELETE },
+    { __LINE__, 0, EAT_DELETE },
+
+    { __LINE__, 2, EAT_CALL, FLAGS0, E_FAIL },
+    { __LINE__, 2, EAT_CALL, FLAGS1, E_FAIL },
+    { __LINE__, 2, EAT_CALL, FLAGS2, E_FAIL },
+    { __LINE__, 2, EAT_CALL, FLAGS3, E_FAIL },
+    { __LINE__, 2, EAT_CALL, FLAGS4, E_FAIL },
+    { __LINE__, 2, EAT_CALL, FLAGS5, E_FAIL },
+    { __LINE__, 2, EAT_CALL, FLAGS6, E_FAIL },
+    { __LINE__, 2, EAT_CALL, FLAGS7, E_FAIL },
+    { __LINE__, 2, EAT_CALL, FLAGS8, E_FAIL },
+
+    { __LINE__, 1, EAT_CALL, FLAGS0, E_FAIL },
+    { __LINE__, 1, EAT_CALL, FLAGS1, E_FAIL },
+    { __LINE__, 1, EAT_CALL, FLAGS2, E_FAIL },
+    { __LINE__, 1, EAT_CALL, FLAGS3, E_FAIL },
+    { __LINE__, 1, EAT_CALL, FLAGS4, E_FAIL },
+    { __LINE__, 1, EAT_CALL, FLAGS5, E_FAIL },
+    { __LINE__, 1, EAT_CALL, FLAGS6, E_FAIL },
+    { __LINE__, 1, EAT_CALL, FLAGS7, E_FAIL },
+    { __LINE__, 1, EAT_CALL, FLAGS8, E_FAIL },
+};
+
+static char  s_cur_dir_A[MAX_PATH] = "";
+static WCHAR s_cur_dir_W[MAX_PATH] = L"";
+
+static char *GetPathA(const char *item)
+{
+    static char s_path[MAX_PATH];
+    lstrcpyA(s_path, s_cur_dir_A);
+    lstrcatA(s_path, "\\");
+    lstrcatA(s_path, item);
+    return s_path;
+}
+
+static WCHAR *GetPathW(const WCHAR *item)
+{
+    static WCHAR s_path[MAX_PATH];
+    lstrcpyW(s_path, s_cur_dir_W);
+    lstrcatW(s_path, L"\\");
+    lstrcatW(s_path, item);
+    return s_path;
+}
+
+static void cleanupA(void)
+{
+    size_t i, k;
+    for (k = 0; k < 4; ++k)
+    {
+        for (i = 0; i < _countof(s_nodesA); ++i)
+        {
+            const NODEA *node = &s_nodesA[i];
+            char *path = GetPathA(node->item);
+
+            DeleteFileA(path);
+            RemoveDirectoryA(path);
+        }
+    }
+}
+
+static void Test_DelNodeA(void)
+{
+    DWORD attr;
+    size_t i;
+
+    if (!GetCurrentDirectoryA(_countof(s_cur_dir_A), s_cur_dir_A))
+    {
+        skip("GetCurrentDirectoryA failed\n");
+        return;
+    }
+
+    cleanupA();
+
+    for (i = 0; i < _countof(s_entries); ++i)
+    {
+        const ENTRY *entry = &s_entries[i];
+        INT lineno = entry->lineno;
+        const NODEA *node = &s_nodesA[entry->node];
+        char *path = GetPathA(node->item);
+        INT ret;
+
+        switch (entry->action_type)
+        {
+            case EAT_CREATE:
+                if (node->is_dir)
+                {
+                    CreateDirectoryA(path, NULL);
+
+                    attr = GetFileAttributesA(path);
+                    ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: path:%s, 
attr:0x%08lX\n", lineno, path, attr);
+                    ok((attr & FILE_ATTRIBUTE_DIRECTORY), "Line %d: path:%s, 
attr:0x%08lX\n", lineno, path, attr);
+                }
+                else
+                {
+                    fclose(fopen(path, "w"));
+
+                    attr = GetFileAttributesA(path);
+                    ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: attr was 
0x%08lX\n", lineno, attr);
+                    ok(!(attr & FILE_ATTRIBUTE_DIRECTORY), "Line %d: attr was 
0x%08lX\n", lineno, attr);
+                }
+                break;
+            case EAT_DELETE:
+                if (node->is_dir)
+                {
+                    RemoveDirectoryA(path);
+                }
+                else
+                {
+                    DeleteFileA(path);
+                }
+                attr = GetFileAttributesA(path);
+                ok(attr == INVALID_FILE_ATTRIBUTES, "Line %d: cannot 
delete\n", lineno);
+                break;
+            case EAT_CHECK_EXIST:
+                attr = GetFileAttributesA(path);
+                ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: attr was 
0x%08lX\n", lineno, attr);
+                break;
+            case EAT_CHECK_NON_EXIST:
+                attr = GetFileAttributesA(path);
+                ok(attr == INVALID_FILE_ATTRIBUTES, "Line %d: attr was 
0x%08lX\n", lineno, attr);
+                break;
+            case EAT_CALL:
+                ret = (*s_pDelNodeA)(path, entry->flags);
+                ok(ret == entry->ret, "Line %d: ret:%d, path:%s, 
flags:0x%08lX\n",
+                   lineno, ret, path, entry->flags);
+                break;
+        }
+    }
+
+    cleanupA();
+}
+
+static void cleanupW(void)
+{
+    size_t i, k;
+    for (k = 0; k < 4; ++k)
+    {
+        for (i = 0; i < _countof(s_nodesW); ++i)
+        {
+            const NODEW *node = &s_nodesW[i];
+            WCHAR *path = GetPathW(node->item);
+
+            DeleteFileW(path);
+            RemoveDirectoryW(path);
+        }
+    }
+}
+
+static void Test_DelNodeW(void)
+{
+    DWORD attr;
+    size_t i;
+
+    if (!GetCurrentDirectoryW(_countof(s_cur_dir_W), s_cur_dir_W))
+    {
+        skip("GetCurrentDirectoryA failed\n");
+        return;
+    }
+
+    cleanupW();
+
+    for (i = 0; i < _countof(s_entries); ++i)
+    {
+        const ENTRY *entry = &s_entries[i];
+        INT lineno = entry->lineno;
+        const NODEW *node = &s_nodesW[entry->node];
+        WCHAR *path = GetPathW(node->item);
+        INT ret;
+
+        switch (entry->action_type)
+        {
+            case EAT_CREATE:
+                if (node->is_dir)
+                {
+                    CreateDirectoryW(path, NULL);
+
+                    attr = GetFileAttributesW(path);
+                    ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: path:%S, 
attr:0x%08lX\n", lineno, path, attr);
+                    ok((attr & FILE_ATTRIBUTE_DIRECTORY), "Line %d: path:%S, 
attr:0x%08lX\n", lineno, path, attr);
+                }
+                else
+                {
+                    fclose(_wfopen(path, L"w"));
+
+                    attr = GetFileAttributesW(path);
+                    ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: attr was 
0x%08lX\n", lineno, attr);
+                    ok(!(attr & FILE_ATTRIBUTE_DIRECTORY), "Line %d: attr was 
0x%08lX\n", lineno, attr);
+                }
+                break;
+            case EAT_DELETE:
+                if (node->is_dir)
+                {
+                    RemoveDirectoryW(path);
+                }
+                else
+                {
+                    DeleteFileW(path);
+                }
+                attr = GetFileAttributesW(path);
+                ok(attr == INVALID_FILE_ATTRIBUTES, "Line %d: cannot 
delete\n", lineno);
+                break;
+            case EAT_CHECK_EXIST:
+                attr = GetFileAttributesW(path);
+                ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: attr was 
0x%08lX\n", lineno, attr);
+                break;
+            case EAT_CHECK_NON_EXIST:
+                attr = GetFileAttributesW(path);
+                ok(attr == INVALID_FILE_ATTRIBUTES, "Line %d: attr was 
0x%08lX\n", lineno, attr);
+                break;
+            case EAT_CALL:
+                ret = (*s_pDelNodeW)(path, entry->flags);
+                ok(ret == entry->ret, "Line %d: ret:%d, path:%S, 
flags:0x%08lX\n",
+                   lineno, ret, path, entry->flags);
+                break;
+        }
+    }
+
+    cleanupW();
+}
+
+START_TEST(DelNode)
+{
+    s_hAdvPack = LoadLibraryA("advpack.dll");
+    if (s_hAdvPack == NULL)
+    {
+        skip("unable to load advpack.dll\n");
+        return;
+    }
+
+    /* DelNodeA */
+    s_pDelNodeA = (DELNODEA)GetProcAddress(s_hAdvPack, "DelNodeA");
+    if (s_pDelNodeA)
+    {
+        Test_DelNodeA();
+    }
+    else
+    {
+        skip("DelNodeA not found in advpack.dll\n");
+    }
+
+    /* DelNodeW */
+    s_pDelNodeW = (DELNODEW)GetProcAddress(s_hAdvPack, "DelNodeW");
+    if (s_pDelNodeW)
+    {
+        Test_DelNodeW();
+    }
+    else
+    {
+        skip("DelNodeW not found in advpack.dll\n");
+    }
+
+    FreeLibrary(s_hAdvPack);
+    s_hAdvPack = NULL;
+}
diff --git a/modules/rostests/apitests/advpack/testlist.c 
b/modules/rostests/apitests/advpack/testlist.c
new file mode 100644
index 00000000000..281dac8b345
--- /dev/null
+++ b/modules/rostests/apitests/advpack/testlist.c
@@ -0,0 +1,18 @@
+/*
+ * PROJECT:     ReactOS API tests
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Test for advpack.dll functions
+ * COPYRIGHT:   Copyright 2023 Katayama Hirofumi MZ 
<[email protected]>
+ */
+
+#define __ROS_LONG64__
+#define STANDALONE
+#include <apitest.h>
+
+extern void func_DelNode(void);
+
+const struct test winetest_testlist[] =
+{
+    { "DelNode", func_DelNode },
+    { 0, 0 }
+};

Reply via email to