From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/ntdll/tests/rtl.c | 181 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+)
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 2f7a1d4cdc0..fa887421233 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -89,6 +89,7 @@ __ASM_STDCALL_FUNC( wrap_fastcall_func1, 8,
/* Function ptrs for ntdll calls */ static HMODULE hntdll = 0; +static PRTL_SPLAY_LINKS (WINAPI *pRtlDelete)(PRTL_SPLAY_LINKS); static void (WINAPI *pRtlDeleteNoSplay)(PRTL_SPLAY_LINKS, PRTL_SPLAY_LINKS *); static VOID (WINAPI *pRtlMoveMemory)(LPVOID,LPCVOID,SIZE_T); static VOID (WINAPI *pRtlFillMemory)(LPVOID,SIZE_T,BYTE); @@ -149,6 +150,7 @@ static void InitFunctionPtrs(void) hntdll = LoadLibraryA("ntdll.dll"); ok(hntdll != 0, "LoadLibrary failed\n"); if (hntdll) { + pRtlDelete = (void *)GetProcAddress(hntdll, "RtlDelete"); pRtlDeleteNoSplay = (void *)GetProcAddress(hntdll, "RtlDeleteNoSplay"); pRtlMoveMemory = (void *)GetProcAddress(hntdll, "RtlMoveMemory"); pRtlFillMemory = (void *)GetProcAddress(hntdll, "RtlFillMemory"); @@ -4666,6 +4668,184 @@ static void test_RtlDeleteNoSplay(void) ok(root == NULL, "Got unexpected root.\n"); }
+static void test_RtlDelete(void) +{ + /* 3 + * / \ + * 1 5 + * / \ / \ + * 0 2 4 6 + */ + static const struct splay_index splay_indices[] = + { + {3, 1, 5}, + {1, 0, 2}, + {5, 4, 6}, + {0, -1, -1}, + {2, -1, -1}, + {4, -1, -1}, + {6, -1, -1}, + }; + /* 1 + * \ + * 3 + * / \ + * 2 5 + * / \ + * 4 6 + */ + static const struct splay_index delete0[] = + { + {1, -1, 3}, + {3, 2, 5}, + {5, 4, 6}, + {2, -1, -1}, + {4, -1, -1}, + {6, -1, -1}, + }; + /* 0 + * \ + * 3 + * / \ + * 2 5 + * / \ + * 4 6 + */ + static const struct splay_index delete1[] = + { + {0, -1, 3}, + {3, 2, 5}, + {5, 4, 6}, + {2, -1, -1}, + {4, -1, -1}, + {6, -1, -1}, + }; + /* 1 + * / \ + * 0 3 + * \ + * 5 + * / \ + * 4 6 + */ + static const struct splay_index delete2[] = + { + {1, 0, 3}, + {3, -1, 5}, + {5, 4, 6}, + {0, -1, -1}, + {4, -1, -1}, + {6, -1, -1}, + }; + /* 1 + * / \ + * 0 2 + * \ + * 5 + * / \ + * 4 6 + */ + static const struct splay_index delete3[] = + { + {1, 0, 2}, + {2, -1, 5}, + {5, 4, 6}, + {0, -1, -1}, + {4, -1, -1}, + {6, -1, -1}, + }; + /* 5 + * / \ + * 3 6 + * / + * 1 + * / \ + * 0 2 + */ + static const struct splay_index delete4[] = + { + {5, 3, 6}, + {3, 1, -1}, + {1, 0, 2}, + {0, -1, -1}, + {2, -1, -1}, + {6, -1, -1}, + }; + /* 4 + * / \ + * 3 6 + * / + * 1 + * / \ + * 0 2 + */ + static const struct splay_index delete5[] = + { + {4, 3, 6}, + {3, 1, -1}, + {1, 0, 2}, + {0, -1, -1}, + {2, -1, -1}, + {6, -1, -1}, + }; + /* 5 + * / + * 3 + * / \ + * 1 4 + * / \ + * 0 2 + */ + static const struct splay_index delete6[] = + { + {5, 3, -1}, + {3, 1, 4}, + {1, 0, 2}, + {0, -1, -1}, + {2, -1, -1}, + {4, -1, -1}, + }; + RTL_SPLAY_LINKS links[7], *root; + static const struct + { + const struct splay_index *indices; + unsigned int index_count; + } + expected_indices[] = + { + {delete0, ARRAY_SIZE(delete0)}, + {delete1, ARRAY_SIZE(delete1)}, + {delete2, ARRAY_SIZE(delete2)}, + {delete3, ARRAY_SIZE(delete3)}, + {delete4, ARRAY_SIZE(delete4)}, + {delete5, ARRAY_SIZE(delete5)}, + {delete6, ARRAY_SIZE(delete6)}, + }; + unsigned int i; + + if (!pRtlDelete) + { + win_skip("RtlDelete is unavailable.\n"); + return; + } + for (i = 0; i < ARRAY_SIZE(expected_indices); i++) + { + winetest_push_context("%d", i); + + init_splay_indices(links, ARRAY_SIZE(links), splay_indices, ARRAY_SIZE(splay_indices)); + + root = pRtlDelete(&links[i]); + expect_splay_indices(links, root, expected_indices[i].indices, expected_indices[i].index_count); + + winetest_pop_context(); + } + + /* Test that root should be NULL when the splay tree is empty */ + RtlInitializeSplayLinks(&links[0]); + root = pRtlDelete(&links[0]); + ok(root == NULL, "Got unexpected root.\n"); +} + START_TEST(rtl) { InitFunctionPtrs(); @@ -4724,4 +4904,5 @@ START_TEST(rtl) test_RtlRealSuccessor(); test_RtlSplay(); test_RtlDeleteNoSplay(); + test_RtlDelete(); }