Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ntdll/tests/exception.c | 147 ++++++++++++++++++++++++----------- 1 file changed, 102 insertions(+), 45 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 3b3f72f07d..d2e0317315 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -56,6 +56,21 @@ static NTSTATUS (WINAPI *pNtClose)(HANDLE); static NTSTATUS (WINAPI *pNtSuspendProcess)(HANDLE process); static NTSTATUS (WINAPI *pNtResumeProcess)(HANDLE process);
+#define RTL_UNLOAD_EVENT_TRACE_NUMBER 64 + +typedef struct _RTL_UNLOAD_EVENT_TRACE +{ + void *BaseAddress; + SIZE_T SizeOfImage; + ULONG Sequence; + ULONG TimeDateStamp; + ULONG CheckSum; + WCHAR ImageName[32]; +} RTL_UNLOAD_EVENT_TRACE, *PRTL_UNLOAD_EVENT_TRACE; + +static RTL_UNLOAD_EVENT_TRACE *(WINAPI *pRtlGetUnloadEventTrace)(void); +static void (WINAPI *pRtlGetUnloadEventTraceEx)(ULONG **element_size, ULONG **element_count, void **event_trace); + #if defined(__x86_64__) typedef struct { @@ -3325,6 +3340,53 @@ static void test_suspend_process(void) CloseHandle(event2); }
+static void test_unload_trace(void) +{ + static const WCHAR imageW[] = {'m','s','x','m','l','3','.','d','l','l',0}; + RTL_UNLOAD_EVENT_TRACE *unload_trace, *ptr; + ULONG *element_size, *element_count, size; + BOOL found = FALSE; + HMODULE hmod; + + unload_trace = pRtlGetUnloadEventTrace(); +todo_wine + ok(unload_trace != NULL, "Failed to get unload events pointer.\n"); + + if (pRtlGetUnloadEventTraceEx) + { + ptr = NULL; + pRtlGetUnloadEventTraceEx(&element_size, &element_count, (void **)&ptr); + todo_wine { + ok(*element_size >= sizeof(*ptr), "Unexpected element size.\n"); + ok(*element_count == RTL_UNLOAD_EVENT_TRACE_NUMBER, "Unexpected trace element count %u.\n", *element_count); + ok(ptr != NULL, "Unexpected pointer %p.\n", ptr); + } + size = *element_size; + } + else + size = sizeof(*unload_trace); + + hmod = LoadLibraryA("msxml3.dll"); + ok(hmod != NULL, "Failed to load library.\n"); + FreeLibrary(hmod); + +if (unload_trace) +{ + ptr = unload_trace; + while (ptr->BaseAddress != NULL) + { + if (!lstrcmpW(imageW, ptr->ImageName)) + { + found = TRUE; + break; + } + ptr = (RTL_UNLOAD_EVENT_TRACE *)((char *)ptr + size); + } +} +todo_wine + ok(found, "Unloaded module wasn't found.\n"); +} + START_TEST(exception) { HMODULE hntdll = GetModuleHandleA("ntdll.dll"); @@ -3346,29 +3408,28 @@ START_TEST(exception) return; }
- pNtGetContextThread = (void *)GetProcAddress( hntdll, "NtGetContextThread" ); - pNtSetContextThread = (void *)GetProcAddress( hntdll, "NtSetContextThread" ); - pNtReadVirtualMemory = (void *)GetProcAddress( hntdll, "NtReadVirtualMemory" ); - pNtClose = (void *)GetProcAddress( hntdll, "NtClose" ); - pRtlUnwind = (void *)GetProcAddress( hntdll, "RtlUnwind" ); - pRtlRaiseException = (void *)GetProcAddress( hntdll, "RtlRaiseException" ); - pRtlCaptureContext = (void *)GetProcAddress( hntdll, "RtlCaptureContext" ); - pNtTerminateProcess = (void *)GetProcAddress( hntdll, "NtTerminateProcess" ); - pRtlAddVectoredExceptionHandler = (void *)GetProcAddress( hntdll, - "RtlAddVectoredExceptionHandler" ); - pRtlRemoveVectoredExceptionHandler = (void *)GetProcAddress( hntdll, - "RtlRemoveVectoredExceptionHandler" ); - pRtlAddVectoredContinueHandler = (void *)GetProcAddress( hntdll, - "RtlAddVectoredContinueHandler" ); - pRtlRemoveVectoredContinueHandler = (void *)GetProcAddress( hntdll, - "RtlRemoveVectoredContinueHandler" ); - pNtQueryInformationProcess = (void*)GetProcAddress( hntdll, - "NtQueryInformationProcess" ); - pNtSetInformationProcess = (void*)GetProcAddress( hntdll, - "NtSetInformationProcess" ); +#define X(f) p##f = (void*)GetProcAddress(hntdll, #f) + X(NtGetContextThread); + X(NtSetContextThread); + X(NtReadVirtualMemory); + X(NtClose); + X(RtlUnwind); + X(RtlRaiseException); + X(RtlCaptureContext); + X(NtTerminateProcess); + X(RtlAddVectoredExceptionHandler); + X(RtlRemoveVectoredExceptionHandler); + X(RtlAddVectoredContinueHandler); + X(RtlRemoveVectoredContinueHandler); + X(NtQueryInformationProcess); + X(NtSetInformationProcess); + X(NtSuspendProcess); + X(NtResumeProcess); + X(RtlGetUnloadEventTrace); + X(RtlGetUnloadEventTraceEx); +#undef X + pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); - pNtSuspendProcess = (void *)GetProcAddress( hntdll, "NtSuspendProcess" ); - pNtResumeProcess = (void *)GetProcAddress( hntdll, "NtResumeProcess" );
#ifdef __i386__ if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE; @@ -3455,31 +3516,26 @@ START_TEST(exception) test_thread_context(); test_suspend_thread(); test_suspend_process(); + test_unload_trace();
#elif defined(__x86_64__) - pRtlAddFunctionTable = (void *)GetProcAddress( hntdll, - "RtlAddFunctionTable" ); - pRtlDeleteFunctionTable = (void *)GetProcAddress( hntdll, - "RtlDeleteFunctionTable" ); - pRtlInstallFunctionTableCallback = (void *)GetProcAddress( hntdll, - "RtlInstallFunctionTableCallback" ); - pRtlLookupFunctionEntry = (void *)GetProcAddress( hntdll, - "RtlLookupFunctionEntry" ); - pRtlAddGrowableFunctionTable = (void *)GetProcAddress( hntdll, "RtlAddGrowableFunctionTable" ); - pRtlGrowFunctionTable = (void *)GetProcAddress( hntdll, "RtlGrowFunctionTable" ); - pRtlDeleteGrowableFunctionTable = (void *)GetProcAddress( hntdll, "RtlDeleteGrowableFunctionTable" ); - p__C_specific_handler = (void *)GetProcAddress( hntdll, - "__C_specific_handler" ); - pRtlCaptureContext = (void *)GetProcAddress( hntdll, - "RtlCaptureContext" ); - pRtlRestoreContext = (void *)GetProcAddress( hntdll, - "RtlRestoreContext" ); - pRtlUnwindEx = (void *)GetProcAddress( hntdll, - "RtlUnwindEx" ); - pRtlWow64GetThreadContext = (void *)GetProcAddress( hntdll, - "RtlWow64GetThreadContext" ); - pRtlWow64SetThreadContext = (void *)GetProcAddress( hntdll, - "RtlWow64SetThreadContext" ); + +#define X(f) p##f = (void*)GetProcAddress(hntdll, #f) + X(RtlAddFunctionTable); + X(RtlDeleteFunctionTable); + X(RtlInstallFunctionTableCallback); + X(RtlLookupFunctionEntry); + X(RtlAddGrowableFunctionTable); + X(RtlGrowFunctionTable); + X(RtlDeleteGrowableFunctionTable); + X(__C_specific_handler); + X(RtlCaptureContext); + X(RtlRestoreContext); + X(RtlUnwindEx); + X(RtlWow64GetThreadContext); + X(RtlWow64SetThreadContext); +#undef X + p_setjmp = (void *)GetProcAddress( hmsvcrt, "_setjmp" );
@@ -3498,6 +3554,7 @@ START_TEST(exception) test_wow64_context(); test_suspend_thread(); test_suspend_process(); + test_unload_trace();
if (pRtlAddFunctionTable && pRtlDeleteFunctionTable && pRtlInstallFunctionTableCallback && pRtlLookupFunctionEntry) test_dynamic_unwind();
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/ntdll/loader.c | 53 ++++++++++++++++++++++++++++++++++++ dlls/ntdll/rtl.c | 33 ---------------------- dlls/ntdll/tests/exception.c | 7 ----- 3 files changed, 53 insertions(+), 40 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index c0708c65b5..994ff6f215 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -159,6 +159,57 @@ static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len ) while (len--) *dst++ = (unsigned char)*src++; }
+#define RTL_UNLOAD_EVENT_TRACE_NUMBER 64 + +typedef struct _RTL_UNLOAD_EVENT_TRACE +{ + void *BaseAddress; + SIZE_T SizeOfImage; + ULONG Sequence; + ULONG TimeDateStamp; + ULONG CheckSum; + WCHAR ImageName[32]; +} RTL_UNLOAD_EVENT_TRACE, *PRTL_UNLOAD_EVENT_TRACE; + +static RTL_UNLOAD_EVENT_TRACE unload_traces[RTL_UNLOAD_EVENT_TRACE_NUMBER]; +static unsigned int unload_trace_seq; + +static void module_push_unload_trace( const LDR_MODULE *ldr ) +{ + RTL_UNLOAD_EVENT_TRACE *ptr = &unload_traces[unload_trace_seq]; + unsigned int len = min(sizeof(ptr->ImageName), ldr->BaseDllName.Length); + + ptr->BaseAddress = ldr->BaseAddress; + ptr->SizeOfImage = ldr->SizeOfImage; + ptr->Sequence = unload_trace_seq; + ptr->TimeDateStamp = ldr->TimeDateStamp; + ptr->CheckSum = ldr->CheckSum; + memcpy(ptr->ImageName, ldr->BaseDllName.Buffer, len); + ptr->ImageName[len / sizeof(*ptr->ImageName)] = 0; + + unload_trace_seq = (unload_trace_seq + 1) % ARRAY_SIZE(unload_traces); +} + +/********************************************************************* + * RtlGetUnloadEventTrace [NTDLL.@] + */ +RTL_UNLOAD_EVENT_TRACE * WINAPI RtlGetUnloadEventTrace(void) +{ + return unload_traces; +} + +/********************************************************************* + * RtlGetUnloadEventTraceEx [NTDLL.@] + */ +void WINAPI RtlGetUnloadEventTraceEx(ULONG **size, ULONG **count, void **trace) +{ + static unsigned int element_size = sizeof(*unload_traces); + static unsigned int element_count = ARRAY_SIZE(unload_traces); + + *size = &element_size; + *count = &element_count; + *trace = unload_traces; +}
/************************************************************************* * call_dll_entry_point @@ -3358,6 +3409,8 @@ static void MODULE_DecRefCount( WINE_MODREF *wm ) MODULE_DecRefCount( wm->deps[i] );
wm->ldr.Flags &= ~LDR_UNLOAD_IN_PROGRESS; + + module_push_unload_trace( &wm->ldr ); } }
diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index 755cc6e596..2e459b2d3c 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -1657,39 +1657,6 @@ void WINAPI RtlInsertElementGenericTableAvl(PRTL_AVL_TABLE table, void *buffer, FIXME("%p %p %u %p: stub\n", table, buffer, size, element); }
-typedef struct _RTL_UNLOAD_EVENT_TRACE -{ - PVOID BaseAddress; - SIZE_T SizeOfImage; - ULONG Sequence; - ULONG TimeDateStamp; - ULONG CheckSum; - WCHAR ImageName[32]; -} RTL_UNLOAD_EVENT_TRACE, *PRTL_UNLOAD_EVENT_TRACE; - -/********************************************************************* - * RtlGetUnloadEventTrace [NTDLL.@] - */ -RTL_UNLOAD_EVENT_TRACE * WINAPI RtlGetUnloadEventTrace(void) -{ - FIXME("stub!\n"); - return NULL; -} - -/********************************************************************* - * RtlGetUnloadEventTraceEx [NTDLL.@] - */ -void WINAPI RtlGetUnloadEventTraceEx(ULONG **size, ULONG **count, void **trace) -{ - static ULONG dummy_size, dummy_count; - - FIXME("(%p, %p, %p): stub!\n", size, count, trace); - - if (size) *size = &dummy_size; - if (count) *count = &dummy_count; - if (trace) *trace = NULL; -} - /********************************************************************* * RtlQueryPackageIdentity [NTDLL.@] */ diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index d2e0317315..4f75cc2454 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -3349,18 +3349,15 @@ static void test_unload_trace(void) HMODULE hmod;
unload_trace = pRtlGetUnloadEventTrace(); -todo_wine ok(unload_trace != NULL, "Failed to get unload events pointer.\n");
if (pRtlGetUnloadEventTraceEx) { ptr = NULL; pRtlGetUnloadEventTraceEx(&element_size, &element_count, (void **)&ptr); - todo_wine { ok(*element_size >= sizeof(*ptr), "Unexpected element size.\n"); ok(*element_count == RTL_UNLOAD_EVENT_TRACE_NUMBER, "Unexpected trace element count %u.\n", *element_count); ok(ptr != NULL, "Unexpected pointer %p.\n", ptr); - } size = *element_size; } else @@ -3370,8 +3367,6 @@ todo_wine ok(hmod != NULL, "Failed to load library.\n"); FreeLibrary(hmod);
-if (unload_trace) -{ ptr = unload_trace; while (ptr->BaseAddress != NULL) { @@ -3382,8 +3377,6 @@ if (unload_trace) } ptr = (RTL_UNLOAD_EVENT_TRACE *)((char *)ptr + size); } -} -todo_wine ok(found, "Unloaded module wasn't found.\n"); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=51336
Your paranoid android.
=== debian9 (32 bit WoW report) ===
ntdll: om.c:2116: Test failed: got 99 om.c:2131: Test failed: got 99 om.c:2131: Test failed: got 99