I had these in my patch repo for quite a while.
Patch 1 shouldn't need explanation.
The problem fixed by patch 2 and 3 is that sizeof(KEY_{BASIC,VALUE_PARTIAL,FULL}_INFORMATION) are all slightly bigger than the actual minimum size required to get all the requested info, because those structs include an array of size 1 as their last member, which is intended to be a variable length array. Fixing these size calculations removes one allocation in wineserver and reduces the amount of data transmitted by 1 - 2 bytes.
Patch 4 just reduces the amount of data transmitted from wineserver for each update_display_cache_from_registry call, which is called every time the display device lists are locked.
-- v3: win32u: Query basic instead of full key information to get the LastWriteTime. win32u: Calculate buffer sizes from registry structs correctly. ntdll: Calculate buffer sizes from registry structs correctly. ntdll: Use correct output buffer size in RtlpNtEnumerateSubKey.
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org --- dlls/ntdll/reg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c index 294b724a5e5..106ee620cda 100644 --- a/dlls/ntdll/reg.c +++ b/dlls/ntdll/reg.c @@ -91,9 +91,9 @@ NTSTATUS WINAPI RtlpNtEnumerateSubKey( HANDLE handle, UNICODE_STRING *out, ULONG DWORD dwLen, dwResultLen; NTSTATUS ret;
- if (out->Length) + if (out->MaximumLength) { - dwLen = out->Length + sizeof(KEY_BASIC_INFORMATION); + dwLen = out->MaximumLength + sizeof(KEY_BASIC_INFORMATION); info = RtlAllocateHeap( GetProcessHeap(), 0, dwLen ); if (!info) return STATUS_NO_MEMORY; @@ -111,7 +111,7 @@ NTSTATUS WINAPI RtlpNtEnumerateSubKey( HANDLE handle, UNICODE_STRING *out, ULONG out->Length = dwResultLen; else if (!ret) { - if (out->Length < info->NameLength) + if (out->MaximumLength < info->NameLength) { out->Length = dwResultLen; ret = STATUS_BUFFER_OVERFLOW;
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org --- dlls/ntdll/reg.c | 6 +++--- dlls/ntdll/unix/system.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c index 106ee620cda..283238559d1 100644 --- a/dlls/ntdll/reg.c +++ b/dlls/ntdll/reg.c @@ -93,7 +93,7 @@ NTSTATUS WINAPI RtlpNtEnumerateSubKey( HANDLE handle, UNICODE_STRING *out, ULONG
if (out->MaximumLength) { - dwLen = out->MaximumLength + sizeof(KEY_BASIC_INFORMATION); + dwLen = out->MaximumLength + offsetof(KEY_BASIC_INFORMATION, Name); info = RtlAllocateHeap( GetProcessHeap(), 0, dwLen ); if (!info) return STATUS_NO_MEMORY; @@ -105,7 +105,7 @@ NTSTATUS WINAPI RtlpNtEnumerateSubKey( HANDLE handle, UNICODE_STRING *out, ULONG }
ret = NtEnumerateKey( handle, index, KeyBasicInformation, info, dwLen, &dwResultLen ); - dwResultLen -= sizeof(KEY_BASIC_INFORMATION); + dwResultLen -= offsetof(KEY_BASIC_INFORMATION, Name);
if (ret == STATUS_BUFFER_OVERFLOW) out->Length = dwResultLen; @@ -138,7 +138,7 @@ NTSTATUS WINAPI RtlpNtQueryValueKey( HANDLE handle, ULONG *result_type, PBYTE de UNICODE_STRING name; NTSTATUS ret; DWORD dwResultLen; - DWORD dwLen = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + (result_len ? *result_len : 0); + DWORD dwLen = offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data[result_len ? *result_len : 0]);
info = RtlAllocateHeap( GetProcessHeap(), 0, dwLen ); if (!info) diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index ee91441794e..87cc8b9c3a4 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -2095,7 +2095,7 @@ static BOOL reg_query_value( HKEY key, LPCWSTR name, DWORD type, void *data, DWO UNICODE_STRING nameW; KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buf;
- if (count > sizeof(buf) - sizeof(KEY_VALUE_PARTIAL_INFORMATION)) return FALSE; + if (count > sizeof(buf) - offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data)) return FALSE;
nameW.Buffer = (WCHAR *)name; nameW.Length = wcslen( name ) * sizeof(WCHAR);
This merge request was approved by Alexandre Julliard.
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org --- dlls/win32u/sysparams.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 8a99e4095f9..136f47672d0 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1258,7 +1258,8 @@ static BOOL update_display_cache_from_registry(void) sizeof(devicemap_video_keyW) ))) return FALSE;
- status = NtQueryKey( video_key, KeyFullInformation, &key, sizeof(key), &size ); + status = NtQueryKey( video_key, KeyFullInformation, &key, + offsetof(KEY_FULL_INFORMATION, Class), &size ); if (status && status != STATUS_BUFFER_OVERFLOW) return FALSE;
@@ -3210,7 +3211,7 @@ void sysparams_init(void)
if ((hkey = reg_open_key( config_key, software_fontsW, sizeof(software_fontsW) ))) { - char buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD)]; + char buffer[offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data[sizeof(DWORD)])]; KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer;
if (query_reg_value( hkey, log_pixelsW, value, sizeof(buffer) ) && value->Type == REG_DWORD)
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org --- dlls/win32u/sysparams.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 136f47672d0..b68bfa3a7ce 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1246,7 +1246,7 @@ static void clear_display_devices(void) static BOOL update_display_cache_from_registry(void) { DWORD adapter_id, monitor_id, monitor_count = 0, size; - KEY_FULL_INFORMATION key; + KEY_BASIC_INFORMATION key; struct adapter *adapter; struct monitor *monitor; HANDLE mutex = NULL; @@ -1258,8 +1258,8 @@ static BOOL update_display_cache_from_registry(void) sizeof(devicemap_video_keyW) ))) return FALSE;
- status = NtQueryKey( video_key, KeyFullInformation, &key, - offsetof(KEY_FULL_INFORMATION, Class), &size ); + status = NtQueryKey( video_key, KeyBasicInformation, &key, + offsetof(KEY_BASIC_INFORMATION, Name), &size ); if (status && status != STATUS_BUFFER_OVERFLOW) return FALSE;