From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/rometadata/mdtables.c | 74 ++++++++++++++++++++++++++++-- dlls/rometadata/tests/rometadata.c | 19 ++++---- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/dlls/rometadata/mdtables.c b/dlls/rometadata/mdtables.c index 8c073a3f165..e5a5185b899 100644 --- a/dlls/rometadata/mdtables.c +++ b/dlls/rometadata/mdtables.c @@ -19,8 +19,12 @@ */ #include <assert.h> +#include <stdarg.h> #define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winnls.h" #include "objbase.h" #include "cor.h" #include "rometadataapi.h" @@ -429,11 +433,75 @@ static HRESULT WINAPI import_GetModuleFromScope(IMetaDataImport *iface, mdModule return E_NOTIMPL; } +static BOOL type_full_name(WCHAR *out, ULONG out_len, ULONG *needed, const char *namespace, const char *name) +{ + ULONG full_name_len; + char *full_name; + + if (namespace[0] && name[0]) + full_name_len = strlen(namespace) + 1 + strlen(name) + 1; + else + full_name_len = strlen(namespace[0] ? namespace : name) + 1; + if (!(full_name = malloc(full_name_len))) return FALSE; + if (namespace[0] && name[0]) + snprintf(full_name, full_name_len, "%s.%s", namespace, name); + else + strcpy(full_name, namespace[0] ? namespace : name); + *needed = MultiByteToWideChar(CP_ACP, 0, full_name, -1, NULL, 0); + if (out && out_len) + { + ULONG n = MultiByteToWideChar(CP_ACP, 0, full_name, min(full_name_len, out_len) - 1, out, out_len - 1); + out[n] = L'\0'; + } + free(full_name); + return TRUE; +} + static HRESULT WINAPI import_GetTypeDefProps(IMetaDataImport *iface, mdTypeDef type_def, WCHAR *name, ULONG len, - ULONG *written, ULONG *flags, mdToken *base) + ULONG *written, ULONG *ret_flags, mdToken *base) { - FIXME("(%p, %#x, %p, %lu, %p, %p, %p): stub!\n", iface, type_def, name, len, written, flags, base); - return E_NOTIMPL; + struct metadata_tables *impl = impl_from_IMetaDataImport(iface); + ULONG needed = 0, flags = 0, extends = 0; + + TRACE("(%p, %#x, %p, %lu, %p, %p, %p)\n", iface, type_def, name, len, written, ret_flags, base); + + if (TypeFromToken(type_def) != mdtTypeDef) return S_FALSE; + + if (name && len) + name[0] = L'\0'; + if (type_def != mdTypeDefNil) + { + const ULONG row = RidFromToken(type_def); + const char *namespace, *nameA; + ULONG name_idx, ns_idx; + HRESULT hr; + + if (FAILED((hr = IMetaDataTables_GetColumn(&impl->IMetaDataTables_iface, TABLE_TYPEDEF, 0, row, &flags)))) + return hr; + if (FAILED((hr = IMetaDataTables_GetColumn(&impl->IMetaDataTables_iface, TABLE_TYPEDEF, 1, row, &name_idx)))) + return hr; + if (FAILED((hr = IMetaDataTables_GetColumn(&impl->IMetaDataTables_iface, TABLE_TYPEDEF, 2, row, &ns_idx)))) + return hr; + if (FAILED((hr = IMetaDataTables_GetColumn(&impl->IMetaDataTables_iface, TABLE_TYPEDEF, 3, row, &extends)))) + return hr; + if (FAILED(hr = IMetaDataTables_GetString(&impl->IMetaDataTables_iface, name_idx, &nameA))) + return hr; + if (FAILED(hr = IMetaDataTables_GetString(&impl->IMetaDataTables_iface, ns_idx, &namespace))) + return hr; + if (!type_full_name(name, len, &needed, namespace, nameA)) return E_OUTOFMEMORY; + /* Native replaces tokens with rid 0 with mdTypeRefNil. */ + if (IsNilToken(extends)) + extends = mdTypeRefNil; + } + + if (written) + *written = needed; + if (ret_flags) + *ret_flags = flags; + if (base) + *base = extends; + + return (name && needed > len) ? CLDB_S_TRUNCATION : S_OK; } static HRESULT WINAPI import_GetInterfaceImplProps(IMetaDataImport *iface, mdInterfaceImpl iface_impl, diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index c8e33d86a81..f3bbae157d7 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -1037,29 +1037,28 @@ static void test_IMetaDataImport(void) exp_len = snprintf(bufA, sizeof(bufA), "%s.%s", info->exp_namespace, info->exp_name) + 1; str_reqd = 0; hr = IMetaDataImport_GetTypeDefProps(md_import, typedef_tokens[i], NULL, 0, &str_reqd, NULL, NULL); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(str_reqd == exp_len, "got str_reqd %lu != %lu\n", str_reqd, exp_len); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(str_reqd == exp_len, "got str_reqd %lu != %lu\n", str_reqd, exp_len); MultiByteToWideChar(CP_ACP, 0, bufA, -1, bufW, ARRAY_SIZE(bufW)); str_len = str_reqd; strW = calloc(str_len, sizeof(WCHAR)); hr = IMetaDataImport_GetTypeDefProps(md_import, typedef_tokens[i], strW, str_len - 1, &str_reqd, &val, &base); - todo_wine ok(hr == CLDB_S_TRUNCATION, "got hr %#lx\n", hr); + ok(hr == CLDB_S_TRUNCATION, "got hr %#lx\n", hr); len = wcslen(strW); - todo_wine ok( len == str_len - 2, "got len %lu != %lu\n", len, str_len - 2); + ok( len == str_len - 2, "got len %lu != %lu\n", len, str_len - 2); if (hr == CLDB_S_TRUNCATION) - todo_wine ok(!wcsncmp(strW, bufW, str_len - 2), "got bufW %s != %s\n", debugstr_w(strW), - debugstr_wn(bufW, str_len - 2)); + ok(!wcsncmp(strW, bufW, str_len - 2), "got bufW %s != %s\n", debugstr_w(strW), + debugstr_wn(bufW, str_len - 2)); val = base = 0; hr = IMetaDataImport_GetTypeDefProps(md_import, typedef_tokens[i], strW, str_len, NULL, &val, &base); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + ok(hr == S_OK, "got hr %#lx\n", hr); if (hr == S_OK) ok(1 || !wcscmp(strW, bufW), "got strW %s != %s\n", debugstr_w(strW), debugstr_w(bufW)); free(strW); - todo_wine ok(val == info->exp_flags, "got val %#lx != %#lx\n", val, info->exp_flags); - todo_wine ok(base == info->exp_base, "got base %s != %s\n", debugstr_mdToken(base), - debugstr_mdToken(info->exp_base)); + ok(val == info->exp_flags, "got val %#lx != %#lx\n", val, info->exp_flags); + ok(base == info->exp_base, "got base %s != %s\n", debugstr_mdToken(base), debugstr_mdToken(info->exp_base)); hr = IMetaDataImport_FindTypeDefByName(md_import, bufW, 0, &token); todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9525