[PATCH 1/2] kernel32/tests: Add some tests for GetFileMUIInfo().
Dmitry Timoshkov
dmitry at baikal.ru
Thu Jul 21 09:49:43 CDT 2022
MUI_RC_CONFIG layout is based on the description from
http://hostagebrain.blogspot.com/2015/11/multilingual-user-interface.html
Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
dlls/kernel32/tests/resource.c | 235 ++++++++++++++++++++++++++++++++-
1 file changed, 234 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/tests/resource.c b/dlls/kernel32/tests/resource.c
index 6c5bc99c0c5..626645a8979 100644
--- a/dlls/kernel32/tests/resource.c
+++ b/dlls/kernel32/tests/resource.c
@@ -2,6 +2,7 @@
* Unit test suite for resource functions.
*
* Copyright 2006 Mike McCormack
+ * Copyright 2022 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,8 +19,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include <windows.h>
+#include <stdarg.h>
#include <stdio.h>
+#include <assert.h>
+#include <windows.h>
#include "wine/test.h"
@@ -520,10 +523,240 @@ static void test_internal_structure(void)
ok( EndUpdateResourceW( res, TRUE ), "EndUpdateResourceW failed\n");
}
+typedef struct
+{
+ DWORD dwSignature;
+ DWORD dwSize;
+ DWORD dwVersion;
+ DWORD unknown1;
+ DWORD unknown2;
+ DWORD unknown3;
+ DWORD dwFileType;
+ BYTE pServiceChecksum[16];
+ BYTE pChecksum[16];
+ DWORD unknown4[6];
+ DWORD dwTypeNameMainOffset;
+ DWORD dwTypeNameMainSize;
+ DWORD dwTypeIDMainOffset;
+ DWORD dwTypeIDMainSize;
+ DWORD dwTypeNameMUIOffset;
+ DWORD dwTypeNameMUISize;
+ DWORD dwTypeIDMUIOffset;
+ DWORD dwTypeIDMUISize;
+ DWORD unknown5;
+ DWORD unknown6;
+ DWORD dwLanguageNameOffset;
+ DWORD dwLanguageNameSize;
+} MUI_RC_CONFIG;
+
+static void *offset_to_data(void *base, DWORD offset)
+{
+ return (char *)base + offset;
+}
+
+static void test_GetFileMUIInfo(void)
+{
+#define MUI_QUERY_ALL (MUI_QUERY_TYPE | MUI_QUERY_CHECKSUM | MUI_QUERY_LANGUAGE_NAME | MUI_QUERY_RESOURCE_TYPES)
+ static const BYTE zero[8];
+ static const WCHAR path[] = L"urlmon.dll";
+ char buf[1024];
+ HRSRC rsrc;
+ MUI_RC_CONFIG *rc_cfg;
+ char *p1, *p2;
+ FILEMUIINFO *info = (FILEMUIINFO *)buf;
+ DWORD size, full_size;
+ HMODULE module;
+ int ret;
+
+ module = LoadLibraryExW(path, 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE);
+ ok(module != NULL, "LoadLibraryEx error %lu\n", GetLastError());
+ rsrc = FindResourceW(module, MAKEINTRESOURCEW(1), L"MUI");
+ todo_wine
+ ok(rsrc != 0, "MUI resource not found\n");
+ if (!rsrc)
+ {
+ skip("MUI resource not found\n");
+ FreeLibrary(module);
+ return;
+ }
+ rc_cfg = LockResource(LoadResource(module, rsrc));
+ ok(rc_cfg->dwVersion == MAKELONG(0,1), "got %08lx\n", rc_cfg->dwVersion);
+ ok(rc_cfg->dwFileType == MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN, "got %08lx\n", rc_cfg->dwFileType);
+
+ SetLastError(0xdeadbeef);
+ ret = GetFileMUIInfo(0, path, NULL, NULL);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
+
+ info->dwSize = sizeof(*info);
+ SetLastError(0xdeadbeef);
+ ret = GetFileMUIInfo(0, path, info, NULL);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
+
+ size = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = GetFileMUIInfo(MUI_QUERY_ALL, path, NULL, &size);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
+
+ size = 0;
+ ret = GetFileMUIInfo(0, path, NULL, &size);
+ ok(ret, "GetFileMUIInfo error %lu\n", GetLastError());
+ ok(size == sizeof(FILEMUIINFO), "got %lu bytes\n", size);
+
+ memset(info, 0, sizeof(*info));
+ size = info->dwSize = sizeof(*info) - 1;
+ SetLastError(0xdeadbeef);
+ ret = GetFileMUIInfo(0, path, info, &size);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
+
+ memset(info, 0, sizeof(*info));
+ size = info->dwSize = sizeof(*info);
+ ret = GetFileMUIInfo(0, path, info, &size);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
+ ok(!size, "got %lu\n", size);
+ ok(info->dwSize == sizeof(*info), "got %lu\n", info->dwSize);
+ ok(!info->dwVersion, "got %08lx\n", info->dwVersion);
+
+ memset(info, 0, sizeof(*info));
+ size = info->dwSize = sizeof(*info);
+ info->dwVersion = MUI_FILEINFO_VERSION;
+ ret = GetFileMUIInfo(0, path, info, &size);
+ ok(ret, "GetFileMUIInfo error %lu\n", GetLastError());
+
+ memset(buf, 0, sizeof(buf));
+ size = info->dwSize = 1;
+ info->dwVersion = MUI_FILEINFO_VERSION;
+ info->dwFileType = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = GetFileMUIInfo(0, path, info, &size);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
+ ok(info->dwVersion == MUI_FILEINFO_VERSION, "got %08lx\n", info->dwVersion);
+ ok(info->dwFileType == 0xdeadbeef, "got %08lx\n", info->dwFileType);
+
+ memset(buf, 0, sizeof(buf));
+ info->dwSize = sizeof(*info);
+ size = sizeof(*info) + 1;
+ info->dwVersion = MUI_FILEINFO_VERSION;
+ info->dwFileType = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = GetFileMUIInfo(0, path, info, &size);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
+ ok(info->dwVersion == MUI_FILEINFO_VERSION, "got %08lx\n", info->dwVersion);
+ ok(info->dwFileType == 0xdeadbeef, "got %08lx\n", info->dwFileType);
+
+ full_size = 0;
+ SetLastError(0xdeadbeef);
+ ret = GetFileMUIInfo(MUI_QUERY_ALL, path, NULL, &full_size);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
+
+ memset(buf, 0, sizeof(buf));
+ info->dwSize = size = sizeof(*info);
+ info->dwVersion = 0;
+ info->dwFileType = 0xdeadbeef;
+ memcpy(info->abBuffer, "deadbeef", 8);
+ SetLastError(0xdeadbeef);
+ ret = GetFileMUIInfo(MUI_QUERY_ALL, path, info, &size);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
+ ok(info->dwVersion == 0, "got %08lx\n", info->dwVersion);
+ ok(info->dwFileType == 0, "got %08lx\n", info->dwFileType);
+ ok(!memcmp(info->abBuffer, zero, 8), "got %.8s\n", info->abBuffer);
+
+ memset(buf, 0, sizeof(buf));
+ info->dwSize = size = sizeof(*info);
+ info->dwVersion = 0xdeadbeef;
+ info->dwFileType = 0xdeadbeef;
+ memcpy(info->abBuffer, "deadbeef", 8);
+ SetLastError(0xdeadbeef);
+ ret = GetFileMUIInfo(MUI_QUERY_ALL, path, info, &size);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
+ ok(info->dwVersion == 0xdeadbeef, "got %08lx\n", info->dwVersion);
+ ok(info->dwFileType == MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN, "got %08lx\n", info->dwFileType);
+ ok(!memcmp(info->abBuffer, zero, 8), "got %.8s\n", info->abBuffer);
+
+ memset(buf, 0, sizeof(buf));
+ info->dwSize = size = sizeof(*info);
+ info->dwVersion = 0xdeadbeef;
+ info->dwFileType = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = GetFileMUIInfo(MUI_QUERY_ALL, path, info, &size);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
+ ok(info->dwVersion == 0xdeadbeef, "got %08lx\n", info->dwVersion);
+ ok(info->dwFileType == MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN, "got %08lx\n", info->dwFileType);
+
+ memset(buf, 0, sizeof(buf));
+ info->dwSize = size = full_size;
+ info->dwVersion = 0;
+ info->dwFileType = 0xdeadbeef;
+ ret = GetFileMUIInfo(MUI_QUERY_ALL, path, info, &size);
+ ok(!ret, "GetFileMUIInfo should fail\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
+ ok(size == 0, "got %08lx\n", size);
+ ok(info->dwVersion == 0, "got %08lx\n", info->dwVersion);
+ ok(info->dwFileType == 0, "got %08lx\n", info->dwFileType);
+ ok(!memcmp(info->abBuffer, zero, 8), "got %.8s\n", info->abBuffer);
+
+ memset(buf, 0, sizeof(buf));
+ info->dwSize = size = full_size;
+ info->dwVersion = MUI_FILEINFO_VERSION;
+ info->dwFileType = 0xdeadbeef;
+ ret = GetFileMUIInfo(MUI_QUERY_ALL, path, info, &size);
+ ok(ret || broken(GetLastError() == ERROR_INSUFFICIENT_BUFFER) /* Some Win10 versions */, "GetFileMUIInfo error %lu\n", GetLastError());
+ while (!ret) /* Try to recover from Win10 breakage */
+ {
+ size += 2;
+ assert(size <= sizeof(buf));
+ info->dwSize = size;
+ ret = GetFileMUIInfo(MUI_QUERY_ALL, path, info, &size);
+ }
+ ok(info->dwVersion == MUI_FILEINFO_VERSION, "got %08lx\n", info->dwVersion);
+ ok(info->dwFileType == MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN, "got %08lx\n", info->dwFileType);
+
+ ok(!memcmp(info->pChecksum, rc_cfg->pChecksum, 16), "Checksum doesn't match\n");
+ ok(!memcmp(info->pServiceChecksum, rc_cfg->pServiceChecksum, 16), "ServiceChecksum doesn't match\n");
+
+ p1 = offset_to_data(rc_cfg, rc_cfg->dwLanguageNameOffset);
+ p2 = offset_to_data(info, info->dwLanguageNameOffset);
+ ok(!memcmp(p1, p2, rc_cfg->dwLanguageNameSize), "LanguageName doesn't match\n");
+
+ p1 = offset_to_data(rc_cfg, rc_cfg->dwTypeNameMainOffset);
+ p2 = offset_to_data(info, info->dwTypeNameMainOffset);
+ ok(!memcmp(p1, p2, rc_cfg->dwTypeNameMainSize), "TypeNameMain doesn't match\n");
+
+ p1 = offset_to_data(rc_cfg, rc_cfg->dwTypeIDMainOffset);
+ p2 = offset_to_data(info, info->dwTypeIDMainOffset);
+ ok(rc_cfg->dwTypeIDMainSize == info->dwTypeIDMainSize * sizeof(DWORD), "dwTypeIDMainSize %#08lx != %08lx\n",
+ rc_cfg->dwTypeIDMainSize, info->dwTypeIDMainSize);
+ ok(!memcmp(p1, p2, rc_cfg->dwTypeIDMainSize), "TypeIDMain doesn't match\n");
+
+ p1 = offset_to_data(rc_cfg, rc_cfg->dwTypeIDMUIOffset);
+ p2 = offset_to_data(info, info->dwTypeIDMUIOffset);
+ ok(rc_cfg->dwTypeIDMUISize == info->dwTypeIDMUISize * sizeof(DWORD), "dwTypeIDMUISize %#08lx != %08lx\n",
+ rc_cfg->dwTypeIDMUISize, info->dwTypeIDMUISize);
+ ok(!memcmp(p1, p2, rc_cfg->dwTypeIDMUISize), "TypeIDMUI doesn't match\n");
+
+ p1 = offset_to_data(rc_cfg, rc_cfg->dwTypeNameMUIOffset);
+ p2 = offset_to_data(info, info->dwTypeNameMUIOffset);
+ ok(!memcmp(p1, p2, rc_cfg->dwTypeNameMUISize), "TypeNameMUI doesn't match\n");
+
+ FreeLibrary(module);
+}
+
START_TEST(resource)
{
DWORD i;
+ test_GetFileMUIInfo();
+
DeleteFileA( filename );
update_missing_exe();
--
2.37.1
More information about the wine-devel
mailing list