For React Native.
From: Zhiyi Zhang zzhang@codeweavers.com
The last parameter of PRTL_GENERIC_ALLOCATE_ROUTINE should be CLONG instead of LONG. --- include/ddk/ntddk.h | 2 +- include/ntdef.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h index 33cb709d172..67e867f45b7 100644 --- a/include/ddk/ntddk.h +++ b/include/ddk/ntddk.h @@ -195,7 +195,7 @@ FORCEINLINE void RtlInsertAsRightChild(PRTL_SPLAY_LINKS parent, PRTL_SPLAY_LINKS struct _RTL_GENERIC_TABLE;
typedef RTL_GENERIC_COMPARE_RESULTS (WINAPI *PRTL_GENERIC_COMPARE_ROUTINE)(struct _RTL_GENERIC_TABLE *, void *, void *); -typedef void * (__WINE_ALLOC_SIZE(2) WINAPI *PRTL_GENERIC_ALLOCATE_ROUTINE)(struct _RTL_GENERIC_TABLE *, LONG); +typedef void * (__WINE_ALLOC_SIZE(2) WINAPI *PRTL_GENERIC_ALLOCATE_ROUTINE)(struct _RTL_GENERIC_TABLE *, CLONG); typedef void (WINAPI *PRTL_GENERIC_FREE_ROUTINE)(struct _RTL_GENERIC_TABLE *Table, void *);
typedef struct _RTL_GENERIC_TABLE diff --git a/include/ntdef.h b/include/ntdef.h index e840bd3f9fe..a7ebd5cbb5a 100644 --- a/include/ntdef.h +++ b/include/ntdef.h @@ -62,6 +62,9 @@ typedef unsigned int ULONG, *PULONG; #endif #endif
+typedef ULONG CLONG; +typedef CLONG *PCLONG; + typedef struct _RTL_BALANCED_NODE { union
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/ntdll/tests/rtl.c | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index fa887421233..2acca39e519 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -108,6 +108,9 @@ static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExW)(PCWSTR, struct in6_addr *, static BOOL (WINAPI *pRtlIsCriticalSectionLocked)(CRITICAL_SECTION *); static BOOL (WINAPI *pRtlIsCriticalSectionLockedByThread)(CRITICAL_SECTION *); static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, ULONG, ULONG); +static void (WINAPI *pRtlInitializeGenericTable)(RTL_GENERIC_TABLE *, PRTL_GENERIC_COMPARE_ROUTINE, + PRTL_GENERIC_ALLOCATE_ROUTINE, PRTL_GENERIC_FREE_ROUTINE, + void *); static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char *); static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *); static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **); @@ -169,6 +172,7 @@ static void InitFunctionPtrs(void) pRtlIsCriticalSectionLocked = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLocked"); pRtlIsCriticalSectionLockedByThread = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLockedByThread"); pRtlInitializeCriticalSectionEx = (void *)GetProcAddress(hntdll, "RtlInitializeCriticalSectionEx"); + pRtlInitializeGenericTable = (void *)GetProcAddress(hntdll, "RtlInitializeGenericTable"); pRtlFindExportedRoutineByName = (void *)GetProcAddress(hntdll, "RtlFindExportedRoutineByName"); pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules"); pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification"); @@ -4846,6 +4850,53 @@ static void test_RtlDelete(void) ok(root == NULL, "Got unexpected root.\n"); }
+static RTL_GENERIC_COMPARE_RESULTS WINAPI generic_compare_proc(RTL_GENERIC_TABLE *table, void *p1, void *p2) +{ + int *value1 = p1, *value2 = p2; + + if (*value1 < *value2) + return GenericLessThan; + else if (*value1 > *value2) + return GenericGreaterThan; + else + return GenericEqual; +} + +static void * WINAPI generic_allocate_proc(RTL_GENERIC_TABLE *table, CLONG size) +{ + return malloc(size); +} + +static void WINAPI generic_free_proc(RTL_GENERIC_TABLE *table, void *ptr) +{ + free(ptr); +} + +static void test_RtlInitializeGenericTable(void) +{ + RTL_GENERIC_TABLE table; + + if (!pRtlInitializeGenericTable) + { + win_skip("RtlInitializeGenericTable is unavailable.\n"); + return; + } + + memset(&table, 0xff, sizeof(table)); + pRtlInitializeGenericTable(&table, generic_compare_proc, generic_allocate_proc, + generic_free_proc, (void *)0xdeadbeef); + ok(!table.TableRoot, "Got unexpected TableRoot.\n"); + ok(table.InsertOrderList.Flink == &table.InsertOrderList, "Got unexpected InsertOrderList.Flink.\n"); + ok(table.InsertOrderList.Blink == &table.InsertOrderList, "Got unexpected InsertOrderList.Blink.\n"); + ok(table.OrderedPointer == &table.InsertOrderList, "Got unexpected OrderedPointer.\n"); + ok(!table.NumberGenericTableElements, "Got unexpected NumberGenericTableElements.\n"); + ok(!table.WhichOrderedElement, "Got unexpected WhichOrderedElement.\n"); + ok(table.CompareRoutine == generic_compare_proc, "Got unexpected CompareRoutine.\n"); + ok(table.AllocateRoutine == generic_allocate_proc, "Got unexpected AllocateRoutine.\n"); + ok(table.FreeRoutine == generic_free_proc, "Got unexpected FreeRoutine.\n"); + ok(table.TableContext == (void *)0xdeadbeef, "Got unexpected TableContext.\n"); +} + START_TEST(rtl) { InitFunctionPtrs(); @@ -4905,4 +4956,5 @@ START_TEST(rtl) test_RtlSplay(); test_RtlDeleteNoSplay(); test_RtlDelete(); + test_RtlInitializeGenericTable(); }
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/ntdll/tests/rtl.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 2acca39e519..0625c24ef8d 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -112,6 +112,7 @@ static void (WINAPI *pRtlInitializeGenericTable)(RTL_GENERIC_TABLE *, PRTL_ PRTL_GENERIC_ALLOCATE_ROUTINE, PRTL_GENERIC_FREE_ROUTINE, void *); static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char *); +static ULONG (WINAPI *pRtlNumberGenericTableElements)(PRTL_GENERIC_TABLE); static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *); static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **); static NTSTATUS (WINAPI *pLdrUnregisterDllNotification)(void *); @@ -174,6 +175,7 @@ static void InitFunctionPtrs(void) pRtlInitializeCriticalSectionEx = (void *)GetProcAddress(hntdll, "RtlInitializeCriticalSectionEx"); pRtlInitializeGenericTable = (void *)GetProcAddress(hntdll, "RtlInitializeGenericTable"); pRtlFindExportedRoutineByName = (void *)GetProcAddress(hntdll, "RtlFindExportedRoutineByName"); + pRtlNumberGenericTableElements = (void *)GetProcAddress(hntdll, "RtlNumberGenericTableElements"); pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules"); pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification"); pLdrUnregisterDllNotification = (void *)GetProcAddress(hntdll, "LdrUnregisterDllNotification"); @@ -4897,6 +4899,22 @@ static void test_RtlInitializeGenericTable(void) ok(table.TableContext == (void *)0xdeadbeef, "Got unexpected TableContext.\n"); }
+static void test_RtlNumberGenericTableElements(void) +{ + RTL_GENERIC_TABLE table; + ULONG count; + + if (!pRtlNumberGenericTableElements) + { + win_skip("RtlNumberGenericTableElements is unavailable.\n"); + return; + } + + table.NumberGenericTableElements = 0xdeadbeef; + count = pRtlNumberGenericTableElements(&table); + ok(count == table.NumberGenericTableElements, "Got unexpected count.\n"); +} + START_TEST(rtl) { InitFunctionPtrs(); @@ -4957,4 +4975,5 @@ START_TEST(rtl) test_RtlDeleteNoSplay(); test_RtlDelete(); test_RtlInitializeGenericTable(); + test_RtlNumberGenericTableElements(); }
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/ntdll/ntdll.spec | 2 +- dlls/ntdll/rtl.c | 9 +++++++++ dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- include/ddk/ntddk.h | 1 + 4 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index ff601a1cd22..8614ecf9d47 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -855,7 +855,7 @@ @ stdcall RtlIsCurrentThread(long) @ stdcall RtlIsDosDeviceName_U(wstr) @ stdcall -arch=x86_64 -norelay RtlIsEcCode(ptr) -@ stub RtlIsGenericTableEmpty +@ stdcall RtlIsGenericTableEmpty(ptr) # @ stub RtlIsGenericTableEmptyAvl @ stdcall RtlIsNameLegalDOS8Dot3(ptr ptr ptr) @ stdcall RtlIsNormalizedString(long wstr long ptr) diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index 8a77b321797..ee330482162 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -547,6 +547,15 @@ void WINAPI RtlInitializeGenericTable(RTL_GENERIC_TABLE *table, PRTL_GENERIC_COM table->TableContext = context; }
+/****************************************************************************** + * RtlIsGenericTableEmpty [NTDLL.@] + */ +BOOLEAN WINAPI RtlIsGenericTableEmpty(RTL_GENERIC_TABLE *table) +{ + TRACE("(%p)\n", table); + return !table->TableRoot; +} + /****************************************************************************** * RtlEnumerateGenericTableWithoutSplaying [NTDLL.@] */ diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 12382313af2..57a947ea821 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -1176,7 +1176,7 @@ @ stdcall RtlIpv6StringToAddressExA(str ptr ptr ptr) @ stdcall RtlIpv6StringToAddressExW(wstr ptr ptr ptr) @ stdcall RtlIpv6StringToAddressW(wstr ptr ptr) -@ stub RtlIsGenericTableEmpty +@ stdcall RtlIsGenericTableEmpty(ptr) @ stub RtlIsGenericTableEmptyAvl @ stdcall RtlIsNameLegalDOS8Dot3(ptr ptr ptr) @ stdcall RtlIsNormalizedString(long wstr long ptr) diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h index 67e867f45b7..67198da2f3d 100644 --- a/include/ddk/ntddk.h +++ b/include/ddk/ntddk.h @@ -309,6 +309,7 @@ void * WINAPI RtlGetElementGenericTable(PRTL_GENERIC_TABLE,ULONG); void WINAPI RtlInitializeGenericTable(PRTL_GENERIC_TABLE,PRTL_GENERIC_COMPARE_ROUTINE,PRTL_GENERIC_ALLOCATE_ROUTINE,PRTL_GENERIC_FREE_ROUTINE,void *); void WINAPI RtlInitializeGenericTableAvl(PRTL_AVL_TABLE,PRTL_AVL_COMPARE_ROUTINE,PRTL_AVL_ALLOCATE_ROUTINE, PRTL_AVL_FREE_ROUTINE,void *); void WINAPI RtlInsertElementGenericTableAvl(PRTL_AVL_TABLE,void *,ULONG,BOOL*); +BOOLEAN WINAPI RtlIsGenericTableEmpty(PRTL_GENERIC_TABLE); void * WINAPI RtlLookupElementGenericTable(PRTL_GENERIC_TABLE,void *); void * WINAPI RtlLookupElementGenericTableAvl(PRTL_AVL_TABLE,void *); void WINAPI RtlMapGenericMask(ACCESS_MASK*,const GENERIC_MAPPING*);
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/ntdll/tests/rtl.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 0625c24ef8d..05a27ec6b2c 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -107,6 +107,7 @@ static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExA)(PCSTR, struct in6_addr *, static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExW)(PCWSTR, struct in6_addr *, PULONG, PUSHORT); static BOOL (WINAPI *pRtlIsCriticalSectionLocked)(CRITICAL_SECTION *); static BOOL (WINAPI *pRtlIsCriticalSectionLockedByThread)(CRITICAL_SECTION *); +static BOOLEAN (WINAPI *pRtlIsGenericTableEmpty)(PRTL_GENERIC_TABLE); static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, ULONG, ULONG); static void (WINAPI *pRtlInitializeGenericTable)(RTL_GENERIC_TABLE *, PRTL_GENERIC_COMPARE_ROUTINE, PRTL_GENERIC_ALLOCATE_ROUTINE, PRTL_GENERIC_FREE_ROUTINE, @@ -172,6 +173,7 @@ static void InitFunctionPtrs(void) pRtlIpv6StringToAddressExW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExW"); pRtlIsCriticalSectionLocked = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLocked"); pRtlIsCriticalSectionLockedByThread = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLockedByThread"); + pRtlIsGenericTableEmpty = (void *)GetProcAddress(hntdll, "RtlIsGenericTableEmpty"); pRtlInitializeCriticalSectionEx = (void *)GetProcAddress(hntdll, "RtlInitializeCriticalSectionEx"); pRtlInitializeGenericTable = (void *)GetProcAddress(hntdll, "RtlInitializeGenericTable"); pRtlFindExportedRoutineByName = (void *)GetProcAddress(hntdll, "RtlFindExportedRoutineByName"); @@ -4915,6 +4917,29 @@ static void test_RtlNumberGenericTableElements(void) ok(count == table.NumberGenericTableElements, "Got unexpected count.\n"); }
+static void test_RtlIsGenericTableEmpty(void) +{ + RTL_GENERIC_TABLE table; + BOOLEAN empty; + + if (!pRtlIsGenericTableEmpty) + { + win_skip("RtlIsGenericTableEmpty is unavailable.\n"); + return; + } + + /* Test that RtlIsGenericTableEmpty() uses TableRoot to check if a generic table is empty */ + table.TableRoot = NULL; + table.NumberGenericTableElements = 1; + empty = pRtlIsGenericTableEmpty(&table); + ok(empty, "Expected empty.\n"); + + table.TableRoot = (RTL_SPLAY_LINKS *)1; + table.NumberGenericTableElements = 0; + empty = pRtlIsGenericTableEmpty(&table); + ok(!empty, "Expected not empty.\n"); +} + START_TEST(rtl) { InitFunctionPtrs(); @@ -4976,4 +5001,5 @@ START_TEST(rtl) test_RtlDelete(); test_RtlInitializeGenericTable(); test_RtlNumberGenericTableElements(); + test_RtlIsGenericTableEmpty(); }