https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f4b7087a0e3c047c8a79b…
commit f4b7087a0e3c047c8a79b8c567f7b21c12d70375
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Thu Apr 27 20:35:41 2023 +0900
Commit: GitHub <noreply(a)github.com>
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
<katayama.hirofumi.mz(a)gmail.com>
+ */
+#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
<katayama.hirofumi.mz(a)gmail.com>
+ */
+
+#define __ROS_LONG64__
+#define STANDALONE
+#include <apitest.h>
+
+extern void func_DelNode(void);
+
+const struct test winetest_testlist[] =
+{
+ { "DelNode", func_DelNode },
+ { 0, 0 }
+};