From: Ziqing Hui Subject: [PATCH v2 2/2] kernel32: Use uppercase name in UpdateResourceW(). Message-Id: Date: Wed, 16 Sep 2020 15:20:14 +0800 Signed-off-by: Ziqing Hui --- v2: Free allocated unicode string. Question: Do we need _TRY{}_EXCEPT{} here like in FindResourceExW() and FindResourceExA() ? dlls/kernel32/resource.c | 35 ++++++++++++++++++++++++++++++++-- dlls/kernel32/tests/resource.c | 1 - 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/dlls/kernel32/resource.c b/dlls/kernel32/resource.c index b81ab3de5a..0a6adc379f 100644 --- a/dlls/kernel32/resource.c +++ b/dlls/kernel32/resource.c @@ -62,6 +62,26 @@ static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str ) return STATUS_SUCCESS; } +static NTSTATUS get_res_nameW( LPCWSTR name, UNICODE_STRING *str ) +{ + if (IS_INTRESOURCE(name)) + { + str->Buffer = ULongToPtr( LOWORD(name) ); + return STATUS_SUCCESS; + } + if (name[0] == '#') + { + ULONG value; + RtlInitUnicodeString( str, name + 1 ); + if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value)) + return STATUS_INVALID_PARAMETER; + str->Buffer = ULongToPtr(value); + return STATUS_SUCCESS; + } + RtlCreateUnicodeString( str, name ); + RtlUpcaseUnicodeString( str, str, FALSE ); + return STATUS_SUCCESS; +} /********************************************************************** * FindResourceExA (KERNEL32.@) @@ -1290,7 +1310,9 @@ BOOL WINAPI UpdateResourceW( HANDLE hUpdate, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage, LPVOID lpData, DWORD cbData) { QUEUEDUPDATES *updates; + UNICODE_STRING nameW, typeW; BOOL ret = FALSE; + NTSTATUS status; TRACE("%p %s %s %08x %p %d\n", hUpdate, debugstr_w(lpType), debugstr_w(lpName), wLanguage, lpData, cbData); @@ -1298,19 +1320,28 @@ BOOL WINAPI UpdateResourceW( HANDLE hUpdate, LPCWSTR lpType, LPCWSTR lpName, updates = GlobalLock(hUpdate); if (updates) { + if ((status = get_res_nameW( lpName, &nameW )) != STATUS_SUCCESS) goto done; + if ((status = get_res_nameW( lpType, &typeW )) != STATUS_SUCCESS) goto done; + if (lpData == NULL && cbData == 0) /* remove resource */ { - ret = update_add_resource( updates, lpType, lpName, wLanguage, NULL, TRUE ); + ret = update_add_resource( updates, typeW.Buffer, nameW.Buffer, wLanguage, NULL, TRUE ); } else { struct resource_data *data; data = allocate_resource_data( wLanguage, 0, lpData, cbData, TRUE ); if (data) - ret = update_add_resource( updates, lpType, lpName, wLanguage, data, TRUE ); + ret = update_add_resource( updates, typeW.Buffer, nameW.Buffer, wLanguage, data, TRUE ); } + + done: + if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) ); GlobalUnlock(hUpdate); } + + if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer ); + if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer ); return ret; } diff --git a/dlls/kernel32/tests/resource.c b/dlls/kernel32/tests/resource.c index acb95249d8..bca0298044 100644 --- a/dlls/kernel32/tests/resource.c +++ b/dlls/kernel32/tests/resource.c @@ -382,7 +382,6 @@ static void update_resources_name( void ) if ( !module ) return; rsrc = FindResourceA( module, res_name, res_type ); - todo_wine ok( rsrc != NULL || broken( GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND ) /* win2008 */, "FindResource failed: %u\n", GetLastError() );