Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2018
- 68 participants
- 1149 messages
Re: [PATCH] oleaut32: Correct some comments.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 21, 2018
Re: [PATCH v8 5/9] ntdll: Return BIOS info from NtQuerySystemInformation on Linux
by Marvin
Hi,
While running your changed tests on Windows, 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=39269
Your paranoid android.
=== wxppro (32 bit info) ===
The task timed out
June 21, 2018
[PATCH] ntdll: Implement LdrRegisterDllNotification and LdrUnregisterDllNotification.
by Alistair Leslie-Hughes
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/ntdll/loader.c | 75 +++++++++++++-
dlls/ntdll/tests/rtl.c | 261 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 332 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 3e00ec6..cae9b25 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -40,6 +40,7 @@
#include "wine/library.h"
#include "wine/unicode.h"
#include "wine/debug.h"
+#include "wine/list.h"
#include "wine/server.h"
#include "ntdll_misc.h"
#include "ddk/wdm.h"
@@ -71,6 +72,13 @@ static BOOL imports_fixup_done = FALSE; /* set once the imports have been fixed
static BOOL process_detaching = FALSE; /* set on process detach to avoid deadlocks with thread detach */
static int free_lib_count; /* recursion depth of LdrUnloadDll calls */
+struct ldr_notification
+{
+ struct list entry;
+ PLDR_DLL_NOTIFICATION_FUNCTION callback;
+ void *context;
+};
+
static const char * const reason_names[] =
{
"PROCESS_DETACH",
@@ -342,6 +350,29 @@ static ULONG_PTR allocate_stub( const char *dll, const char *name )
static inline ULONG_PTR allocate_stub( const char *dll, const char *name ) { return 0xdeadbeef; }
#endif /* __i386__ */
+/* call ldr notifications */
+static void call_ldr_notifications( ULONG reason, LDR_MODULE *module )
+{
+ struct ldr_notification *notify, *notify_next;
+ LDR_DLL_NOTIFICATION_DATA data;
+
+ data.Loaded.Flags = 0;
+ data.Loaded.FullDllName = &module->FullDllName;
+ data.Loaded.BaseDllName = &module->BaseDllName;
+ data.Loaded.DllBase = module->BaseAddress;
+ data.Loaded.SizeOfImage = module->SizeOfImage;
+
+ LIST_FOR_EACH_ENTRY_SAFE( notify, notify_next, &ldr_notifications, struct ldr_notification, entry )
+ {
+ TRACE_(relay)("\1Call LDR notification callback (proc=%p,reason=%u,data=%p,context=%p)\n",
+ notify->callback, reason, &data, notify->context );
+
+ notify->callback(reason, &data, notify->context);
+
+ TRACE_(relay)("\1Ret LDR notification callback (proc=%p,reason=%u,data=%p,context=%p)\n",
+ notify->callback, reason, &data, notify->context );
+ }
+}
/*************************************************************************
* get_modref
@@ -1275,12 +1306,18 @@ static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved )
{
WINE_MODREF *prev = current_modref;
current_modref = wm;
+
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_LOADED, &wm->ldr );
status = MODULE_InitDLL( wm, DLL_PROCESS_ATTACH, lpReserved );
if (status == STATUS_SUCCESS)
+ {
wm->ldr.Flags |= LDR_PROCESS_ATTACHED;
+ }
else
{
MODULE_InitDLL( wm, DLL_PROCESS_DETACH, lpReserved );
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_UNLOADED, &wm->ldr );
+
/* point to the name so LdrInitializeThunk can print it */
last_failed_modref = wm;
WARN("Initialization of %s failed\n", debugstr_w(wm->ldr.BaseDllName.Buffer));
@@ -1353,6 +1390,7 @@ static void process_detach(void)
mod->Flags &= ~LDR_PROCESS_ATTACHED;
MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr),
DLL_PROCESS_DETACH, ULongToPtr(process_detaching) );
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_UNLOADED, mod );
/* Restart at head of WINE_MODREF list, as entries might have
been added and/or removed while performing the call ... */
@@ -1467,8 +1505,27 @@ NTSTATUS WINAPI LdrEnumerateLoadedModules( void *unknown, LDRENUMPROC callback,
NTSTATUS WINAPI LdrRegisterDllNotification(ULONG flags, PLDR_DLL_NOTIFICATION_FUNCTION callback,
void *context, void **cookie)
{
- FIXME( "(%04x, %p, %p, %p) stub\n", flags, callback, context, cookie );
- return STATUS_NOT_IMPLEMENTED;
+ struct ldr_notification *notify;
+
+ TRACE( "(%x, %p, %p, %p)\n", flags, callback, context, cookie );
+
+ if (!callback || !cookie)
+ return STATUS_INVALID_PARAMETER;
+
+ if (flags)
+ FIXME( "ignoring flags %x\n", flags );
+
+ notify = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*notify) );
+ if (!notify) return STATUS_NO_MEMORY;
+ notify->callback = callback;
+ notify->context = context;
+
+ RtlEnterCriticalSection( &loader_section );
+ list_add_tail( &ldr_notifications, ¬ify->entry );
+ RtlLeaveCriticalSection( &loader_section );
+
+ *cookie = notify;
+ return STATUS_SUCCESS;
}
/******************************************************************
@@ -1476,8 +1533,18 @@ NTSTATUS WINAPI LdrRegisterDllNotification(ULONG flags, PLDR_DLL_NOTIFICATION_FU
*/
NTSTATUS WINAPI LdrUnregisterDllNotification( void *cookie )
{
- FIXME( "(%p) stub\n", cookie );
- return STATUS_NOT_IMPLEMENTED;
+ struct ldr_notification *notify = cookie;
+
+ TRACE( "(%p)\n", cookie );
+
+ if (!notify) return STATUS_INVALID_PARAMETER;
+
+ RtlEnterCriticalSection( &loader_section );
+ list_remove( ¬ify->entry );
+ RtlLeaveCriticalSection( &loader_section );
+
+ RtlFreeHeap( GetProcessHeap(), 0, notify );
+ return STATUS_SUCCESS;
}
/******************************************************************
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index 2e3a7de..1a9e313 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -101,6 +101,8 @@ static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, U
static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *);
static NTSTATUS (WINAPI *pRtlMakeSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
static NTSTATUS (WINAPI *pRtlAbsoluteToSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PULONG);
+static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **);
+static NTSTATUS (WINAPI *pLdrUnregisterDllNotification)(void *);
static HMODULE hkernel32 = 0;
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
@@ -108,10 +110,15 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
#define LEN 16
static const char* src_src = "This is a test!"; /* 16 bytes long, incl NUL */
+static WCHAR ws2_32dllW[] = {'w','s','2','_','3','2','.','d','l','l',0};
+static WCHAR nsidllW[] = {'n','s','i','.','d','l','l',0};
+static WCHAR wintrustdllW[] = {'w','i','n','t','r','u','s','t','.','d','l','l',0};
+static WCHAR crypt32dllW[] = {'c','r','y','p','t','3','2','.','d','l','l',0};
static ULONG src_aligned_block[4];
static ULONG dest_aligned_block[32];
static const char *src = (const char*)src_aligned_block;
static char* dest = (char*)dest_aligned_block;
+const WCHAR *expected_dll = nsidllW;
static void InitFunctionPtrs(void)
{
@@ -157,6 +164,8 @@ static void InitFunctionPtrs(void)
pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules");
pRtlMakeSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlMakeSelfRelativeSD");
pRtlAbsoluteToSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlAbsoluteToSelfRelativeSD");
+ pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification");
+ pLdrUnregisterDllNotification = (void *)GetProcAddress(hntdll, "LdrUnregisterDllNotification");
}
hkernel32 = LoadLibraryA("kernel32.dll");
ok(hkernel32 != 0, "LoadLibrary failed\n");
@@ -2259,6 +2268,257 @@ static void test_RtlMakeSelfRelativeSD(void)
ok( status == STATUS_BAD_DESCRIPTOR_FORMAT, "got %08x\n", status );
}
+static DWORD (CALLBACK *orig_entry)(HMODULE,DWORD,LPVOID);
+static DWORD *dll_main_data;
+
+static inline void *get_rva( HMODULE module, DWORD va )
+{
+ return (void *)((char *)module + va);
+}
+
+static void CALLBACK ldr_notify_callback1(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ const IMAGE_IMPORT_DESCRIPTOR *imports;
+ const IMAGE_THUNK_DATA *import_list;
+ IMAGE_THUNK_DATA *thunk_list;
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+ ULONG size;
+ int i, j;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, expected_dll))
+ return;
+
+ ok(data->Loaded.Flags == 0, "Expected flags 0, got %x\n", data->Loaded.Flags);
+ ok(!lstrcmpiW(data->Loaded.BaseDllName->Buffer, expected_dll), "Expected %s, got %s\n",
+ wine_dbgstr_w(expected_dll), wine_dbgstr_w(data->Loaded.BaseDllName->Buffer));
+ ok(!!data->Loaded.DllBase, "Expected non zero base address\n");
+ ok(data->Loaded.SizeOfImage, "Expected non zero image size\n");
+
+ /* expect module to be last module listed in LdrData load order list */
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ ok(!lstrcmpiW(mod->BaseDllName.Buffer, expected_dll), "Expected %s, got %s\n",
+ wine_dbgstr_w(expected_dll), wine_dbgstr_w(mod->BaseDllName.Buffer));
+
+ /* show that imports have already been resolved */
+ imports = RtlImageDirectoryEntryToData(data->Loaded.DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
+ ok(!!imports, "Expected dll to have imports\n");
+
+ for (i = 0; imports[i].Name; i++)
+ {
+ thunk_list = get_rva(data->Loaded.DllBase, (DWORD)imports[i].FirstThunk);
+ if (imports[i].OriginalFirstThunk)
+ import_list = get_rva(data->Loaded.DllBase, (DWORD)imports[i].OriginalFirstThunk);
+ else
+ import_list = thunk_list;
+
+ for (j = 0; import_list[j].u1.Ordinal; j++)
+ {
+ ok(thunk_list[j].u1.AddressOfData > data->Loaded.SizeOfImage,
+ "Import has not been resolved: %p\n", (void*)thunk_list[j].u1.Function);
+ }
+ }
+}
+
+static void CALLBACK ldr_notify_callback2(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ *calls <<= 4;
+ *calls |= reason + 2;
+}
+
+static BOOL WINAPI fake_dll_main(HINSTANCE instance, DWORD reason, void* reserved)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 3;
+ }
+ else if (reason == DLL_PROCESS_DETACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 4;
+ }
+ return orig_entry(instance, reason, reserved);
+}
+
+static void CALLBACK ldr_notify_callback_dll_main(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ if (mod->BaseAddress != data->Loaded.DllBase)
+ return;
+
+ orig_entry = mod->EntryPoint;
+ mod->EntryPoint = fake_dll_main;
+ dll_main_data = calls;
+}
+
+static BOOL WINAPI fake_dll_main_fail(HINSTANCE instance, DWORD reason, void* reserved)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 3;
+ }
+ else if (reason == DLL_PROCESS_DETACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 4;
+ }
+ return FALSE;
+}
+
+static void CALLBACK ldr_notify_callback_fail(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ if (mod->BaseAddress != data->Loaded.DllBase)
+ return;
+
+ orig_entry = mod->EntryPoint;
+ mod->EntryPoint = fake_dll_main_fail;
+ dll_main_data = calls;
+}
+
+static void CALLBACK ldr_notify_callback_imports(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, crypt32dllW))
+ {
+ *calls <<= 4;
+ *calls |= 1;
+ }
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, wintrustdllW))
+ {
+ *calls <<= 4;
+ *calls |= 2;
+ }
+}
+
+static void test_LdrRegisterDllNotification(void)
+{
+ void *cookie, *cookie2;
+ NTSTATUS status;
+ HMODULE mod;
+ DWORD calls;
+
+ if (!pLdrRegisterDllNotification || !pLdrUnregisterDllNotification)
+ {
+ win_skip("Ldr(Un)RegisterDllNotification not available\n");
+ return;
+ }
+
+ mod = LoadLibraryW(expected_dll);
+ if(mod)
+ FreeLibrary(mod);
+ else
+ expected_dll = ws2_32dllW; /* XP Default */
+
+ /* generic test */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback1, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == LDR_DLL_NOTIFICATION_REASON_LOADED, "Expected LDR_DLL_NOTIFICATION_REASON_LOADED, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == LDR_DLL_NOTIFICATION_REASON_UNLOADED, "Expected LDR_DLL_NOTIFICATION_REASON_UNLOADED, got %x\n", calls);
+
+ /* test order of callbacks */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback2, &calls, &cookie2);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x13, "Expected order 0x13, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == 0x24, "Expected order 0x24, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie2);
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll main order */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_dll_main, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x13, "Expected order 0x13, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == 0x42, "Expected order 0x42, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll main order */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_fail, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!mod, "Expected library to fail loading\n");
+ ok(calls == 0x1342, "Expected order 0x1342, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll with dependencies */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_imports, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(wintrustdllW);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x12 || calls == 0x21, "got %x\n", calls);
+
+ FreeLibrary(mod);
+ pLdrUnregisterDllNotification(cookie);
+}
+
START_TEST(rtl)
{
InitFunctionPtrs();
@@ -2293,4 +2553,5 @@ START_TEST(rtl)
test_RtlLeaveCriticalSection();
test_LdrEnumerateLoadedModules();
test_RtlMakeSelfRelativeSD();
+ test_LdrRegisterDllNotification();
}
--
1.9.1
June 21, 2018
[PATCH 5/5] ntdll: GetLogicalProcessorInformation report LPT_PC_SMT for SMT cores.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 5712e4cc1b..2ca9cd59b0 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1352,7 +1352,8 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
(*pdata)[i].Relationship = rel;
(*pdata)[i].ProcessorMask = mask;
- /* TODO: set processor core flags */
+ if (rel == RelationProcessorCore)
+ (*pdata)[i].u.ProcessorCore.Flags = count_bits(mask) > 1 ? LTP_PC_SMT : 0;
(*pdata)[i].u.Reserved[0] = 0;
(*pdata)[i].u.Reserved[1] = id;
*len = i+1;
--
2.14.4
June 21, 2018
[PATCH 4/5] ntdll: GetLogicalProcessorInformationEx report LTP_PC_SMT for SMT cores.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 27 +++++++++++++++------------
include/winnt.h | 2 ++
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index b16f320957..5712e4cc1b 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1309,6 +1309,17 @@ static DWORD log_proc_ex_size_plus(DWORD size)
return sizeof(LOGICAL_PROCESSOR_RELATIONSHIP) + sizeof(DWORD) + size;
}
+static DWORD count_bits(ULONG_PTR mask)
+{
+ DWORD count = 0;
+ while (mask > 0)
+ {
+ mask >>= 1;
+ count++;
+ }
+ return count;
+}
+
/* Store package and core information for a logical processor. Parsing of processor
* data may happen in multiple passes; the 'id' parameter is then used to locate
* previously stored data. The type of data stored in 'id' depends on 'rel':
@@ -1377,7 +1388,10 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
dataex->Relationship = rel;
dataex->Size = log_proc_ex_size_plus(sizeof(PROCESSOR_RELATIONSHIP));
- dataex->u.Processor.Flags = 0; /* TODO */
+ if (rel == RelationProcessorCore)
+ dataex->u.Processor.Flags = count_bits(mask) > 1 ? LTP_PC_SMT : 0;
+ else
+ dataex->u.Processor.Flags = 0;
dataex->u.Processor.EfficiencyClass = 0;
dataex->u.Processor.GroupCount = 1;
dataex->u.Processor.GroupMask[0].Mask = mask;
@@ -1520,17 +1534,6 @@ static inline BOOL logical_proc_info_add_group(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
}
#ifdef linux
-static DWORD count_bits(ULONG_PTR mask)
-{
- DWORD count = 0;
- while (mask > 0)
- {
- mask >>= 1;
- count++;
- }
- return count;
-}
-
/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */
static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, DWORD *max_len)
diff --git a/include/winnt.h b/include/winnt.h
index 54bf11dabd..862cc45291 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -5982,6 +5982,8 @@ typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP
RelationAll = 0xffff
} LOGICAL_PROCESSOR_RELATIONSHIP;
+#define LTP_PC_SMT 0x1
+
typedef enum _PROCESSOR_CACHE_TYPE
{
CacheUnified,
--
2.14.4
June 21, 2018
[PATCH v2 3/5] ntdll: Report physical cores once with proper thread mask.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 48 +++++++++++++++++++++++++++++++++++++-----------
1 file changed, 37 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 14e18dc6af..b16f320957 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1322,17 +1322,16 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
if (pdata) {
DWORD i;
- if(rel == RelationProcessorPackage){
- for(i=0; i<*len; i++)
+ for (i=0; i<*len; i++)
+ {
+ if (rel == RelationProcessorPackage && (*pdata)[i].Relationship == rel && (*pdata)[i].u.Reserved[1] == id)
{
- if ((*pdata)[i].Relationship!=rel || (*pdata)[i].u.Reserved[1]!=id)
- continue;
-
(*pdata)[i].ProcessorMask |= mask;
return TRUE;
}
- }else
- i = *len;
+ else if (rel == RelationProcessorCore && (*pdata)[i].Relationship == rel && (*pdata)[i].u.Reserved[1] == id)
+ return TRUE;
+ }
while(*len == *pmax_len)
{
@@ -1358,6 +1357,10 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
dataex->u.Processor.GroupMask[0].Mask |= mask;
return TRUE;
}
+ else if (rel == RelationProcessorCore && dataex->Relationship == rel && dataex->u.Processor.Reserved[1] == id)
+ {
+ return TRUE;
+ }
ofs += dataex->Size;
}
@@ -1554,6 +1557,9 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(i=beg; i<=end; i++)
{
+ DWORD phys_core = 0;
+ ULONG_PTR thread_mask = 0;
+
if(i > 8*sizeof(ULONG_PTR))
{
FIXME("skipping logical processor %d\n", i);
@@ -1574,15 +1580,35 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
return STATUS_NO_MEMORY;
}
- sprintf(name, core_info, i, "core_id");
+ /* Sysfs enumerates logical cores (and not physical cores), but Windows enumerates
+ * by physical core. Upon enumerating a logical core in sysfs, we register a physical
+ * core and all its logical cores. In order to not report physical cores multiple
+ * times, we pass a unique physical core ID to logical_proc_info_add_by_id and let
+ * that call figure out any duplication.
+ * Obtain a unique physical core ID from the first element of thread_siblings_list.
+ * This list provides logical cores sharing the same physical core. The IDs are based
+ * on kernel cpu core numbering as opposed to a hardware core ID like provided through
+ * 'core_id', so are suitable as a unique ID.
+ */
+ sprintf(name, core_info, i, "thread_siblings_list");
f = fopen(name, "r");
if(f)
{
- fscanf(f, "%u", &r);
+ fscanf(f, "%d%c", &phys_core, &op);
+ fclose(f);
+ }
+ else phys_core = i;
+
+ /* Mask of logical threads sharing same physical core in kernel core numbering. */
+ sprintf(name, core_info, i, "thread_siblings");
+ f = fopen(name, "r");
+ if(f)
+ {
+ fscanf(f, "%lx", &thread_mask);
fclose(f);
}
- else r = i;
- if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, r, (ULONG_PTR)1 << i))
+ else thread_mask = 1<<i;
+ if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, thread_mask))
{
fclose(fcpu_list);
return STATUS_NO_MEMORY;
--
2.14.4
June 21, 2018
[PATCH 2/5] ntdll: store core information by core on apple.
by Roderick Colenbrander
The id parameter can be used for core / package lookup. On Linux
we pass package or core values. On Mac, we use package for both.
Use a core identifier on Mac as well.
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index e6458b98f2..14e18dc6af 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1309,6 +1309,12 @@ static DWORD log_proc_ex_size_plus(DWORD size)
return sizeof(LOGICAL_PROCESSOR_RELATIONSHIP) + sizeof(DWORD) + size;
}
+/* Store package and core information for a logical processor. Parsing of processor
+ * data may happen in multiple passes; the 'id' parameter is then used to locate
+ * previously stored data. The type of data stored in 'id' depends on 'rel':
+ * - RelationProcessorPackage: package id ('CPU socket').
+ * - RelationProcessorCore: physical core number.
+ */
static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, DWORD *len, DWORD *pmax_len,
LOGICAL_PROCESSOR_RELATIONSHIP rel, DWORD id, ULONG_PTR mask)
@@ -1805,6 +1811,7 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(p = 0; p < pkgs_no; ++p){
for(j = 0; j < cores_per_package && p * cores_per_package + j < cores_no; ++j){
ULONG_PTR mask = 0;
+ DWORD phys_core;
for(k = 0; k < lcpu_per_core; ++k)
mask |= (ULONG_PTR)1 << (j * lcpu_per_core + k);
@@ -1816,7 +1823,8 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
return STATUS_NO_MEMORY;
/* add new core */
- if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, p, mask))
+ phys_core = p * cores_per_package + j;
+ if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, mask))
return STATUS_NO_MEMORY;
for(i = 1; i < 5; ++i){
--
2.14.4
June 21, 2018
[PATCH 1/5] ntdll: Derive number of logical CPU cores from core mask.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index dc0ce04f42..e6458b98f2 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1511,6 +1511,17 @@ static inline BOOL logical_proc_info_add_group(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
}
#ifdef linux
+static DWORD count_bits(ULONG_PTR mask)
+{
+ DWORD count = 0;
+ while (mask > 0)
+ {
+ mask >>= 1;
+ count++;
+ }
+ return count;
+}
+
/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */
static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, DWORD *max_len)
@@ -1643,7 +1654,6 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(i=0; i<len; i++){
if((*data)[i].Relationship == RelationProcessorCore){
all_cpus_mask |= (*data)[i].ProcessorMask;
- ++num_cpus;
}
}
}else{
@@ -1651,11 +1661,11 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infoex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*dataex) + i);
if(infoex->Relationship == RelationProcessorCore){
all_cpus_mask |= infoex->u.Processor.GroupMask[0].Mask;
- ++num_cpus;
}
i += infoex->Size;
}
}
+ num_cpus = count_bits(all_cpus_mask);
fnuma_list = fopen("/sys/devices/system/node/online", "r");
if(!fnuma_list)
--
2.14.4
June 21, 2018
[PATCH v2 0/5] ntdll: Improve logical core reporting on Linux and Mac.
by Roderick Colenbrander
Hi,
This is an updated version of the previous patchset with a few improvements
to unify some of the logic better across Linux and Mac.
The overall issue is that on Linux we report each logical core as a physical
core, so on SMT systems we report twice the number of cores. In addition we
don't properly report SMT capabilities.
The main issues are in the Linux sysfs code for parsing the CPU topology.
We use a common helper function (logical_proc_info_add_by_id) among Linux
and Mac. This is were some of the fixes need to be implemented for not
adding cores twice. (We do something similar in logical_proc_info_add_cache
in relation to parsing shared_cpu_map.)
However we use logical_proc_info_add_by_id in an inconsistent manner between
Linux and Mac code. On Linux we use different ID values (core and package),
but on Mac we re-use the package ID. The early patches rectify this and
thanks Andrew Eikum for helping to test this. The later patches fix the
Linux issues and then add proper SMT reporting flags.
Thanks,
Roderick
Roderick Colenbrander (5):
ntdll: Derive number of logical CPU cores from core mask.
ntdll: store core information by core on apple.
ntdll: Report physical cores once with proper thread mask.
ntdll: GetLogicalProcessorInformationEx report LTP_PC_SMT for SMT
cores.
ntdll: GetLogicalProcessorInformation report LPT_PC_SMT for SMT cores.
dlls/ntdll/nt.c | 75 +++++++++++++++++++++++++++++++++++++++++++++------------
include/winnt.h | 2 ++
2 files changed, 61 insertions(+), 16 deletions(-)
--
2.14.4
June 21, 2018
[PATCH v8 9/9] ntdll: Return chassis info from NtQuerySystemInformation on Linux
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/nt.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index e622912d8a..d9fc2e6108 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -108,6 +108,17 @@ struct smbios_board {
BYTE serial;
};
+struct smbios_chassis {
+ BYTE type;
+ BYTE length;
+ WORD handle;
+ BYTE vendor;
+ BYTE shape;
+ BYTE version;
+ BYTE serial;
+ BYTE asset_tag;
+};
+
#include "poppack.h"
/* Firmware table providers */
@@ -1945,12 +1956,15 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
size_t system_vendor_len, system_product_len, system_version_len, system_serial_len;
char board_vendor[128], board_product[128], board_version[128], board_serial[128];
size_t board_vendor_len, board_product_len, board_version_len, board_serial_len;
+ char chassis_vendor[128], chassis_version[128], chassis_serial[128], chassis_asset_tag[128];
+ size_t chassis_vendor_len, chassis_version_len, chassis_serial_len, chassis_asset_tag_len;
char *buffer = (char*)sfti->TableBuffer;
BYTE string_count;
struct smbios_prologue *prologue;
struct smbios_bios *bios;
struct smbios_system *system;
struct smbios_board *board;
+ struct smbios_chassis *chassis;
#define S(s) s, sizeof(s)
bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
@@ -1964,6 +1978,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
board_product_len = get_smbios_string("/sys/class/dmi/id/board_name", S(board_product));
board_version_len = get_smbios_string("/sys/class/dmi/id/board_version", S(board_version));
board_serial_len = get_smbios_string("/sys/class/dmi/id/board_serial", S(board_serial));
+ chassis_vendor_len = get_smbios_string("/sys/class/dmi/id/chassis_vendor", S(chassis_vendor));
+ chassis_version_len = get_smbios_string("/sys/class/dmi/id/chassis_version", S(chassis_version));
+ chassis_serial_len = get_smbios_string("/sys/class/dmi/id/chassis_serial", S(chassis_serial));
+ chassis_asset_tag_len = get_smbios_string("/sys/class/dmi/id/chassis_tag", S(chassis_asset_tag));
#undef S
*required_len = sizeof(struct smbios_prologue);
@@ -1978,6 +1996,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
*required_len += sizeof(struct smbios_board);
*required_len += max(board_vendor_len + board_product_len + board_version_len + board_serial_len + 5, 2);
+ *required_len += sizeof(struct smbios_chassis);
+ *required_len += max(chassis_vendor_len + chassis_version_len + chassis_serial_len +
+ chassis_asset_tag_len + 5, 2);
+
sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
@@ -2064,6 +2086,33 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
copy_smbios_string(&buffer, board_version, board_version_len);
copy_smbios_string(&buffer, board_serial, board_serial_len);
memset(buffer, 0, 1);
+ buffer++;
+ }
+ else
+ {
+ memset(buffer, 0, 2);
+ buffer += 2;
+ }
+
+ string_count = 0;
+ chassis = (struct smbios_chassis*)buffer;
+ chassis->type = 3;
+ chassis->length = sizeof(struct smbios_chassis);
+ chassis->handle = 0;
+ chassis->vendor = chassis_vendor_len ? ++string_count : 0;
+ chassis->shape = 0x2; /* unknown */
+ chassis->version = chassis_version_len ? ++string_count : 0;
+ chassis->serial = chassis_serial_len ? ++string_count : 0;
+ chassis->asset_tag = chassis_asset_tag_len ? ++string_count : 0;
+ buffer += sizeof(struct smbios_chassis);
+
+ if (string_count)
+ {
+ copy_smbios_string(&buffer, chassis_vendor, chassis_vendor_len);
+ copy_smbios_string(&buffer, chassis_version, chassis_version_len);
+ copy_smbios_string(&buffer, chassis_serial, chassis_serial_len);
+ copy_smbios_string(&buffer, chassis_asset_tag, chassis_asset_tag_len);
+ memset(buffer, 0, 1);
}
else
{
--
2.17.1
June 21, 2018