From: Vibhav Pant vibhavp@gmail.com
--- dlls/rometadata/tests/rometadata.c | 358 ++++++++++++++++++++++++++++- include/cor.idl | 26 +++ include/corhdr.h | 2 + 3 files changed, 385 insertions(+), 1 deletion(-)
diff --git a/dlls/rometadata/tests/rometadata.c b/dlls/rometadata/tests/rometadata.c index 03e39d61e77..d752770302b 100644 --- a/dlls/rometadata/tests/rometadata.c +++ b/dlls/rometadata/tests/rometadata.c @@ -17,6 +17,7 @@ */
#define COBJMACROS +#define _DEFINE_META_DATA_META_CONSTANTS #include <windows.h> #include "initguid.h" #include "cor.h" @@ -214,6 +215,31 @@ struct type_info const char *exp_namespace; };
+struct column_info +{ + ULONG exp_offset; + ULONG exp_col_size; + ULONG exp_type; + const char *exp_name; +}; + +enum coded_idx_type +{ + CT_TypeDefOrRef = 64, + CT_HasConstant = 65, + CT_HasCustomAttribute = 66, + CT_HasFieldMarshal = 67, + CT_HasDeclSecurity = 68, + CT_MemberRefParent = 69, + CT_HasSemantics = 70, + CT_MethodDefOrRef = 71, + CT_MemberForwarded = 72, + CT_Implementation = 73, + CT_CustomAttributeType = 74, + CT_ResolutionScope = 75, + CT_TypeOrMethodDef = 76 +}; + static void test_MetaDataDispenser_OpenScope(void) { static const struct table_info tables[TABLE_MAX] = { @@ -263,6 +289,246 @@ static void test_MetaDataDispenser_OpenScope(void) {4, 0, 2, -1, "MethodSpec"}, {4, 0, 2, 0, "GenericParamConstraint"}, }; + static const struct { + ULONG len; + const struct column_info columns[9]; + } table_columns[TABLE_MAX] = { + {5, + { + {0, 2, iUSHORT, "Generation"}, + {2, 2, iSTRING, "Name"}, + {4, 2, iGUID, "Mvid"}, + {6, 2, iGUID, "EncId"}, + {8, 2, iGUID, "EncBaseId"} + }}, + {3, + { + {0, 2, CT_ResolutionScope, "ResolutionScope"}, + {2, 2, iSTRING, "Name"}, + {4, 2, iSTRING, "Namespace"} + }}, + {6, + { + {0, 4, iULONG, "Flags"}, + {4, 2, iSTRING, "Name"}, + {6, 2, iSTRING, "Namespace"}, + {8, 2, CT_TypeDefOrRef, "Extends"}, + {10, 2, TABLE_FIELD, "FieldList"}, + {12, 2, TABLE_METHODDEF, "MethodList"} + }}, + {1, {{0, 2, TABLE_FIELD, "Field"}}}, + {3, + { + {0, 2, iUSHORT, "Flags"}, + {2, 2, iSTRING, "Name"}, + {4, 2, iBLOB, "Signature"}, + }}, + {1, {{0, 2, TABLE_METHODDEF, "Method"}}}, + {6, + { + {0, 4, iULONG, "RVA"}, + {4, 2, iUSHORT, "ImplFlags"}, + {6, 2, iUSHORT, "Flags"}, + {8, 2, iSTRING, "Name"}, + {10, 2, iBLOB, "Signature"}, + {12, 2, TABLE_PARAM, "ParamList"} + }}, + {1, {{0, 2, TABLE_PARAM, "Param"}}}, + {3, + { + {0, 2, iUSHORT, "Flags"}, + {2, 2, iUSHORT, "Sequence"}, + {4, 2, iSTRING, "Name"} + }}, + {2, + { + {0, 2, TABLE_TYPEDEF, "Class"}, + {2, 2, CT_TypeDefOrRef, "Interface"}, + }}, + {3, + { + {0, 2, CT_MemberRefParent, "Class"}, + {2, 2, iSTRING, "Name"}, + {4, 2, iBLOB, "Signature"}, + }}, + {3, + { + {0, 1, iBYTE, "Type"}, + {2, 2, CT_HasConstant, "Parent"}, + {4, 2, iBLOB, "Value"} + }}, + {3, + { + {0, 2, CT_HasCustomAttribute, "Parent"}, + {2, 2, CT_CustomAttributeType, "Type"}, + {4, 2, iBLOB, "Value"} + }}, + {2, + { + {0, 2, CT_HasFieldMarshal, "Parent"}, + {2, 2, iBLOB, "NativeType"} + }}, + {3, + { + {0, 2, iSHORT, "Action"}, + {2, 2, CT_HasDeclSecurity, "Parent"}, + {4, 2, iBLOB, "PermissionSet"} + }}, + {3, + { + {0, 2, iUSHORT, "PackingSize"}, + {2, 4, iULONG, "ClassSize"}, + {6, 2, TABLE_TYPEDEF, "Parent"} + }}, + {2, + { + {0, 4, iULONG, "OffSet"}, + {4, 2, TABLE_FIELD, "Field"} + }}, + {1, {{0, 2, iBLOB, "Signature"}}}, + {2, + { + {0, 2, TABLE_TYPEDEF, "Parent"}, + {2, 2, TABLE_EVENT, "EventList"}, + }}, + {1, {{0, 2, TABLE_EVENT, "Event"}}}, + {3, + { + {0, 2, iUSHORT, "EventFlags"}, + {2, 2, iSTRING, "Name"}, + {4, 2, CT_TypeDefOrRef, "EventType"} + }}, + {2, + { + {0, 2, TABLE_TYPEDEF, "Parent"}, + {2, 2, TABLE_PROPERTY, "PropertyList"} + }}, + {1, {{0, 2, TABLE_PROPERTY, "Property"}}}, + {3, + { + {0, 2, iUSHORT, "PropFlags"}, + {2, 2, iSTRING, "Name"}, + {4, 2, iBLOB, "Type"} + }}, + {3, + { + {0, 2, iUSHORT, "Semantic"}, + {2, 2, TABLE_METHODDEF, "Method"}, + {4, 2, CT_HasSemantics, "Association"} + }}, + {3, + { + {0, 2, TABLE_TYPEDEF, "Class"}, + {2, 2, CT_MethodDefOrRef, "MethodBody"}, + {4, 2, CT_MethodDefOrRef, "MethodDeclaration"} + }}, + {1, {{0, 2, iSTRING, "Name"}}}, + {1, {{0, 2, iBLOB, "Signature"}}}, + {4, + { + {0, 2, iUSHORT, "MappingFlags"}, + {2, 2, CT_MemberForwarded, "MemberForwarded"}, + {4, 2, iSTRING, "ImportName"}, + {6, 2, TABLE_MODULEREF, "ImportScope"} + }}, + {2, + { + {0, 4, iULONG, "RVA"}, + {4, 2, TABLE_FIELD, "Field"} + }}, + {2, + { + {0, 4, iULONG, "Token"}, + {4, 4, iULONG, "FuncCode"} + }}, + {1, {{0, 4, iULONG, "Token"}}}, + {9, + { + {0, 4, iULONG, "HashAlgId"}, + {4, 2, iUSHORT, "MajorVersion"}, + {6, 2, iUSHORT, "MinorVersion"}, + {8, 2, iUSHORT, "BuildNumber"}, + {10, 2, iUSHORT, "RevisionNumber"}, + {12, 4, iULONG, "Flags"}, + {16, 2, iBLOB, "PublicKey"}, + {18, 2, iSTRING, "Name"}, + {20, 2, iSTRING, "Locale"} + }}, + {1, {{0, 4, iULONG, "Processor"}}}, + {3, + { + {0, 4, iULONG, "OSPlatformId"}, + {4, 4, iULONG, "OSMajorVersion"}, + {8, 4, iULONG, "OSMinorVersion"} + }}, + {9, + { + {0, 2, iUSHORT, "MajorVersion"}, + {2, 2, iUSHORT, "MinorVersion"}, + {4, 2, iUSHORT, "BuildNumber"}, + {6, 2, iUSHORT, "RevisionNumber"}, + {8, 4, iULONG, "Flags"}, + {12, 2, iBLOB, "PublicKeyOrToken"}, + {14, 2, iSTRING, "Name"}, + {16, 2, iSTRING, "Locale"}, + {18, 2, iBLOB, "HashValue"} + }}, + {2, + { + {0, 4, iULONG, "Processor"}, + {4, 2, TABLE_ASSEMBLYREF, "AssemblyRef"} + }}, + {4, + { + {0, 4, iULONG, "OSPlatformId"}, + {4, 4, iULONG, "OSMajorVersion"}, + {8, 4, iULONG, "OSMinorVersion"}, + {12, 2, TABLE_ASSEMBLYREF, "AssemblyRef"} + }}, + {3, + { + {0, 4, iULONG, "Flags"}, + {4, 2, iSTRING, "Name"}, + {6, 2, iBLOB, "HashValue"} + }}, + {5, + { + {0, 4, iULONG, "Flags"}, + {4, 4, iULONG, "TypeDefId"}, + {8, 2, iSTRING, "TypeName"}, + {10, 2, iSTRING, "TypeNamespace"}, + {12, 2, CT_Implementation, "Implementation"} + }}, + {4, + { + {0, 4, iULONG, "Offset"}, + {4, 4, iULONG, "Flags"}, + {8, 2, iSTRING, "Name"}, + {10, 2, CT_Implementation, "Implementation"} + }}, + {2, + { + {0, 2, TABLE_TYPEDEF, "NestedClass"}, + {2, 2, TABLE_TYPEDEF, "EnclosingClass"} + }}, + {4, + { + {0, 2, iUSHORT, "Number"}, + {2, 2, iUSHORT, "Flags"}, + {4, 2, CT_TypeOrMethodDef, "Owner"}, + {6, 2, iSTRING, "Name"} + }}, + {2, + { + {0, 2, CT_MethodDefOrRef, "Method"}, + {2, 2, iBLOB, "Instantiation"} + }}, + {2, + { + {0, 2, TABLE_GENERICPARAM, "Owner"}, + {2, 2, CT_TypeDefOrRef, "Constraint"} + }}, + }; static const struct type_info type_defs[3] = { { 0, "<Module>", NULL }, @@ -315,6 +581,7 @@ static void test_MetaDataDispenser_OpenScope(void) const struct table_info *table = &tables[i]; ULONG row_size, rows, cols, key_idx; const char *name; + ULONG j;
winetest_push_context("tables[%lu]", i);
@@ -327,6 +594,30 @@ static void test_MetaDataDispenser_OpenScope(void) ok(key_idx == table->exp_key_idx, "got key_idx %lu != %lu\n", key_idx, table->exp_key_idx); ok(!strcmp(name, table->exp_name), "got name %s != %s\n", debugstr_a(name), debugstr_a(table->exp_name));
+ for (j = 0; j < table_columns[i].len; j++) + { + const struct column_info *column = &table_columns[i].columns[j]; + ULONG offset, col_size, type; + + winetest_push_context("column=%lu", j); + + hr = IMetaDataTables_GetColumnInfo(md_tables, i, j, &offset, &col_size, &type, &name); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + if (FAILED(hr)) + { + winetest_pop_context(); + continue; + } + + ok(offset == column->exp_offset, "got offset %lu != %lu\n", offset, column->exp_offset); + ok(col_size == column->exp_col_size, "got col_size %lu != %lu\n", col_size, column->exp_col_size); + ok(type == column->exp_type, "got type %lu != %lu\n", type, column->exp_type); + ok(!strcmp(name, column->exp_name), "got name %s != %s\n", debugstr_a(name), debugstr_a(column->exp_name)); + + winetest_pop_context(); + } + winetest_pop_context(); }
@@ -344,6 +635,18 @@ static void test_MetaDataDispenser_OpenScope(void) ok(hr == S_OK, "got hr %#lx\n", hr); ok(!!guid, "got guid %p\n", guid);
+ hr = IMetaDataTables_GetColumn(md_tables, TABLE_MODULE, 1, 1, &val); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine + ok(val == module->Name, "got val %#lx != %#x\n", val, module->Name); + + hr = IMetaDataTables_GetColumn(md_tables, TABLE_MODULE, 2, 1, &val); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine + ok(val == module->Mvid, "got val %#lx != %#x\n", val, module->Mvid); + /* Read defined types. */ for (i = 0; i < ARRAY_SIZE(type_defs); i++) { @@ -373,6 +676,24 @@ static void test_MetaDataDispenser_OpenScope(void) itest1_def_idx = ((i + 1) << 5) | 3; }
+ hr = IMetaDataTables_GetColumn(md_tables, TABLE_TYPEDEF, 0, i + 1, &val); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine + ok(val == type_def->Flags, "got val %#lx != %#lx\n", val, type_def->Flags); + + hr = IMetaDataTables_GetColumn(md_tables, TABLE_TYPEDEF, 1, i + 1, &val); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine + ok(val == type_def->Name, "got val %#lx != %#x\n", val, type_def->Name); + + hr = IMetaDataTables_GetColumn(md_tables, TABLE_TYPEDEF, 2, i + 1, &val); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine + ok(val == type_def->Namespace, "got val %#lx != %#x\n", val, type_def->Namespace); + winetest_pop_context(); }
@@ -390,10 +711,11 @@ static void test_MetaDataDispenser_OpenScope(void) ok(hr == S_OK, "got hr %#lx\n", hr); if (str && !strcmp(str, ".ctor")) { + ULONG rid, type, typeref_row = (ref->Class & ~7) >> 3; const struct row_typeref *typeref = NULL;
/* All MemberRefParent coded indices in test-simple.winmd point to TypeRef entries. */ - hr = IMetaDataTables_GetRow(md_tables, TABLE_TYPEREF, (ref->Class & ~7) >> 3, (BYTE *)&typeref); + hr = IMetaDataTables_GetRow(md_tables, TABLE_TYPEREF, typeref_row, (BYTE *)&typeref); ok(hr == S_OK, "got hr %#lx\n", hr); hr = IMetaDataTables_GetString(md_tables, typeref->Name, &str); ok(hr == S_OK, "got hr %#lx\n", hr); @@ -408,8 +730,36 @@ static void test_MetaDataDispenser_OpenScope(void) break; } } + + hr = IMetaDataTables_GetColumn(md_tables, TABLE_TYPEREF, 1, typeref_row, &val); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine + ok(val == typeref->Name, "got val %#lx != %#x\n", val, typeref->Name); + + hr = IMetaDataTables_GetColumn(md_tables, TABLE_TYPEREF, 2, typeref_row, &val); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine + ok(val == typeref->Namespace, "got val %#lx != %#x\n", val, typeref->Namespace); + + hr = IMetaDataTables_GetColumn(md_tables, TABLE_MEMBERREF, 0, i + 1, &val); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + rid = RidFromToken(val); + type = TypeFromToken(val); + todo_wine + ok(rid == typeref_row, "got rid %#lx != %#lx\n", rid, typeref_row); + todo_wine + ok(type == mdtTypeRef, "got type %#lx != %#x\n", type, mdtTypeRef); }
+ hr = IMetaDataTables_GetColumn(md_tables, TABLE_MEMBERREF, 1, i + 1, &val); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine + ok(val == ref->Name, "got val %#lx != %#x\n", val, ref->Name); + winetest_pop_context(); }
@@ -439,6 +789,12 @@ static void test_MetaDataDispenser_OpenScope(void) ok(IsEqualGUID(guid, &IID_ITest1), "got guid %s\n", debugstr_guid(guid)); }
+ hr = IMetaDataTables_GetColumn(md_tables, TABLE_CUSTOMATTRIBUTE, 2, i + 1, &val); + todo_wine + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine + ok(val == attr->Value, "got val %#lx != %#x\n", val, attr->Value); + winetest_pop_context(); }
diff --git a/include/cor.idl b/include/cor.idl index 7c731d60c98..792c73e6373 100644 --- a/include/cor.idl +++ b/include/cor.idl @@ -106,3 +106,29 @@ cpp_quote("VOID WINAPI _CorImageUnloading(PVOID);") cpp_quote("HRESULT WINAPI _CorValidateImage(PVOID*,LPCWSTR);") cpp_quote("HRESULT WINAPI CoInitializeCor(DWORD);") cpp_quote("void WINAPI CoUninitializeCor(void);") + +cpp_quote("#if defined(_DEFINE_META_DATA_META_CONSTANTS) && !defined(_META_DATA_META_CONSTANTS_DEFINED)") +cpp_quote("#define _META_DATA_META_CONSTANTS_DEFINED") + +cpp_quote("const UINT iRidMax = 63;") + +cpp_quote("const UINT iCodedToken = 64;") +cpp_quote("const UINT iCodedTokenMax = 95;") + +cpp_quote("const UINT iSHORT = 96;") +cpp_quote("const UINT iUSHORT = 97;") +cpp_quote("const UINT iLONG = 98;") +cpp_quote("const UINT iULONG = 99;") +cpp_quote("const UINT iBYTE = 100;") + +cpp_quote("const UINT iSTRING = 101;") +cpp_quote("const UINT iGUID = 102;") +cpp_quote("const UINT iBLOB = 103;") + +cpp_quote("inline int IsRidType(ULONG t) { return t <= iRidMax; }") +cpp_quote("inline int IsCodedTokenType(ULONG t) { return t >= iCodedToken && t <= iCodedTokenMax; }") +cpp_quote("inline int IsRidOrToken(ULONG t) { return t <= iCodedTokenMax; }") +cpp_quote("inline int IsHeapType(ULONG t) { return t >= iSTRING; }") +cpp_quote("inline int IsFixedType(ULONG t) { return t >= iSHORT && t <= iBYTE; }") + +cpp_quote("#endif /* defined(_DEFINE_META_DATA_META_CONSTANTS) && !defined(_META_DATA_META_CONSTANTS_DEFINED) */ ") \ No newline at end of file diff --git a/include/corhdr.h b/include/corhdr.h index 5ca84fe9363..91f67d25c0f 100644 --- a/include/corhdr.h +++ b/include/corhdr.h @@ -98,6 +98,8 @@ typedef enum CorElementType #define TypeFromToken(tk) ((ULONG32)((tk) & 0xff000000)) #define IsNilToken(tk) ((RidFromToken(tk)) == 0)
+typedef ULONG RID; + typedef LPVOID mdScope; typedef ULONG32 mdToken;