From: Vibhav Pant vibhavp@gmail.com
--- dlls/rometadata/assembly.c | 49 +++++++++++++++++++++++++++++- dlls/rometadata/mdtables.c | 15 +++++---- dlls/rometadata/rometadatapriv.h | 3 ++ dlls/rometadata/tests/rometadata.c | 10 ------ 4 files changed, 60 insertions(+), 17 deletions(-)
diff --git a/dlls/rometadata/assembly.c b/dlls/rometadata/assembly.c index 00824d55d36..b4298ec3bcd 100644 --- a/dlls/rometadata/assembly.c +++ b/dlls/rometadata/assembly.c @@ -842,4 +842,51 @@ ULONG assembly_get_heap_size(const assembly_t *assembly, enum heap_type heap) return assembly->stream_user_strings.size; DEFAULT_UNREACHABLE; } -} \ No newline at end of file +} + +const char *assembly_get_string(const assembly_t *assembly, ULONG idx) +{ + return idx < assembly->stream_strings.size ? (const char *)&assembly->stream_strings.start[idx] : NULL; +} + +static HRESULT decode_int(const BYTE *encoded, ULONG *val, ULONG *len) +{ + if (!(encoded[0] & 0x80)) + { + *len = 1; + *val = encoded[0]; + } + else if (!(encoded[0] & 0x40)) + { + *len = 2; + *val = ((encoded[0] & ~0xc0) << 8) + encoded[1]; + } + else if (!(encoded[0] & 0x20)) + { + *len = 4; + *val = ((encoded[0] & ~0xe0) << 24) + (encoded[1] << 16) + (encoded[2] << 8) + encoded[3]; + } + else + return E_INVALIDARG; + return S_OK; +} + +HRESULT assembly_get_blob(const assembly_t *assembly, ULONG idx, const BYTE **blob, ULONG *size) +{ + const BYTE *ptr; + ULONG size_len; + HRESULT hr; + + if (idx >= assembly->stream_blobs.size) return E_INVALIDARG; + ptr = assembly->stream_blobs.start + idx; + if (FAILED(hr = decode_int(ptr, size, &size_len))) return hr; + *blob = ptr + size_len; + return S_OK; +} + +const GUID *assembly_get_guid(const assembly_t *assembly, ULONG idx) +{ + ULONG offset = (idx - 1) * sizeof(GUID); /* Indices into the GUID heap are 1-based */ + + return offset < assembly->stream_guids.size ? (const GUID *)(assembly->stream_guids.start + offset) : NULL; +} diff --git a/dlls/rometadata/mdtables.c b/dlls/rometadata/mdtables.c index 862582788d8..b66fac6487f 100644 --- a/dlls/rometadata/mdtables.c +++ b/dlls/rometadata/mdtables.c @@ -187,20 +187,23 @@ static HRESULT WINAPI tables_GetColumn(IMetaDataTables *iface, ULONG idx_tbl, UL
static HRESULT WINAPI tables_GetString(IMetaDataTables *iface, ULONG idx, const char **str) { - FIXME("(%p, %lu, %p): stub!\n", iface, idx, str); - return E_NOTIMPL; + struct metadata_tables *impl = impl_from_IMetaDataTables(iface); + TRACE("(%p, %lu, %p)\n", iface, idx, str); + return (*str = assembly_get_string(impl->assembly, idx)) ? S_OK : E_INVALIDARG; }
static HRESULT WINAPI tables_GetBlob(IMetaDataTables *iface, ULONG idx, ULONG *size, const BYTE **blob) { - FIXME("(%p, %lu, %p, %p): stub!\n", iface, idx, size, blob); - return E_NOTIMPL; + struct metadata_tables *impl = impl_from_IMetaDataTables(iface); + TRACE("(%p, %lu, %p, %p)\n", iface, idx, size, blob); + return assembly_get_blob(impl->assembly, idx, blob, size); }
static HRESULT WINAPI tables_GetGuid(IMetaDataTables *iface, ULONG idx, const GUID **guid) { - FIXME("(%p, %lu, %p): stub!\n", iface, idx, guid); - return E_NOTIMPL; + struct metadata_tables *impl = impl_from_IMetaDataTables(iface); + TRACE("(%p, %lu, %p)!\n", iface, idx, guid); + return (*guid = assembly_get_guid(impl->assembly, idx)) ? S_OK : E_INVALIDARG; }
static HRESULT WINAPI tables_GetUserString(IMetaDataTables *iface, ULONG idx, ULONG *size, const BYTE **string) diff --git a/dlls/rometadata/rometadatapriv.h b/dlls/rometadata/rometadatapriv.h index fe67903608d..3d1d2f21873 100644 --- a/dlls/rometadata/rometadatapriv.h +++ b/dlls/rometadata/rometadatapriv.h @@ -50,5 +50,8 @@ extern HRESULT assembly_open_from_file(const WCHAR *path, assembly_t **out); extern void assembly_free(assembly_t *assembly); extern HRESULT assembly_get_table(const assembly_t *assembly, ULONG table_idx, struct metadata_table_info *info); extern ULONG assembly_get_heap_size(const assembly_t *assembly, enum heap_type heap); +extern const char *assembly_get_string(const assembly_t *assembly, ULONG idx); +extern HRESULT assembly_get_blob(const assembly_t *assembly, ULONG idx, const BYTE **blob, ULONG *size); +extern const GUID *assembly_get_guid(const assembly_t *assembly, ULONG idx);
#endif /* __WINE_ROMETADATA_PRIVATE__ */ diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index b1dd9739eb6..03e39d61e77 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -337,15 +337,11 @@ static void test_MetaDataDispenser_OpenScope(void)
str = NULL; hr = IMetaDataTables_GetString(md_tables, module->Name, &str); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(str &&!strcmp(str, "dlls/rometadata/tests/test-simple.winmd"), "got str %s\n", debugstr_a(str));
hr = IMetaDataTables_GetGuid(md_tables, module->Mvid, &guid); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(!!guid, "got guid %p\n", guid);
/* Read defined types. */ @@ -363,18 +359,14 @@ static void test_MetaDataDispenser_OpenScope(void) ok(type_def->Flags == type_info->exp_flags, "got Flags %#lx != %#lx\n", type_def->Flags, type_info->exp_flags); str = NULL; hr = IMetaDataTables_GetString(md_tables, type_def->Name, &str); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(str && !strcmp(str, type_info->exp_name), "got str %s != %s\n", debugstr_a(str), debugstr_a(type_info->exp_name)); if (type_info->exp_namespace) { str = NULL; hr = IMetaDataTables_GetString(md_tables, type_def->Namespace, &str); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(str && !strcmp(str, type_info->exp_namespace), "got str %s != %s\n", debugstr_a(str), debugstr_a(type_info->exp_namespace)); if (!strcmp(type_info->exp_name, "ITest1") && !strcmp(type_info->exp_namespace, "Wine.Test")) @@ -395,7 +387,6 @@ static void test_MetaDataDispenser_OpenScope(void) ok(hr == S_OK, "got hr %#lx\n", hr);
hr = IMetaDataTables_GetString(md_tables, ref->Name, &str); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); if (str && !strcmp(str, ".ctor")) { @@ -422,7 +413,6 @@ static void test_MetaDataDispenser_OpenScope(void) winetest_pop_context(); }
- todo_wine ok(!!guid_ctor_idx, "got guid_ctor_coded_idx %lu\n", guid_ctor_idx);
/* Verify ITest1 has the correct GuidAttribute value. */