diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index c0708c65b56..994ff6f215a 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 755cc6e5967..2e459b2d3ca 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 d2e03173159..4f75cc2454a 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"); }