From: Vibhav Pant vibhavp@gmail.com
--- dlls/rometadata/tests/rometadata.c | 74 ++++++++++++++++++++++++++- include/corhdr.h | 82 ++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 1 deletion(-)
diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index f347a574c11..ccfa15e396e 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -777,6 +777,16 @@ static void test_MetaDataDispenser_OpenScope(void) IMetaDataTables_Release(md_tables); }
+struct method_props +{ + const WCHAR *exp_name; + CorMethodAttr exp_method_flags; + CorMethodImpl exp_impl_flags; + BYTE exp_sig_blob[6]; + ULONG exp_sig_len; + CorPinvokeMap exp_call_conv; +}; + static void test_IMetaDataImport(void) { static const struct type_info type_defs[] = @@ -786,11 +796,17 @@ static void test_IMetaDataImport(void) { tdInterface | tdAbstract | tdWindowsRuntime, "ITest2", "Wine.Test", 0x1000000 }, { tdPublic | tdSealed | tdWindowsRuntime, "Test2", "Wine.Test", 0x100000b }, }; + static const struct method_props test2_methods[2] = + { + { L"Method1", mdPublic | mdNewSlot | mdFinal | mdVirtual | mdHideBySig, miManaged | miRuntime, { 0x20, 0x2, 0x8, 0x8, 0x8 }, 5, pmCallConvWinapi }, + { L"Method2", mdPublic | mdNewSlot | mdFinal | mdVirtual | mdHideBySig, miManaged | miRuntime, { 0x20, 0x1, 0x11, 0x9, 0x11, 0x9 }, 6, pmCallConvWinapi }, + }; const WCHAR *filename = load_resource(L"test-enum.winmd"); ULONG buf_len, buf_count, str_len, str_reqd, i; + mdTypeDef *typedef_tokens, typedef1, typedef2; + mdMethodDef *methoddef_tokens; IMetaDataDispenser *dispenser; IMetaDataImport *md_import; - mdTypeDef *typedef_tokens; HCORENUM henum = 0; WCHAR *strW; HRESULT hr; @@ -883,6 +899,62 @@ static void test_IMetaDataImport(void) hr = IMetaDataImport_FindTypeDefByName(md_import, NULL, 0, NULL); todo_wine ok(hr == E_INVALIDARG, "got hr %#lx\n", hr);
+ hr = IMetaDataImport_FindTypeDefByName(md_import, L"Test2", 0, &typedef1); + todo_wine ok(hr == CLDB_E_RECORD_NOTFOUND, "got hr %#lx\n", hr); + hr = IMetaDataImport_FindTypeDefByName(md_import, NULL, 0, &typedef1); + todo_wine ok(hr == E_INVALIDARG, "got hr %#lx\n", hr); + + typedef1 = 0; + hr = IMetaDataImport_FindTypeDefByName(md_import, L"Wine.Test.Test2", 0, &typedef1); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + buf_count = 0xdeadbeef; + henum = NULL; + hr = IMetaDataImport_EnumMethods(md_import, &henum, typedef1, NULL, 0, &buf_count); + todo_wine ok(hr == S_FALSE, "got hr %#lx\n", hr); + todo_wine ok(buf_count == 0, "got buf_reqd %lu\n", buf_count); + buf_len = 0; + hr = IMetaDataImport_CountEnum(md_import, henum, &buf_len); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_len == ARRAY_SIZE(test2_methods), "got buf_len %#lx\n" , buf_len); + methoddef_tokens = calloc(buf_len, sizeof(*methoddef_tokens)); + ok(!!methoddef_tokens, "got methoddef_tokens %p\n", methoddef_tokens); + hr = IMetaDataImport_EnumMethods(md_import, &henum, typedef1, methoddef_tokens, buf_len, &buf_count); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(buf_count == buf_len, "got buf_reqd %lu != %lu\n", buf_count, buf_len); + for (i = 0; i < buf_len; i++) + { + ULONG method_flags = 0, impl_flags = 0, sig_len = 0, call_conv = 0; + const struct method_props *method = &test2_methods[i]; + const BYTE *sig_blob; + WCHAR name[80]; + + winetest_push_context("i=%lu", i); + + name[0] = L'\0'; + str_len = 0; + hr = IMetaDataImport_GetMethodProps(md_import, methoddef_tokens[i], &typedef2, name, ARRAY_SIZE(name), &str_len, + &method_flags, &sig_blob, &sig_len, NULL, &impl_flags); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(method_flags == method->exp_method_flags, "got method_flags %#lx != %#x\n", method_flags, + method->exp_method_flags); + todo_wine ok(impl_flags == method->exp_impl_flags, "got impl_flags %#lx != %#x\n", impl_flags, + method->exp_impl_flags); + todo_wine ok(!!sig_blob, "got sig_blob %p\n", sig_blob); + todo_wine ok(sig_len == method->exp_sig_len, "got sig_len %lu != %lu\n", sig_len, method->exp_sig_len); + if (sig_blob && sig_len == method->exp_sig_len) + ok(!memcmp(sig_blob, method->exp_sig_blob, method->exp_sig_len), "got unexpected sig_blob\n"); + todo_wine ok(!wcscmp(name, method->exp_name), "got name %s != %s\n", debugstr_w(name), + debugstr_w(method->exp_name)); + + hr = IMetaDataImport_GetNativeCallConvFromSig(md_import, sig_blob, sig_len, &call_conv); + 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); + + winetest_pop_context(); + } + free(methoddef_tokens); + IMetaDataImport_CloseEnum(md_import, henum); + IMetaDataImport_Release(md_import); }
diff --git a/include/corhdr.h b/include/corhdr.h index f3af49abc8d..b825e16df4c 100644 --- a/include/corhdr.h +++ b/include/corhdr.h @@ -168,4 +168,86 @@ typedef enum CorTypeAttr tdReservedMask = 0x040800 } CorTypeAttr;
+typedef enum CorMethodAttr +{ + mdPrivateScope = 0x0000, + mdPrivate = 0x0001, + mdFamANDAssem = 0x0002, + mdAssem = 0x0003, + mdFamily = 0x0004, + mdFamORAssem = 0x0005, + mdPublic = 0x0006, + mdStatic = 0x0010, + mdFinal = 0x0020, + mdVirtual = 0x0040, + mdHideBySig = 0x0080, + mdReuseSlot = 0x0000, + mdNewSlot = 0x0100, + mdCheckAccessOnOverride = 0x0200, + mdAbstract = 0x0400, + mdSpecialName = 0x0800, + mdPinvokeImpl = 0x2000, + mdUnmanagedExport = 0x0008, + mdRTSpecialName = 0x1000, + mdHasSecurity = 0x4000, + mdRequireSecObject = 0x8000, + + mdMemberAccessMask = 0x0007, + mdVtableLayoutMask = 0x0100, + mdReservedMask = 0xd000, +} CorMethodAttr; + +typedef enum CorMethodImpl +{ + miIL = 0x0000, + miNative = 0x0001, + miOPTIL = 0x0002, + miRuntime = 0x0003, + miUnmanaged = 0x0004, + miManaged = 0x0000, + miForwardRef = 0x0010, + miPreserveSig = 0x0080, + miInternalCall = 0x1000, + miSynchronized = 0x0020, + miNoInlining = 0x0008, + miAggressiveInlining = 0x0100, + miNoOptimization = 0x0040, + miAggressiveOptimization = 0x0200, + miAsync = 0x2000, + + miCodeTypeMask = 0x0003, + miManagedMask = 0x0004, + miUserMask = 0x33fc, + + miMaxMethodImplVal = 0xffff, +} CorMethodImpl; + +typedef enum CorPinvokeMap +{ + pmNoMangle = 0x0001, + pmCharSetNotSpec = 0x0000, + pmCharSetAnsi = 0x0002, + pmCharSetUnicode = 0x0004, + pmCharSetAuto = 0x0006, + pmBestFitUseAssem = 0x0000, + pmBestFitEnabled = 0x0010, + pmBestFitDisabled = 0x0020, + pmThrowOnUnmappableCharUseAssem = 0x0000, + pmThrowOnUnmappableCharEnabled = 0x1000, + pmThrowOnUnmappableCharDisabled = 0x2000, + pmSupportsLastError = 0x0040, + pmCallConvWinapi = 0x0100, + pmCallConvCdecl = 0x0200, + pmCallConvStdcall = 0x0300, + pmCallConvThiscall = 0x0400, + pmCallConvFastcall = 0x0500, + + pmCharSetMask = 0x0006, + pmBestFitMask = 0x0030, + pmCallConvMask = 0x0700, + pmThrowOnUnmappableCharMask = 0x3000, + + pmMaxValue = 0xffff, +} CorPinvokeMap; + #endif /* __WINE_CORHDR_H */