-- v3: rometadata: Implement IMetaDataImport::{EnumMembers, EnumMembersWithName, FindMember}. rometadata: Implement IMetaDataImport::{EnumFieldsWithName, FindField}. rometadata: Implement IMetaDataImport::FindMethod. rometadata: Implement IMetaDataImport::EnumMethodsWithName. rometadata/tests: Add tests for IMetaDataImport::{EnumMembersWithName, FindMember}.
From: Vibhav Pant vibhavp@gmail.com
--- dlls/rometadata/tests/rometadata.c | 49 ++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-)
diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index cce3c18455e..4cf918b410c 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -1010,15 +1010,15 @@ static void test_IMetaDataImport(void) static const WCHAR *guid_attribute_name = L"Windows.Foundation.Metadata.GuidAttribute";
const WCHAR *filename = load_resource(L"test-enum.winmd"); - ULONG buf_len, buf_count, str_len, str_reqd, i; + ULONG buf_len, buf_len2, buf_count, str_len, str_reqd, i; + mdMethodDef *methoddef_tokens, methoddef = mdMethodDefNil; mdTypeDef *typedef_tokens, typedef1, typedef2; - mdMethodDef *methoddef_tokens; + HCORENUM henum = NULL, henum2 = NULL; IMetaDataDispenser *dispenser; mdFieldDef *fielddef_tokens; mdProperty *property_tokens; IMetaDataImport *md_import; const BYTE *data = NULL; - HCORENUM henum = 0; const GUID *guid; WCHAR *strW; HRESULT hr; @@ -1173,11 +1173,54 @@ static void test_IMetaDataImport(void) todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); todo_wine ok(call_conv == method->exp_call_conv, "got call_conv %#lx != %#x\n", call_conv, method->exp_call_conv);
+ methoddef = mdMethodDefNil; + hr = IMetaDataImport_FindMethod(md_import, typedef2, name, sig_blob, sig_len, &methoddef); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(methoddef == methoddef_tokens[i], "got methoddef %s != %s\n", debugstr_mdToken(methoddef), + debugstr_mdToken(methoddef_tokens[i])); + methoddef = mdMethodDefNil; + hr = IMetaDataImport_FindMethod(md_import, typedef2, name, NULL, 0, &methoddef); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(methoddef == methoddef_tokens[i], "got methoddef %s != %s\n", debugstr_mdToken(methoddef), + debugstr_mdToken(methoddef_tokens[i])); + + henum2 = NULL; + methoddef = mdMethodDefNil; + hr = IMetaDataImport_EnumMethodsWithName(md_import, &henum2, typedef2, name, NULL, 0, NULL); + todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); + todo_wine ok(!!henum2, "got henum2 %p\n", henum2); + buf_len2 = 0; + hr = IMetaDataImport_CountEnum(md_import, henum2, &buf_len2); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == 1, "got buf_count2 %lu\n", buf_len2); + buf_len2 = 0; + hr = IMetaDataImport_EnumMethodsWithName(md_import, &henum2, typedef2, name, &methoddef, 1, &buf_len2); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == 1, "got count %lu\n", hr); + todo_wine ok(methoddef == methoddef_tokens[i], "got methoddef %s != %s\n", debugstr_mdToken(methoddef), + debugstr_mdToken(methoddef_tokens[i])); + IMetaDataImport_CloseEnum(md_import, henum2); + winetest_pop_context(); } + hr = IMetaDataImport_FindMethod(md_import, typedef2, NULL, NULL, 0, &methoddef); + todo_wine ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + hr = IMetaDataImport_FindMethod(md_import, typedef2, L"foo", NULL, 0, &methoddef); + todo_wine ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr); free(methoddef_tokens); IMetaDataImport_CloseEnum(md_import, henum);
+ henum = NULL; + /* EnumMethodsWithName with a NULL name is the same as EnumMethods. */ + hr = IMetaDataImport_EnumMethodsWithName(md_import, &henum, typedef2, NULL, NULL, 0, NULL); + todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); + todo_wine ok(!!henum, "got henum %p\n", henum); + buf_len2 = 0; + hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + IMetaDataImport_CloseEnum(md_import, henum); + for (i = 0; i < ARRAY_SIZE(field_enum_test_cases); i++) { const struct field_props *fields_props = field_enum_test_cases[i].field_props;
From: Vibhav Pant vibhavp@gmail.com
--- dlls/rometadata/tests/rometadata.c | 50 ++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-)
diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index 4cf918b410c..b000e467d3c 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -1011,11 +1011,11 @@ static void test_IMetaDataImport(void)
const WCHAR *filename = load_resource(L"test-enum.winmd"); ULONG buf_len, buf_len2, buf_count, str_len, str_reqd, i; - mdMethodDef *methoddef_tokens, methoddef = mdMethodDefNil; mdTypeDef *typedef_tokens, typedef1, typedef2; + mdMethodDef *methoddef_tokens, methoddef; + mdFieldDef *fielddef_tokens, fielddef; HCORENUM henum = NULL, henum2 = NULL; IMetaDataDispenser *dispenser; - mdFieldDef *fielddef_tokens; mdProperty *property_tokens; IMetaDataImport *md_import; const BYTE *data = NULL; @@ -1251,6 +1251,17 @@ static void test_IMetaDataImport(void) ok(buf_count == buf_len, "got buf_count %lu != %lu\n", buf_count, buf_len); IMetaDataImport_CloseEnum(md_import, henum);
+ henum = NULL; + /* EnumFieldsWithName with a NULL name is the same as EnumFields. */ + hr = IMetaDataImport_EnumFieldsWithName(md_import, &henum, typedef1, NULL, NULL, 0, NULL); + todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); + todo_wine ok(!!henum, "got henum %p\n", henum); + buf_len2 = 0; + hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + IMetaDataImport_CloseEnum(md_import, henum); + for (field_idx = 0; field_idx < buf_len; field_idx++) { ULONG flags = 0, sig_len = 0, value_type = 0, value_len = 0; @@ -1261,7 +1272,7 @@ static void test_IMetaDataImport(void)
winetest_push_context("field_idx=%lu", field_idx);
- test_token(md_import, fielddef_tokens[i], mdtFieldDef, FALSE); + test_token(md_import, fielddef_tokens[field_idx], mdtFieldDef, FALSE); name[0] = L'\0'; typedef2 = 0; hr = IMetaDataImport_GetFieldProps(md_import, fielddef_tokens[field_idx], &typedef2, name, ARRAY_SIZE(name), NULL, @@ -1280,12 +1291,45 @@ static void test_IMetaDataImport(void) if (props->has_value) ok(value && !memcmp(value, props->exp_value, props->value_len), "got unexpected value %p\n", value);
+ henum = NULL; + hr = IMetaDataImport_EnumFieldsWithName(md_import, &henum, typedef2, name, &fielddef, 0, NULL); + todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); + todo_wine ok(!!henum, "got henum %p\n", henum); + buf_len2 = 0; + hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == 1, "got buf_len2 %lu\n", buf_len2); + fielddef = mdFieldDefNil; + hr = IMetaDataImport_EnumFieldsWithName(md_import, &henum, typedef2, name, &fielddef, 1, NULL); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), + debugstr_mdToken(fielddef_tokens[field_idx])); + IMetaDataImport_CloseEnum(md_import, henum); + + fielddef = mdFieldDefNil; + hr = IMetaDataImport_FindField(md_import, typedef2, name, sig_blob, sig_len, &fielddef); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), + debugstr_mdToken(fielddef_tokens[field_idx])); + hr = IMetaDataImport_FindField(md_import, typedef2, name, sig_blob, sig_len, &fielddef); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + fielddef = mdFieldDefNil; + hr = IMetaDataImport_FindField(md_import, typedef2, name, NULL, 0, &fielddef); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), + debugstr_mdToken(fielddef_tokens[field_idx])); + winetest_pop_context(); } free(fielddef_tokens); winetest_pop_context(); }
+ hr = IMetaDataImport_FindField(md_import, typedef2, NULL, NULL, 0, &fielddef); + todo_wine ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + hr = IMetaDataImport_FindField(md_import, typedef2, L"foo", NULL, 0, &fielddef); + todo_wine ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr); + typedef1 = buf_len = 0; data = NULL; hr = IMetaDataImport_FindTypeDefByName(md_import, L"Wine.Test.ITest2", 0, &typedef1);
From: Vibhav Pant vibhavp@gmail.com
--- dlls/rometadata/tests/rometadata.c | 94 ++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+)
diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index b000e467d3c..fa653977de7 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -1020,6 +1020,7 @@ static void test_IMetaDataImport(void) IMetaDataImport *md_import; const BYTE *data = NULL; const GUID *guid; + mdToken token; WCHAR *strW; HRESULT hr; ULONG val; @@ -1201,6 +1202,30 @@ static void test_IMetaDataImport(void) debugstr_mdToken(methoddef_tokens[i])); IMetaDataImport_CloseEnum(md_import, henum2);
+ token = mdTokenNil; + hr = IMetaDataImport_FindMember(md_import, typedef2, name, sig_blob, sig_len, &token); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(token == methoddef_tokens[i], "got token %s != %s\n", debugstr_mdToken(token), + debugstr_mdToken(methoddef_tokens[i])); + token = mdTokenNil; + hr = IMetaDataImport_FindMember(md_import, typedef2, name, NULL, 0, &token); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(token == methoddef_tokens[i], "got token %s != %s\n", debugstr_mdToken(token), + debugstr_mdToken(methoddef_tokens[i])); + + henum2 = NULL; + token = mdTokenNil; + hr = IMetaDataImport_EnumMembersWithName(md_import, &henum2, typedef2, name, &token, 1, NULL); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(!!henum2, "got henum2 %p\n", henum2); + buf_len2 = 0; + hr = IMetaDataImport_CountEnum(md_import, henum2, &buf_len2); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == 1, "got buf_len2 %lu\n", buf_len2); + todo_wine ok(token == methoddef_tokens[i], "got token %s != %s\n", debugstr_mdToken(token), + debugstr_mdToken(methoddef_tokens[i])); + IMetaDataImport_CloseEnum(md_import, henum2); + winetest_pop_context(); } hr = IMetaDataImport_FindMethod(md_import, typedef2, NULL, NULL, 0, &methoddef); @@ -1221,6 +1246,26 @@ static void test_IMetaDataImport(void) todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); IMetaDataImport_CloseEnum(md_import, henum);
+ henum = NULL; + hr = IMetaDataImport_EnumMembers(md_import, &henum, typedef2, NULL, 0, NULL); + todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); + todo_wine ok(!!henum, "got henum %p\n", henum); + buf_len2 = 0; + hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + IMetaDataImport_CloseEnum(md_import, henum); + + henum = NULL; + hr = IMetaDataImport_EnumMembersWithName(md_import, &henum, typedef2, NULL, NULL, 0, NULL); + todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); + todo_wine ok(!!henum, "got henum %p\n", henum); + buf_len2 = 0; + hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + IMetaDataImport_CloseEnum(md_import, henum); + for (i = 0; i < ARRAY_SIZE(field_enum_test_cases); i++) { const struct field_props *fields_props = field_enum_test_cases[i].field_props; @@ -1262,6 +1307,26 @@ static void test_IMetaDataImport(void) todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); IMetaDataImport_CloseEnum(md_import, henum);
+ henum = NULL; + hr = IMetaDataImport_EnumMembers(md_import, &henum, typedef1, NULL, 0, NULL); + todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); + todo_wine ok(!!henum, "got henum %p\n", henum); + buf_len2 = 0; + hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + IMetaDataImport_CloseEnum(md_import, henum); + + henum = NULL; + hr = IMetaDataImport_EnumMembersWithName(md_import, &henum, typedef1, NULL, NULL, 0, NULL); + todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); + todo_wine ok(!!henum, "got henum %p\n", henum); + buf_len2 = 0; + hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + IMetaDataImport_CloseEnum(md_import, henum); + for (field_idx = 0; field_idx < buf_len; field_idx++) { ULONG flags = 0, sig_len = 0, value_type = 0, value_len = 0; @@ -1306,6 +1371,19 @@ static void test_IMetaDataImport(void) debugstr_mdToken(fielddef_tokens[field_idx])); IMetaDataImport_CloseEnum(md_import, henum);
+ henum = NULL; + fielddef = mdFieldDefNil; + hr = IMetaDataImport_EnumMembersWithName(md_import, &henum, typedef2, name, &fielddef, 1, NULL); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(!!henum, "got henum %p\n", henum); + buf_len2 = 0; + hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len2 == 1, "got buf_len2 %lu\n", buf_len2); + todo_wine ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), + debugstr_mdToken(fielddef_tokens[field_idx])); + IMetaDataImport_CloseEnum(md_import, henum); + fielddef = mdFieldDefNil; hr = IMetaDataImport_FindField(md_import, typedef2, name, sig_blob, sig_len, &fielddef); todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); @@ -1319,6 +1397,17 @@ static void test_IMetaDataImport(void) todo_wine ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), debugstr_mdToken(fielddef_tokens[field_idx]));
+ token = mdTokenNil; + hr = IMetaDataImport_FindMember(md_import, typedef2, name, sig_blob, sig_len, &token); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(token == fielddef_tokens[field_idx], "got token %s != %s\n", debugstr_mdToken(token), + debugstr_mdToken(fielddef_tokens[field_idx])); + token = mdTokenNil; + hr = IMetaDataImport_FindMember(md_import, typedef2, name, NULL, 0, &token); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(token == fielddef_tokens[field_idx], "got token %s != %s\n", debugstr_mdToken(token), + debugstr_mdToken(fielddef_tokens[field_idx])); + winetest_pop_context(); } free(fielddef_tokens); @@ -1330,6 +1419,11 @@ static void test_IMetaDataImport(void) hr = IMetaDataImport_FindField(md_import, typedef2, L"foo", NULL, 0, &fielddef); todo_wine ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr);
+ hr = IMetaDataImport_FindMember(md_import, typedef1, NULL, NULL, 0, &token); + todo_wine ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + hr = IMetaDataImport_FindMember(md_import, typedef1, L"foo", NULL, 0, &token); + todo_wine ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr); + typedef1 = buf_len = 0; data = NULL; hr = IMetaDataImport_FindTypeDefByName(md_import, L"Wine.Test.ITest2", 0, &typedef1);
From: Vibhav Pant vibhavp@gmail.com
--- dlls/rometadata/mdtables.c | 208 ++++++++++++++++++++++++----- dlls/rometadata/tests/rometadata.c | 20 +-- 2 files changed, 182 insertions(+), 46 deletions(-)
diff --git a/dlls/rometadata/mdtables.c b/dlls/rometadata/mdtables.c index 10e02ba9a10..435ad2b1fa3 100644 --- a/dlls/rometadata/mdtables.c +++ b/dlls/rometadata/mdtables.c @@ -321,33 +321,83 @@ static ULONG WINAPI import_Release(IMetaDataImport *iface) return IMetaDataTables_Release(&impl->IMetaDataTables_iface); }
+enum token_enum_type +{ + TOKEN_ENUM_RANGE, + TOKEN_ENUM_LIST +}; struct token_enum { - ULONG count; - ULONG row_start; - ULONG row_cur; - ULONG row_end; + enum token_enum_type type; + ULONG pos; + + union + { + struct + { + CorTokenType token_type; + ULONG start; + ULONG end; + } range; + struct + { + ULONG count; + mdToken tokens[1]; + } list; + } data; };
-HRESULT token_enum_create(HCORENUM *out) +static HRESULT token_enum_range_create(HCORENUM *out, CorTokenType type, ULONG row_start, ULONG row_end) { struct token_enum *md_enum;
+ assert(row_start <= row_end); if (!(md_enum = calloc(1, sizeof(*md_enum)))) return E_OUTOFMEMORY; + md_enum->type = TOKEN_ENUM_RANGE; + md_enum->data.range.token_type = type; + md_enum->pos = md_enum->data.range.start = row_start; + md_enum->data.range.end = row_end; *out = md_enum; return S_OK; }
-static HRESULT token_enum_get_entries(struct token_enum *henum, CorTokenType type, mdToken *buf, ULONG buf_len, - ULONG *buf_written) +static HRESULT token_enum_list_create(HCORENUM *out, ULONG count, const mdToken *tokens) { - ULONG i = 0; + struct token_enum *md_enum; + + assert(tokens && count); + if (!(md_enum = calloc(1, offsetof(struct token_enum, data.list.tokens[count])))) return E_OUTOFMEMORY; + md_enum->type = TOKEN_ENUM_LIST; + md_enum->pos = 0; + md_enum->data.list.count = count; + memcpy(md_enum->data.list.tokens, tokens, count * sizeof(*tokens)); + *out = md_enum; + return S_OK; +} + +static HRESULT token_enum_get_entries(struct token_enum *henum, mdToken *buf, ULONG buf_len, ULONG *buf_written) +{ + ULONG n = 0; + + switch (henum->type) + { + case TOKEN_ENUM_RANGE: + while (henum->pos <= henum->data.range.end && n < buf_len) + buf[n++] = TokenFromRid(henum->pos++, henum->data.range.token_type); + break; + case TOKEN_ENUM_LIST: + if (henum->pos < henum->data.list.count) + { + n = min(buf_len, henum->data.list.count - henum->pos); + memcpy(buf, &henum->data.list.tokens[henum->pos], n * sizeof(*buf)); + henum->pos += n; + } + break; + }
- while (henum->row_cur <= henum->row_end && i < buf_len) - buf[i++] = TokenFromRid(henum->row_cur++, type); if (buf_written) - *buf_written = i; - return !!i ? S_OK : S_FALSE; + *buf_written = n; + return !!n ? S_OK : S_FALSE; }
static void WINAPI import_CloseEnum(IMetaDataImport *iface, HCORENUM henum) @@ -362,7 +412,23 @@ static HRESULT WINAPI import_CountEnum(IMetaDataImport *iface, HCORENUM henum, U
TRACE("(%p, %p, %p)\n", iface, henum, count);
- *count = henum ? md_enum->count : 0; + if (!henum) + { + *count = 0; + return S_OK; + } + switch (md_enum->type) + { + case TOKEN_ENUM_RANGE: + assert(md_enum->data.range.start && md_enum->data.range.start <= md_enum->data.range.end); + *count = md_enum->data.range.end - md_enum->data.range.start + 1; + break; + case TOKEN_ENUM_LIST: + *count = md_enum->data.list.count; + break; + DEFAULT_UNREACHABLE; + } + return S_OK; }
@@ -372,8 +438,17 @@ static HRESULT WINAPI import_ResetEnum(IMetaDataImport *iface, HCORENUM henum, U
TRACE("(%p, %p, %lu)\n", iface, henum, idx);
- if (henum) - md_enum->row_cur = md_enum->row_start + idx; + if (!henum) return S_OK; + switch (md_enum->type) + { + case TOKEN_ENUM_RANGE: + md_enum->pos = md_enum->data.range.start + idx; + break; + case TOKEN_ENUM_LIST: + md_enum->pos = idx; + break; + DEFAULT_UNREACHABLE; + } return S_OK; }
@@ -438,7 +513,6 @@ static HRESULT table_get_num_rows(IMetaDataTables *iface, enum table table, ULON static HRESULT WINAPI import_EnumTypeDefs(IMetaDataImport *iface, HCORENUM *ret_henum, mdTypeDef *typedefs, ULONG len, ULONG *count) { struct metadata_tables *impl = impl_from_IMetaDataImport(iface); - struct token_enum *henum = *ret_henum; ULONG rows; HRESULT hr;
@@ -447,21 +521,16 @@ static HRESULT WINAPI import_EnumTypeDefs(IMetaDataImport *iface, HCORENUM *ret_ if (count) *count = 0;
- if (!henum) + if (!*ret_henum) { hr = table_get_num_rows(&impl->IMetaDataTables_iface, TABLE_TYPEDEF, &rows); if (FAILED(hr)) return hr; /* Skip the <Module> row. */ if (rows < 2) return S_FALSE; - if (FAILED((hr = token_enum_create((HCORENUM *)&henum)))) return hr; - - henum->count = rows - 1; - henum->row_start = henum->row_cur = 2; - henum->row_end = rows; - *ret_henum = henum; + if (FAILED((hr = token_enum_range_create(ret_henum, mdtTypeDef, 2, rows)))) return hr; }
- return token_enum_get_entries(henum, mdtTypeDef, typedefs, len, count); + return token_enum_get_entries(*ret_henum, typedefs, len, count); }
static HRESULT WINAPI import_EnumInterfaceImpls(IMetaDataImport *iface, HCORENUM *henum, mdTypeDef type_def, @@ -741,6 +810,7 @@ static HRESULT table_create_enum_from_token_list(IMetaDataTables *iface, enum ta if (FAILED((hr = table_get_num_rows(iface, table, &num_rows)))) return hr; if (row > num_rows) return S_FALSE; if (FAILED((hr = IMetaDataTables_GetColumn(iface, table, col, row, &row_start)))) return hr; + if (IsNilToken(row_start)) return S_FALSE; row_start = RidFromToken(row_start);
if (row != num_rows) @@ -753,11 +823,8 @@ static HRESULT table_create_enum_from_token_list(IMetaDataTables *iface, enum ta else if (FAILED((hr = table_get_num_rows(iface, list_table, &row_end)))) return hr;
- if (FAILED((hr = token_enum_create((HCORENUM *)&henum)))) return hr; - - henum->count = row_end - row_start + 1; - henum->row_start = henum->row_cur = row_start; - henum->row_end = row_end; + if (row_end < row_start) return S_FALSE; + if (FAILED((hr = token_enum_range_create((HCORENUM *)&henum, list_table << 24, row_start, row_end)))) return hr; *ret_henum = henum; return S_OK; } @@ -786,14 +853,83 @@ static HRESULT WINAPI import_EnumMethods(IMetaDataImport *iface, HCORENUM *ret_h if (hr != S_OK) return hr; }
- return token_enum_get_entries(*ret_henum, mdtMethodDef, method_defs, len, count); + return token_enum_get_entries(*ret_henum, method_defs, len, count); }
-static HRESULT WINAPI import_EnumMethodsWithName(IMetaDataImport *iface, HCORENUM *henum, mdTypeDef type_def, - const WCHAR *name, mdMethodDef *method_defs, ULONG len, ULONG *count) +static HRESULT WINAPI import_EnumMethodsWithName(IMetaDataImport *iface, HCORENUM *ret_henum, mdTypeDef type_def, + const WCHAR *name, mdMethodDef *method_defs, ULONG len, ULONG *ret_count) { - FIXME("(%p, %p, %#x, %s, %p, %lu, %p): stub!\n", iface, henum, type_def, debugstr_w(name), method_defs, len, count); - return E_NOTIMPL; + TRACE("(%p, %p, %s, %s, %p, %lu, %p)\n", iface, ret_henum, debugstr_mdToken(type_def), debugstr_w(name), + method_defs, len, ret_count); + + if (!name) return IMetaDataImport_EnumMethods(iface, ret_henum, type_def, method_defs, len, ret_count); + if (ret_count) *ret_count = 0; + if (TypeFromToken(type_def) != mdtTypeDef || IsNilToken(type_def)) return S_FALSE; + + if (!*ret_henum) + { + mdMethodDef cur_method, *methods; + ULONG cur_name_len = 80, count; + HCORENUM all_methods = NULL; + WCHAR *cur_name, *tmp; + HRESULT hr; + + if (!(cur_name = malloc(sizeof(WCHAR) * cur_name_len))) return E_OUTOFMEMORY; + hr = IMetaDataImport_EnumMethods(iface, &all_methods, type_def, &cur_method, 1, NULL); + if (hr != S_OK) + { + free(cur_name); + return hr; + } + if (FAILED((hr = IMetaDataImport_CountEnum(iface, all_methods, &count)))) + { + free(cur_name); + IMetaDataImport_CloseEnum(iface, all_methods); + return hr; + } + if (!(methods = calloc(count, sizeof(*methods)))) + { + free(cur_name); + IMetaDataImport_CloseEnum(iface, all_methods); + return E_OUTOFMEMORY; + } + count = 0; + while (hr == S_OK) + { + ULONG reqd; + + hr = IMetaDataImport_GetMethodProps(iface, cur_method, NULL, cur_name, cur_name_len, &reqd, NULL, NULL, + NULL, NULL, NULL); + if (hr == CLDB_E_TRUNCATION) + { + cur_name_len = reqd; + if (!(tmp = realloc(cur_name, sizeof(WCHAR) * cur_name_len))) + { + hr = E_OUTOFMEMORY; + break; + } + cur_name = tmp; + continue; /* Try again */ + } + else if (FAILED(hr)) + break; + if (!wcsncmp(cur_name, name, reqd)) + methods[count++] = cur_method; + hr = IMetaDataImport_EnumMethods(iface, &all_methods, type_def, &cur_method, 1, NULL); + } + + free(cur_name); + IMetaDataImport_CloseEnum(iface, all_methods); + if (FAILED(hr) || !count) + { + free(methods); + return FAILED(hr) ? hr : S_FALSE; + } + hr = token_enum_list_create(ret_henum, count, methods); + free(methods); + if (FAILED(hr)) return hr; + } + return token_enum_get_entries(*ret_henum, method_defs, len, ret_count); }
static HRESULT WINAPI import_EnumFields(IMetaDataImport *iface, HCORENUM *ret_henum, mdTypeDef token, @@ -820,7 +956,7 @@ static HRESULT WINAPI import_EnumFields(IMetaDataImport *iface, HCORENUM *ret_he if (hr != S_OK) return hr; }
- return token_enum_get_entries(*ret_henum, mdtFieldDef, field_defs, len, count); + return token_enum_get_entries(*ret_henum, field_defs, len, count); }
static HRESULT WINAPI import_EnumFieldsWithName(IMetaDataImport *iface, HCORENUM *henum, mdTypeDef token, @@ -1038,7 +1174,7 @@ static HRESULT WINAPI import_EnumProperties(IMetaDataImport *iface, HCORENUM *re if (!*ret_henum) return S_FALSE; }
- return token_enum_get_entries(*ret_henum, mdtProperty, props, len, count); + return token_enum_get_entries(*ret_henum, props, len, count); }
static HRESULT WINAPI import_EnumEvents(IMetaDataImport *iface, HCORENUM *henum, mdTypeDef type_def, mdEvent *events, diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index fa653977de7..cf6b61abed5 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -1188,18 +1188,18 @@ static void test_IMetaDataImport(void) henum2 = NULL; methoddef = mdMethodDefNil; hr = IMetaDataImport_EnumMethodsWithName(md_import, &henum2, typedef2, name, NULL, 0, NULL); - todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); - todo_wine ok(!!henum2, "got henum2 %p\n", henum2); + ok(hr == S_FALSE, "got hr %#lx\n", hr); + ok(!!henum2, "got henum2 %p\n", henum2); buf_len2 = 0; hr = IMetaDataImport_CountEnum(md_import, henum2, &buf_len2); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == 1, "got buf_count2 %lu\n", buf_len2); + ok(buf_len2 == 1, "got buf_count2 %lu\n", buf_len2); buf_len2 = 0; hr = IMetaDataImport_EnumMethodsWithName(md_import, &henum2, typedef2, name, &methoddef, 1, &buf_len2); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == 1, "got count %lu\n", hr); - todo_wine ok(methoddef == methoddef_tokens[i], "got methoddef %s != %s\n", debugstr_mdToken(methoddef), - debugstr_mdToken(methoddef_tokens[i])); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(buf_len2 == 1, "got count %lu\n", hr); + ok(methoddef == methoddef_tokens[i], "got methoddef %s != %s\n", debugstr_mdToken(methoddef), + debugstr_mdToken(methoddef_tokens[i])); IMetaDataImport_CloseEnum(md_import, henum2);
token = mdTokenNil; @@ -1238,12 +1238,12 @@ static void test_IMetaDataImport(void) henum = NULL; /* EnumMethodsWithName with a NULL name is the same as EnumMethods. */ hr = IMetaDataImport_EnumMethodsWithName(md_import, &henum, typedef2, NULL, NULL, 0, NULL); - todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); - todo_wine ok(!!henum, "got henum %p\n", henum); + ok(hr == S_FALSE, "got hr %#lx\n", hr); + ok(!!henum, "got henum %p\n", henum); buf_len2 = 0; hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); IMetaDataImport_CloseEnum(md_import, henum);
henum = NULL;
From: Vibhav Pant vibhavp@gmail.com
--- dlls/rometadata/mdtables.c | 33 ++++++++++++++++++++++++++++-- dlls/rometadata/tests/rometadata.c | 16 +++++++-------- 2 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/dlls/rometadata/mdtables.c b/dlls/rometadata/mdtables.c index 435ad2b1fa3..70072666986 100644 --- a/dlls/rometadata/mdtables.c +++ b/dlls/rometadata/mdtables.c @@ -1004,8 +1004,37 @@ static HRESULT WINAPI import_FindMember(IMetaDataImport *iface, mdTypeDef type_d static HRESULT WINAPI import_FindMethod(IMetaDataImport *iface, mdTypeDef type_def, const WCHAR *name, const COR_SIGNATURE *sig_blob, ULONG len, mdMethodDef *method_def) { - FIXME("(%p, %#x, %s, %p, %lu, %p): stub!\n", iface, type_def, debugstr_w(name), sig_blob, len, method_def); - return E_NOTIMPL; + mdMethodDef cur_method; + HCORENUM henum = NULL; + BOOL found = FALSE; + HRESULT hr; + + TRACE("(%p, %s, %s, %p, %lu, %p):\n", iface, debugstr_mdToken(type_def), debugstr_w(name), sig_blob, len, + method_def); + + if (!name) return E_INVALIDARG; + if (IsNilToken(type_def) || TypeFromToken(type_def) != mdtTypeDef) return CLDB_E_RECORD_NOTFOUND; + + if (FAILED((hr = IMetaDataImport_EnumMethodsWithName(iface, &henum, type_def, name, &cur_method, 1, NULL)))) return hr; + while (hr == S_OK) + { + const COR_SIGNATURE *cur_sig; + ULONG cur_sig_len; + + hr = IMetaDataImport_GetMethodProps(iface, cur_method, NULL, NULL, 0, NULL, NULL, &cur_sig, &cur_sig_len, NULL, + NULL); + if (FAILED(hr)) break; + if (!(len && sig_blob) || (len == cur_sig_len && !memcmp(cur_sig, sig_blob, len))) + { + found = TRUE; + break; + } + hr = IMetaDataImport_EnumMethodsWithName(iface, &henum, type_def, name, &cur_method, 1, NULL); + } + IMetaDataImport_CloseEnum(iface, henum); + + *method_def = found ? cur_method : mdMethodDefNil; + return FAILED(hr) ? hr : (found ? S_OK : CLDB_E_RECORD_NOTFOUND); }
static HRESULT WINAPI import_FindField(IMetaDataImport *iface, mdTypeDef type_def, const WCHAR *name, diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index cf6b61abed5..06a12286fff 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -1176,14 +1176,14 @@ static void test_IMetaDataImport(void)
methoddef = mdMethodDefNil; hr = IMetaDataImport_FindMethod(md_import, typedef2, name, sig_blob, sig_len, &methoddef); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(methoddef == methoddef_tokens[i], "got methoddef %s != %s\n", debugstr_mdToken(methoddef), - debugstr_mdToken(methoddef_tokens[i])); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(methoddef == methoddef_tokens[i], "got methoddef %s != %s\n", debugstr_mdToken(methoddef), + debugstr_mdToken(methoddef_tokens[i])); methoddef = mdMethodDefNil; hr = IMetaDataImport_FindMethod(md_import, typedef2, name, NULL, 0, &methoddef); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(methoddef == methoddef_tokens[i], "got methoddef %s != %s\n", debugstr_mdToken(methoddef), - debugstr_mdToken(methoddef_tokens[i])); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(methoddef == methoddef_tokens[i], "got methoddef %s != %s\n", debugstr_mdToken(methoddef), + debugstr_mdToken(methoddef_tokens[i]));
henum2 = NULL; methoddef = mdMethodDefNil; @@ -1229,9 +1229,9 @@ static void test_IMetaDataImport(void) winetest_pop_context(); } hr = IMetaDataImport_FindMethod(md_import, typedef2, NULL, NULL, 0, &methoddef); - todo_wine ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); hr = IMetaDataImport_FindMethod(md_import, typedef2, L"foo", NULL, 0, &methoddef); - todo_wine ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr); + ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr); free(methoddef_tokens); IMetaDataImport_CloseEnum(md_import, henum);
From: Vibhav Pant vibhavp@gmail.com
--- dlls/rometadata/mdtables.c | 110 +++++++++++++++++++++++++++-- dlls/rometadata/tests/rometadata.c | 36 +++++----- 2 files changed, 122 insertions(+), 24 deletions(-)
diff --git a/dlls/rometadata/mdtables.c b/dlls/rometadata/mdtables.c index 70072666986..7cb026a41a7 100644 --- a/dlls/rometadata/mdtables.c +++ b/dlls/rometadata/mdtables.c @@ -959,11 +959,80 @@ static HRESULT WINAPI import_EnumFields(IMetaDataImport *iface, HCORENUM *ret_he return token_enum_get_entries(*ret_henum, field_defs, len, count); }
-static HRESULT WINAPI import_EnumFieldsWithName(IMetaDataImport *iface, HCORENUM *henum, mdTypeDef token, - const WCHAR *name, mdFieldDef *field_defs, ULONG len, ULONG *count) +static HRESULT WINAPI import_EnumFieldsWithName(IMetaDataImport *iface, HCORENUM *ret_henum, mdTypeDef token, + const WCHAR *name, mdFieldDef *field_defs, ULONG len, ULONG *ret_count) { - FIXME("(%p, %p, %#x, %s, %p, %lu, %p): stub!\n", iface, henum, token, debugstr_w(name), field_defs, len, count); - return E_NOTIMPL; + TRACE("(%p, %p, %s, %s, %p, %lu, %p)\n", iface, ret_henum, debugstr_mdToken(token), debugstr_w(name), field_defs, + len, ret_count); + + if (!name) return IMetaDataImport_EnumFields(iface, ret_henum, token, field_defs, len, ret_count); + if (ret_count) *ret_count = 0; + if (TypeFromToken(token) != mdtTypeDef || IsNilToken(token)) return S_FALSE; + + if (!*ret_henum) + { + ULONG cur_name_len = 80, count; + mdFieldDef cur_field, *fields; + HCORENUM all_fields = NULL; + WCHAR *cur_name, *tmp; + HRESULT hr; + + if (!(cur_name = malloc(sizeof(WCHAR) * cur_name_len))) return E_OUTOFMEMORY; + hr = IMetaDataImport_EnumFields(iface, &all_fields, token, &cur_field, 1, NULL); + if (hr != S_OK) + { + free(cur_name); + return hr; + } + if (FAILED((hr = IMetaDataImport_CountEnum(iface, all_fields, &count)))) + { + IMetaDataImport_CloseEnum(iface, all_fields); + free(cur_name); + return hr; + } + if (!(fields = calloc(count, sizeof(*fields)))) + { + IMetaDataImport_CloseEnum(iface, all_fields); + free(cur_name); + return E_OUTOFMEMORY; + } + count = 0; + while (hr == S_OK) + { + ULONG reqd; + + hr = IMetaDataImport_GetFieldProps(iface, cur_field, NULL, cur_name, cur_name_len, &reqd, NULL, NULL, NULL, + NULL, NULL, NULL); + if (hr == CLDB_E_TRUNCATION) + { + cur_name_len = reqd; + if (!(tmp = realloc(cur_name, sizeof(WCHAR) * cur_name_len))) + { + hr = E_OUTOFMEMORY; + break; + } + cur_name = tmp; + continue; + } + else if (FAILED(hr)) + break; + if (!wcsncmp(cur_name, name, reqd)) + fields[count++] = cur_field; + hr = IMetaDataImport_EnumFields(iface, &all_fields, token, &cur_field, 1, NULL); + } + + free(cur_name); + IMetaDataImport_CloseEnum(iface, all_fields); + if (FAILED(hr) || !count) + { + free(fields); + return FAILED(hr) ? hr : S_FALSE; + } + hr = token_enum_list_create(ret_henum, count, fields); + free(fields); + if (FAILED(hr)) return hr; + } + return token_enum_get_entries(*ret_henum, field_defs, len, ret_count); }
static HRESULT WINAPI import_EnumParams(IMetaDataImport *iface, HCORENUM *henum, mdMethodDef method_def, @@ -1040,8 +1109,37 @@ static HRESULT WINAPI import_FindMethod(IMetaDataImport *iface, mdTypeDef type_d static HRESULT WINAPI import_FindField(IMetaDataImport *iface, mdTypeDef type_def, const WCHAR *name, const COR_SIGNATURE *sig_blob, ULONG len, mdFieldDef *field_def) { - FIXME("(%p, %#x, %s, %p, %lu, %p): stub!\n", iface, type_def, debugstr_w(name), sig_blob, len, field_def); - return E_NOTIMPL; + HCORENUM henum = NULL; + mdFieldDef cur_field; + BOOL found = FALSE; + HRESULT hr; + + TRACE("(%p, %s, %s, %p, %lu, %p)\n", iface, debugstr_mdToken(type_def), debugstr_w(name), sig_blob, len, field_def); + + if (!name) return E_INVALIDARG; + if (IsNilToken(type_def) || TypeFromToken(type_def) != mdtTypeDef) return CLDB_E_RECORD_NOTFOUND; + + if (FAILED((hr = IMetaDataImport_EnumFieldsWithName(iface, &henum, type_def, name, &cur_field, 1, NULL)))) + return hr; + while (hr == S_OK) + { + const COR_SIGNATURE *cur_sig; + ULONG cur_sig_len; + + hr = IMetaDataImport_GetFieldProps(iface, cur_field, NULL, NULL, 0, NULL, NULL, &cur_sig, &cur_sig_len, NULL, + NULL, NULL); + if (FAILED(hr)) break; + if (!(len && sig_blob) || (len && sig_blob && len == cur_sig_len && !memcmp(cur_sig, sig_blob, len))) + { + found = TRUE; + break; + } + hr = IMetaDataImport_EnumFieldsWithName(iface, &henum, type_def, name, &cur_field, 1, NULL); + } + IMetaDataImport_CloseEnum(iface, henum); + + *field_def = found ? cur_field : mdFieldDefNil; + return FAILED(hr) ? hr : (found ? S_OK : CLDB_E_RECORD_NOTFOUND); }
static HRESULT WINAPI import_FindMemberRef(IMetaDataImport *iface, mdTypeRef typeref, const WCHAR *name, diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index 06a12286fff..a426934a399 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -1299,12 +1299,12 @@ static void test_IMetaDataImport(void) henum = NULL; /* EnumFieldsWithName with a NULL name is the same as EnumFields. */ hr = IMetaDataImport_EnumFieldsWithName(md_import, &henum, typedef1, NULL, NULL, 0, NULL); - todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); - todo_wine ok(!!henum, "got henum %p\n", henum); + ok(hr == S_FALSE, "got hr %#lx\n", hr); + ok(!!henum, "got henum %p\n", henum); buf_len2 = 0; hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); IMetaDataImport_CloseEnum(md_import, henum);
henum = NULL; @@ -1358,17 +1358,17 @@ static void test_IMetaDataImport(void)
henum = NULL; hr = IMetaDataImport_EnumFieldsWithName(md_import, &henum, typedef2, name, &fielddef, 0, NULL); - todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); - todo_wine ok(!!henum, "got henum %p\n", henum); + ok(hr == S_FALSE, "got hr %#lx\n", hr); + ok(!!henum, "got henum %p\n", henum); buf_len2 = 0; hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == 1, "got buf_len2 %lu\n", buf_len2); + ok(buf_len2 == 1, "got buf_len2 %lu\n", buf_len2); fielddef = mdFieldDefNil; hr = IMetaDataImport_EnumFieldsWithName(md_import, &henum, typedef2, name, &fielddef, 1, NULL); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), - debugstr_mdToken(fielddef_tokens[field_idx])); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), + debugstr_mdToken(fielddef_tokens[field_idx])); IMetaDataImport_CloseEnum(md_import, henum);
henum = NULL; @@ -1386,16 +1386,16 @@ static void test_IMetaDataImport(void)
fielddef = mdFieldDefNil; hr = IMetaDataImport_FindField(md_import, typedef2, name, sig_blob, sig_len, &fielddef); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), - debugstr_mdToken(fielddef_tokens[field_idx])); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), + debugstr_mdToken(fielddef_tokens[field_idx])); hr = IMetaDataImport_FindField(md_import, typedef2, name, sig_blob, sig_len, &fielddef); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + ok(hr == S_OK, "got hr %#lx\n", hr); fielddef = mdFieldDefNil; hr = IMetaDataImport_FindField(md_import, typedef2, name, NULL, 0, &fielddef); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), - debugstr_mdToken(fielddef_tokens[field_idx])); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), + debugstr_mdToken(fielddef_tokens[field_idx]));
token = mdTokenNil; hr = IMetaDataImport_FindMember(md_import, typedef2, name, sig_blob, sig_len, &token); @@ -1415,9 +1415,9 @@ static void test_IMetaDataImport(void) }
hr = IMetaDataImport_FindField(md_import, typedef2, NULL, NULL, 0, &fielddef); - todo_wine ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); hr = IMetaDataImport_FindField(md_import, typedef2, L"foo", NULL, 0, &fielddef); - todo_wine ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr); + ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr);
hr = IMetaDataImport_FindMember(md_import, typedef1, NULL, NULL, 0, &token); todo_wine ok(hr == E_INVALIDARG, "got hr %#lx\n", hr);
From: Vibhav Pant vibhavp@gmail.com
--- dlls/rometadata/mdtables.c | 70 ++++++++++++++++++++++++++--- dlls/rometadata/tests/rometadata.c | 72 +++++++++++++++--------------- 2 files changed, 100 insertions(+), 42 deletions(-)
diff --git a/dlls/rometadata/mdtables.c b/dlls/rometadata/mdtables.c index 7cb026a41a7..01a6190fc84 100644 --- a/dlls/rometadata/mdtables.c +++ b/dlls/rometadata/mdtables.c @@ -789,15 +789,62 @@ static HRESULT WINAPI import_ResolveTypeRef(IMetaDataImport *iface, mdTypeRef ty static HRESULT WINAPI import_EnumMembers(IMetaDataImport *iface, HCORENUM *henum, mdTypeDef type_def, mdToken *member_defs, ULONG len, ULONG *count) { - FIXME("(%p, %p, %#x, %p, %lu, %p): stub!\n", iface, henum, type_def, member_defs, len, count); - return E_NOTIMPL; + TRACE("(%p, %p, %s, %p, %lu, %p)\n", iface, henum, debugstr_mdToken(type_def), member_defs, len, count); + return IMetaDataImport_EnumMembersWithName(iface, henum, type_def, NULL, member_defs, len, count); }
static HRESULT WINAPI import_EnumMembersWithName(IMetaDataImport *iface, HCORENUM *henum, mdTypeDef token, const WCHAR *name, mdToken *member_defs, ULONG len, ULONG *count) { - FIXME("(%p, %p, %#x, %s, %p, %lu, %p): stub!\n", iface, henum, token, debugstr_w(name), member_defs, len, count); - return E_NOTIMPL; + TRACE("(%p, %p, %s, %s, %p, %lu, %p)\n", iface, henum, debugstr_mdToken(token), debugstr_w(name), member_defs, len, + count); + + if (!*henum) + { + HCORENUM methods_enum = NULL, fields_enum = NULL; + ULONG methods_len, fields_len; + mdToken *tokens = NULL; + HRESULT hr; + + if (FAILED((hr = IMetaDataImport_EnumMethodsWithName(iface, &methods_enum, token, name, NULL, 0, NULL)))) + return hr; + if (FAILED((hr = IMetaDataImport_CountEnum(iface, methods_enum, &methods_len)))) goto done; + + if (FAILED((hr = IMetaDataImport_EnumFieldsWithName(iface, &fields_enum, token, name, NULL, 0, NULL)))) + goto done; + if (FAILED((hr = IMetaDataImport_CountEnum(iface, fields_enum, &fields_len)))) goto done; + + if (!methods_len && !fields_len) + { + hr = S_FALSE; + goto done; + } + if (!(tokens = calloc(methods_len + fields_len, sizeof(*tokens)))) + { + hr = E_OUTOFMEMORY; + goto done; + } + if (methods_len) + { + hr = IMetaDataImport_EnumMethodsWithName(iface, &methods_enum, token, name, tokens, methods_len, NULL); + if (FAILED(hr)) goto done; + } + if (fields_len) + { + hr = IMetaDataImport_EnumFieldsWithName(iface, &fields_enum, token, name, &tokens[methods_len], fields_len, + NULL); + if (FAILED(hr)) goto done; + } + done: + IMetaDataImport_CloseEnum(iface, methods_enum); + IMetaDataImport_CloseEnum(iface, fields_enum); + if (hr == S_OK) + hr = token_enum_list_create(henum, methods_len + fields_len, tokens); + free(tokens); + if (hr != S_OK) return hr; + } + + return token_enum_get_entries(*henum, member_defs, len, count); }
static HRESULT table_create_enum_from_token_list(IMetaDataTables *iface, enum table table, enum table list_table, @@ -1066,8 +1113,19 @@ static HRESULT WINAPI import_EnumPermissionSets(IMetaDataImport *iface, HCORENUM static HRESULT WINAPI import_FindMember(IMetaDataImport *iface, mdTypeDef type_def, const WCHAR *name, const COR_SIGNATURE *sig_blob, ULONG len, mdToken *member_ref) { - FIXME("(%p, %#x, %s, %p, %lu, %p): stub!\n", iface, type_def, debugstr_w(name), sig_blob, len, member_ref); - return E_NOTIMPL; + HRESULT hr; + + TRACE("(%p, %s, %s, %p, %lu, %p)\n", iface, debugstr_mdToken(type_def), debugstr_w(name), sig_blob, len, + member_ref); + + if (!name) return E_INVALIDARG; + if (IsNilToken(type_def) || TypeFromToken(type_def) != mdtTypeDef) return S_FALSE; + + /* If a method and a field have the same name, native returns the method. */ + hr = IMetaDataImport_FindMethod(iface, type_def, name, sig_blob, len, member_ref); + if (hr == CLDB_E_RECORD_NOTFOUND) + hr = IMetaDataImport_FindField(iface, type_def, name, sig_blob, len, member_ref); + return hr; }
static HRESULT WINAPI import_FindMethod(IMetaDataImport *iface, mdTypeDef type_def, const WCHAR *name, diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index a426934a399..733ded128b7 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -1204,26 +1204,26 @@ static void test_IMetaDataImport(void)
token = mdTokenNil; hr = IMetaDataImport_FindMember(md_import, typedef2, name, sig_blob, sig_len, &token); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(token == methoddef_tokens[i], "got token %s != %s\n", debugstr_mdToken(token), - debugstr_mdToken(methoddef_tokens[i])); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(token == methoddef_tokens[i], "got token %s != %s\n", debugstr_mdToken(token), + debugstr_mdToken(methoddef_tokens[i])); token = mdTokenNil; hr = IMetaDataImport_FindMember(md_import, typedef2, name, NULL, 0, &token); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(token == methoddef_tokens[i], "got token %s != %s\n", debugstr_mdToken(token), - debugstr_mdToken(methoddef_tokens[i])); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(token == methoddef_tokens[i], "got token %s != %s\n", debugstr_mdToken(token), + debugstr_mdToken(methoddef_tokens[i]));
henum2 = NULL; token = mdTokenNil; hr = IMetaDataImport_EnumMembersWithName(md_import, &henum2, typedef2, name, &token, 1, NULL); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(!!henum2, "got henum2 %p\n", henum2); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(!!henum2, "got henum2 %p\n", henum2); buf_len2 = 0; hr = IMetaDataImport_CountEnum(md_import, henum2, &buf_len2); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == 1, "got buf_len2 %lu\n", buf_len2); - todo_wine ok(token == methoddef_tokens[i], "got token %s != %s\n", debugstr_mdToken(token), - debugstr_mdToken(methoddef_tokens[i])); + ok(buf_len2 == 1, "got buf_len2 %lu\n", buf_len2); + ok(token == methoddef_tokens[i], "got token %s != %s\n", debugstr_mdToken(token), + debugstr_mdToken(methoddef_tokens[i])); IMetaDataImport_CloseEnum(md_import, henum2);
winetest_pop_context(); @@ -1248,22 +1248,22 @@ static void test_IMetaDataImport(void)
henum = NULL; hr = IMetaDataImport_EnumMembers(md_import, &henum, typedef2, NULL, 0, NULL); - todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); - todo_wine ok(!!henum, "got henum %p\n", henum); + ok(hr == S_FALSE, "got hr %#lx\n", hr); + ok(!!henum, "got henum %p\n", henum); buf_len2 = 0; hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); IMetaDataImport_CloseEnum(md_import, henum);
henum = NULL; hr = IMetaDataImport_EnumMembersWithName(md_import, &henum, typedef2, NULL, NULL, 0, NULL); - todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); - todo_wine ok(!!henum, "got henum %p\n", henum); + ok(hr == S_FALSE, "got hr %#lx\n", hr); + ok(!!henum, "got henum %p\n", henum); buf_len2 = 0; hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); IMetaDataImport_CloseEnum(md_import, henum);
for (i = 0; i < ARRAY_SIZE(field_enum_test_cases); i++) @@ -1309,22 +1309,22 @@ static void test_IMetaDataImport(void)
henum = NULL; hr = IMetaDataImport_EnumMembers(md_import, &henum, typedef1, NULL, 0, NULL); - todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); - todo_wine ok(!!henum, "got henum %p\n", henum); + ok(hr == S_FALSE, "got hr %#lx\n", hr); + ok(!!henum, "got henum %p\n", henum); buf_len2 = 0; hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); IMetaDataImport_CloseEnum(md_import, henum);
henum = NULL; hr = IMetaDataImport_EnumMembersWithName(md_import, &henum, typedef1, NULL, NULL, 0, NULL); - todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); - todo_wine ok(!!henum, "got henum %p\n", henum); + ok(hr == S_FALSE, "got hr %#lx\n", hr); + ok(!!henum, "got henum %p\n", henum); buf_len2 = 0; hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); + ok(buf_len2 == buf_len, "got buf_len2 %lu != %lu\n", buf_len2, buf_len); IMetaDataImport_CloseEnum(md_import, henum);
for (field_idx = 0; field_idx < buf_len; field_idx++) @@ -1374,14 +1374,14 @@ static void test_IMetaDataImport(void) henum = NULL; fielddef = mdFieldDefNil; hr = IMetaDataImport_EnumMembersWithName(md_import, &henum, typedef2, name, &fielddef, 1, NULL); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(!!henum, "got henum %p\n", henum); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(!!henum, "got henum %p\n", henum); buf_len2 = 0; hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len2); ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(buf_len2 == 1, "got buf_len2 %lu\n", buf_len2); - todo_wine ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), - debugstr_mdToken(fielddef_tokens[field_idx])); + ok(buf_len2 == 1, "got buf_len2 %lu\n", buf_len2); + ok(fielddef == fielddef_tokens[field_idx], "got fielddef %s != %s\n", debugstr_mdToken(fielddef), + debugstr_mdToken(fielddef_tokens[field_idx])); IMetaDataImport_CloseEnum(md_import, henum);
fielddef = mdFieldDefNil; @@ -1399,14 +1399,14 @@ static void test_IMetaDataImport(void)
token = mdTokenNil; hr = IMetaDataImport_FindMember(md_import, typedef2, name, sig_blob, sig_len, &token); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(token == fielddef_tokens[field_idx], "got token %s != %s\n", debugstr_mdToken(token), - debugstr_mdToken(fielddef_tokens[field_idx])); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(token == fielddef_tokens[field_idx], "got token %s != %s\n", debugstr_mdToken(token), + debugstr_mdToken(fielddef_tokens[field_idx])); token = mdTokenNil; hr = IMetaDataImport_FindMember(md_import, typedef2, name, NULL, 0, &token); - todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); - todo_wine ok(token == fielddef_tokens[field_idx], "got token %s != %s\n", debugstr_mdToken(token), - debugstr_mdToken(fielddef_tokens[field_idx])); + ok(hr == S_OK, "got hr %#lx\n", hr); + ok(token == fielddef_tokens[field_idx], "got token %s != %s\n", debugstr_mdToken(token), + debugstr_mdToken(fielddef_tokens[field_idx]));
winetest_pop_context(); } @@ -1420,9 +1420,9 @@ static void test_IMetaDataImport(void) ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr);
hr = IMetaDataImport_FindMember(md_import, typedef1, NULL, NULL, 0, &token); - todo_wine ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); hr = IMetaDataImport_FindMember(md_import, typedef1, L"foo", NULL, 0, &token); - todo_wine ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr); + ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr);
typedef1 = buf_len = 0; data = NULL;
On Thu Nov 27 09:32:05 2025 +0000, Vibhav Pant wrote:
changed this line in [version 3 of the diff](/wine/wine/-/merge_requests/9604/diffs?diff_id=228120&start_sha=50130ca20af6f4df6a34f52ea7bfd4950bc34f18#64498ec8eadd4866b8b06b49661faa5cf4c1c8e4_961_1012)
Thanks.
v3: * Add tests and implementation for EnumMembers, EnumMembersWithName, FindMember.