From: wasertech danny@waser.tech
--- dlls/ntdll/unix/file.c | 8 +++++++- dlls/ntdll/unix/system.c | 41 ++++++++++++++++++++++++++++++++++++++++ include/winternl.h | 6 ++++++ 3 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 958ae9a6937..13d4cfafd8c 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -125,6 +125,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(file); WINE_DECLARE_DEBUG_CHANNEL(winediag);
+BOOL init_numa_info(FILE_NUMA_NODE_INFORMATION *info); + #define MAX_DOS_DRIVES 26
/* just in case... */ @@ -4583,7 +4585,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, 0, /* FileIdGlobalTxDirectoryInformation */ 0, /* FileIsRemoteDeviceInformation */ 0, /* FileAttributeCacheInformation */ - 0, /* FileNumaNodeInformation */ + sizeof(FILE_NUMA_NODE_INFORMATION), /* FileNumaNodeInformation */ 0, /* FileStandardLinkInformation */ 0, /* FileRemoteProtocolInformation */ 0, /* FileRenameInformationBypassAccessCheck */ @@ -4735,6 +4737,10 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, info->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; } break; + case FileNumaNodeInformation: + FILE_NUMA_NODE_INFORMATION *ni = (FILE_NUMA_NODE_INFORMATION *)ptr; + if (!init_numa_info(ni)) status = STATUS_NOT_IMPLEMENTED; + status = STATUS_SUCCESS; break; case FileStatInformation: if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 342e443f5e7..bf61f179849 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -1404,6 +1404,33 @@ static void init_logical_proc_info(void) init_tsc_frequency(); }
+BOOL init_numa_info(FILE_NUMA_NODE_INFORMATION *info) +{ + unsigned int i; + + if (!info) return FALSE; + pthread_once(&logical_proc_init_once, init_logical_proc_info); + + info->HighestNodeNumber = 0; + info->NodeNumber = 0; + info->Reserved = 0; + + if (!logical_proc_info_len || !logical_proc_info) + return TRUE; + + for (i = 0; i < logical_proc_info_len; ++i) + { + if (logical_proc_info[i].Relationship == RelationNumaNode) + { + if (logical_proc_info[i].NumaNode.NodeNumber > info->HighestNodeNumber) + info->HighestNodeNumber = logical_proc_info[i].NumaNode.NodeNumber; + } + } + + info->NodeNumber = 0; + return TRUE; +} + /****************************************************************** * init_cpu_info * @@ -3885,6 +3912,20 @@ NTSTATUS WINAPI NtQuerySystemInformationEx( SYSTEM_INFORMATION_CLASS class, break; }
+ case SystemNumaProximityNodeInformation: + { + FILE_NUMA_NODE_INFORMATION *numa_info = info; + + len = sizeof(FILE_NUMA_NODE_INFORMATION); + if (size < len) { ret = STATUS_BUFFER_TOO_SMALL; break; } + if (!info) return STATUS_ACCESS_VIOLATION; + if (!init_numa_info(numa_info)) + ret = STATUS_NOT_IMPLEMENTED; + + ret = STATUS_SUCCESS; + break; + } + default: FIXME( "(0x%08x,%p,%u,%p,%u,%p) stub\n", class, query, query_len, info, size, ret_size ); break; diff --git a/include/winternl.h b/include/winternl.h index 36c24b01e56..39e720554db 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1790,6 +1790,12 @@ typedef struct _FILE_STAT_INFORMATION { ULONG EffectiveAccess; } FILE_STAT_INFORMATION, *PFILE_STAT_INFORMATION;
+typedef struct _FILE_NUMA_NODE_INFORMATION { + ULONG HighestNodeNumber; + ULONG NodeNumber; + ULONG Reserved; +} FILE_NUMA_NODE_INFORMATION, *PFILE_NUMA_NODE_INFORMATION; + typedef struct _FILE_IO_COMPLETION_NOTIFICATION_INFORMATION { ULONG Flags; } FILE_IO_COMPLETION_NOTIFICATION_INFORMATION, *PFILE_IO_COMPLETION_NOTIFICATION_INFORMATION;