Fixes #600 - Fix vtable ordering bug (#681)

* Fix bug where interfaces with overloaded functions had the wrong vtable order
Add test for vtable
Convert other tests to xunit

* Merge with main and make sue we clean the samples before we build them

* Add additional interfaces to test and test apps that helped produce the data

* Updated .winmd

* Update versions
This commit is contained in:
Steve Otteson 2021-09-27 14:53:36 -07:00 коммит произвёл GitHub
Родитель 7375f2a321
Коммит 2bca58c779
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
32 изменённых файлов: 3119 добавлений и 61 удалений

Просмотреть файл

@ -49,10 +49,6 @@ jobs:
displayName: Publish x64 generated assets
artifact: 'generated_x64'
# - publish: 'generation\emitter\generated\x64'
# displayName: Publish x64 emitter assets
# artifact: 'emitter_generated_x64'
- job: scrape_x86
displayName: "Scrape headers: x86"
pool:

Просмотреть файл

@ -55,6 +55,7 @@ SOCKADDR_STORAGE
PEXCEPTION_ROUTINE
FNCALLBACK
_OLD_LARGE_INTEGER
IVssCreateWriterMetadataEx
--remap
ABI::Windows::Foundation::IActivatableClassRegistration=IActivatableClassRegistration
adpcmcoef_tag=ADPCMCOEFSET

Просмотреть файл

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6198a8ac40dd885566158b082a95b06030d05ff72cf20ccacb233dc3e22b32f7
size 13330944
oid sha256:0acbeffbe3cbe9a1bb3c9d48c25c8ebd49b13daa107ee3cf5e60e6072544a7a5
size 13329920

Просмотреть файл

@ -15,6 +15,9 @@ ThrowOnNativeProcessError
& "$PSScriptRoot\UpdateGlobalJsonWinmdGeneratorVersion.ps1"
dotnet clean "$PSScriptRoot\..\sources\GeneratorSdk\samples"
ThrowOnNativeProcessError
dotnet pack "$PSScriptRoot\..\sources\GeneratorSdk\samples\diasdk" -c Release
ThrowOnNativeProcessError

Просмотреть файл

@ -16,71 +16,25 @@ if (!$skipInstallTools.IsPresent)
Write-Output "`e[36m*** Running tests on .winmd`e[0m"
$windowsWin32TestsDir = "$rootDir\tests\Windows.Win32.Tests"
dotnet test $windowsWin32TestsDir -c:Release
ThrowOnNativeProcessError
if (!$winmdPath)
{
$winmdPath = Get-OutputWinmdFileName -arch "crossarch"
}
$baselineWinmd = "$PSScriptRoot\BaselineWinmd\Windows.Win32.winmd"
$winmdUtilsPathBin = "$metadataToolsBin\WinmdUtils.dll"
$failed = $false
Write-Output "`nLooking for duplicate imports in $winmdPath..."
Write-Output "Calling: dotnet $winmdUtilsPathBin showDuplicateImports --winmd $winmdPath"
& dotnet $winmdUtilsPathBin showDuplicateImports --winmd $winmdPath
if (!$failed -and $LastExitCode -lt 0)
{
$failed = $true
}
Write-Output "`nLooking for duplicate types in $winmdPath..."
Write-Output "Calling: dotnet $winmdUtilsPathBin showDuplicateTypes --winmd $winmdPath"
& dotnet $winmdUtilsPathBin showDuplicateTypes --winmd $winmdPath
if (!$failed -and $LastExitCode -lt 0)
{
$failed = $true
}
Write-Output "`nLooking for duplicate constants in $winmdPath..."
Write-Output "Calling: dotnet $winmdUtilsPathBin showDuplicateConstants --winmd $winmdPath"
& dotnet $winmdUtilsPathBin showDuplicateConstants --winmd $winmdPath
if (!$failed -and $LastExitCode -lt 0)
{
$failed = $true
}
$allowedEmptyDelegatesFileName = "$rootDir\tests\emptyDelegatesAllowList.rsp"
Write-Output "`nLooking for empty delegates in $winmdPath..."
Write-Output "Calling: dotnet $winmdUtilsPathBin showEmptyDelegates --winmd $winmdPath @$allowedEmptyDelegatesFileName"
& dotnet $winmdUtilsPathBin showEmptyDelegates --winmd $winmdPath @$allowedEmptyDelegatesFileName
if (!$failed -and $LastExitCode -lt 0)
{
$failed = $true
}
$pointersToDelegatesAllowListFileName = "$rootDir\tests\pointersToDelegatesAllowList.rsp"
Write-Output "`nLooking for pointers to delegates in $winmdPath..."
Write-Output "Calling: dotnet $winmdUtilsPathBin showPointersToDelegates --winmd $winmdPath @$pointersToDelegatesAllowListFileName"
& dotnet $winmdUtilsPathBin showPointersToDelegates --winmd $winmdPath @$pointersToDelegatesAllowListFileName
if (!$failed -and $LastExitCode -lt 0)
{
$failed = $true
}
Write-Output "`n"
Write-Output "Comparing $winmdPath against baseline $baselineWinmd..."
Write-Output "Calling: dotnet $winmdUtilsPathBin compare --first $baselineWinmd --second $winmdPath"
& dotnet $winmdUtilsPathBin compare --first $baselineWinmd --second $winmdPath
if (!$failed -and $LastExitCode -lt 0)
if ($LastExitCode -lt 0)
{
Write-Output "If all the differences are expected, please update the baseline by doing this:`ncopy $winmdPath $baselineWinmd"
$failed = $true
}
if ($failed)
{
exit -1
}

Просмотреть файл

@ -63,36 +63,132 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WinSDK", "WinSDK", "{8ADADA
..\generation\WinSDK\WithSetLastError.rsp = ..\generation\WinSDK\WithSetLastError.rsp
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{C3EAC69E-9456-4B3A-9BFD-41D387716EE2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Windows.Win32.Tests", "..\tests\Windows.Win32.Tests\Windows.Win32.Tests.csproj", "{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestCommon", "..\Tests\TestCommon\TestCommon.csproj", "{39AEB794-C1A5-4A2B-A860-0DEF2082F263}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VtablesFromPdb", "..\tests\VtablesFromPdb\VtablesFromPdb.csproj", "{0045FF95-AC14-4C51-B348-E8A5E51E90BC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5B6F6176-0031-4105-B9FF-B713499D8975}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Debug|x64.ActiveCfg = Debug|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Debug|x64.Build.0 = Debug|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Debug|x86.ActiveCfg = Debug|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Debug|x86.Build.0 = Debug|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Release|Any CPU.Build.0 = Release|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Release|x64.ActiveCfg = Release|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Release|x64.Build.0 = Release|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Release|x86.ActiveCfg = Release|Any CPU
{5B6F6176-0031-4105-B9FF-B713499D8975}.Release|x86.Build.0 = Release|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Debug|x64.ActiveCfg = Debug|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Debug|x64.Build.0 = Debug|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Debug|x86.ActiveCfg = Debug|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Debug|x86.Build.0 = Debug|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Release|Any CPU.Build.0 = Release|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Release|x64.ActiveCfg = Release|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Release|x64.Build.0 = Release|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Release|x86.ActiveCfg = Release|Any CPU
{8C0897A4-2BA6-40D5-AF41-130BE109C024}.Release|x86.Build.0 = Release|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Debug|x64.ActiveCfg = Debug|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Debug|x64.Build.0 = Debug|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Debug|x86.ActiveCfg = Debug|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Debug|x86.Build.0 = Debug|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Release|Any CPU.Build.0 = Release|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Release|x64.ActiveCfg = Release|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Release|x64.Build.0 = Release|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Release|x86.ActiveCfg = Release|Any CPU
{74D143DF-9C79-4E34-83C8-0347826317D7}.Release|x86.Build.0 = Release|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Debug|x64.ActiveCfg = Debug|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Debug|x64.Build.0 = Debug|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Debug|x86.ActiveCfg = Debug|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Debug|x86.Build.0 = Debug|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Release|Any CPU.Build.0 = Release|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Release|x64.ActiveCfg = Release|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Release|x64.Build.0 = Release|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Release|x86.ActiveCfg = Release|Any CPU
{D58855C2-F427-4C4D-990A-7F932A7B4CA3}.Release|x86.Build.0 = Release|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Debug|x64.ActiveCfg = Debug|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Debug|x64.Build.0 = Debug|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Debug|x86.ActiveCfg = Debug|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Debug|x86.Build.0 = Debug|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Release|Any CPU.Build.0 = Release|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Release|x64.ActiveCfg = Release|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Release|x64.Build.0 = Release|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Release|x86.ActiveCfg = Release|Any CPU
{C8AA8253-FF34-4963-9CD0-B7A4C28D33BB}.Release|x86.Build.0 = Release|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Debug|x64.ActiveCfg = Debug|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Debug|x64.Build.0 = Debug|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Debug|x86.ActiveCfg = Debug|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Debug|x86.Build.0 = Debug|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Release|Any CPU.Build.0 = Release|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Release|x64.ActiveCfg = Release|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Release|x64.Build.0 = Release|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Release|x86.ActiveCfg = Release|Any CPU
{08297558-5DC0-4ACB-A67B-3E498638AD4B}.Release|x86.Build.0 = Release|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Debug|x64.ActiveCfg = Debug|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Debug|x64.Build.0 = Debug|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Debug|x86.ActiveCfg = Debug|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Debug|x86.Build.0 = Debug|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Release|Any CPU.Build.0 = Release|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Release|x64.ActiveCfg = Release|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Release|x64.Build.0 = Release|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Release|x86.ActiveCfg = Release|Any CPU
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E}.Release|x86.Build.0 = Release|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Debug|x64.ActiveCfg = Debug|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Debug|x64.Build.0 = Debug|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Debug|x86.ActiveCfg = Debug|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Debug|x86.Build.0 = Debug|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Release|Any CPU.Build.0 = Release|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Release|x64.ActiveCfg = Release|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Release|x64.Build.0 = Release|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Release|x86.ActiveCfg = Release|Any CPU
{39AEB794-C1A5-4A2B-A860-0DEF2082F263}.Release|x86.Build.0 = Release|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Debug|x64.ActiveCfg = Debug|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Debug|x64.Build.0 = Debug|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Debug|x86.ActiveCfg = Debug|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Debug|x86.Build.0 = Debug|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Release|Any CPU.Build.0 = Release|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Release|x64.ActiveCfg = Release|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Release|x64.Build.0 = Release|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Release|x86.ActiveCfg = Release|Any CPU
{0045FF95-AC14-4C51-B348-E8A5E51E90BC}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -102,6 +198,9 @@ Global
{6C9DCCF4-8580-478A-BB61-36ACCCADB16F} = {4D4F6043-CD81-4FD3-A6E5-0A2148281E78}
{65F906A0-83DF-435D-AE74-BE67CBC8CC9B} = {D3E6399F-0983-4742-B07C-874B6ED80E51}
{8ADADAAD-DC58-4080-870F-65FE47825343} = {B952F7CE-A7D8-4633-925D-FF1C95FA77AC}
{A4A27854-A16F-40A5-ABEF-CDD427E03C0E} = {C3EAC69E-9456-4B3A-9BFD-41D387716EE2}
{39AEB794-C1A5-4A2B-A860-0DEF2082F263} = {C3EAC69E-9456-4B3A-9BFD-41D387716EE2}
{0045FF95-AC14-4C51-B348-E8A5E51E90BC} = {C3EAC69E-9456-4B3A-9BFD-41D387716EE2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {156D7600-E986-417B-9D16-E6FA1039AF42}

Просмотреть файл

@ -1794,7 +1794,9 @@ namespace ClangSharpSourceToWinmd
var inheritedMethodCount = this.GetInheritedMethodCount(node);
foreach (MethodDeclarationSyntax method in node.Members.Where(m => m is MethodDeclarationSyntax).Skip(inheritedMethodCount))
foreach (MethodDeclarationSyntax method in node.Members.Where(m => m is MethodDeclarationSyntax)
.OrderBy(m => SyntaxUtils.GetVtableSlotFromMethodBody((MethodDeclarationSyntax)m))
.Skip(inheritedMethodCount))
{
var methodSymbol = model.GetDeclaredSymbol(method);
var methodName = methodSymbol.Name;

Просмотреть файл

@ -62,3 +62,14 @@ DECLSPEC_IMPORT void WINAPI CloseSampleHandle(_In_ SAMPLE_HANDLE handle);
DECLSPEC_IMPORT void WINAPI SampleCallMe1(_In_ LPSAMPLECALLBACK callback);
DECLSPEC_IMPORT void WINAPI SampleCallMe2(_In_ LPALREADYPTR_SAMPLECALLBACK callback);
interface IOverloads : public IUnknown
{
virtual HRESULT A(int a);
virtual HRESULT B(int b);
virtual HRESULT C(int c);
virtual HRESULT C(int a, int c);
virtual HRESULT B(int a, int b);
virtual HRESULT B(int a, int b, int c);
virtual HRESULT A(int a, int b, int c);
};

Просмотреть файл

@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
"version": "0.3-preview",
"version": "0.11-preview",
"assemblyVersion": {
"precision": "revision"
},

Просмотреть файл

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace MetadataUtils
{
public static class DecompilerUtils
{
public static DecompilerTypeSystem LoadDecompilerTypeSystem(string winmdFileName)
{
DecompilerSettings settings = new DecompilerSettings() { ThrowOnAssemblyResolveErrors = false };
return CreateTypeSystemFromFile(winmdFileName, settings);
}
public static IEnumerable<ITypeDefinition> GetSelfDefinedWinmdToplevelTypes(DecompilerTypeSystem winmd)
{
return winmd.GetTopLevelTypeDefinitions().Where(
type => type.ParentModule == winmd.MainModule && type.FullName != "<Module>");
}
private static PEFile LoadPEFile(string fileName, DecompilerSettings settings)
{
settings.LoadInMemory = true;
return new PEFile(
fileName,
new FileStream(fileName, FileMode.Open, FileAccess.Read),
streamOptions: PEStreamOptions.PrefetchEntireImage,
metadataOptions: settings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None
);
}
private static DecompilerTypeSystem CreateTypeSystemFromFile(string fileName, DecompilerSettings settings)
{
settings.LoadInMemory = true;
var file = LoadPEFile(fileName, settings);
var resolver = new UniversalAssemblyResolver(fileName, settings.ThrowOnAssemblyResolveErrors, file.DetectTargetFrameworkId());
return new DecompilerTypeSystem(file, resolver);
}
}
}

Просмотреть файл

@ -9,6 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ICSharpCode.Decompiler" Version="7.0.0.6488" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>

Просмотреть файл

@ -1,10 +1,14 @@
using Microsoft.CodeAnalysis;
using System;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace MetadataUtils
{
public static class SyntaxUtils
{
private static readonly Regex vtableSlotRegex = new Regex(@"\(IntPtr\)\(lpVtbl\[(\d+)\]\)");
public static bool IsEmptyStruct(StructDeclarationSyntax node)
{
bool hasNoImportantAttributes =
@ -137,5 +141,16 @@ namespace MetadataUtils
{
return GetFullName(node, false);
}
public static int GetVtableSlotFromMethodBody(MethodDeclarationSyntax method)
{
var match = vtableSlotRegex.Match(method.Body.ToString());
if (match.Success)
{
return int.Parse(match.Groups[1].Value);
}
throw new InvalidOperationException($"Could not find vtable entry for {method.Parent}.{method.Identifier.ValueText}");
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

13
tests/PdbsApp/PdbsApp.cpp Normal file
Просмотреть файл

@ -0,0 +1,13 @@
#include <Windows.h>
#include <d3d11_3.h>
#include <d2d1_3.h>
#include <dcomp.h>
#include <dwrite_3.h>
int main()
{
ID2D1SvgStrokeDashArray *pTemp = nullptr;
IDCompositionVisual *pTemp1 = nullptr;
IDCompositionGaussianBlurEffect *pTemp2 = nullptr;
IDWriteFactory3 *pTemp3 = nullptr;
}

Просмотреть файл

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{10441770-3547-4690-9249-5dfbc8d6490c}</ProjectGuid>
<RootNamespace>PdbsApp</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="PdbsApp.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

Просмотреть файл

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="$(RepoRootPath)images/windows.png" />
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="PdbsApp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="2.4.1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,49 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using Xunit.Abstractions;
namespace TestCommon
{
public static class TestUtils
{
public static string GetAssetFile(string fileName)
{
return Path.Combine(BinPath, "assets", fileName);
}
public static string Win32WinmdPath => Path.GetFullPath(Path.Combine(BinPath, @"..\..\windows.win32.winmd"));
public static string BinPath => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
public static int ExecuteCmd(string cmd, string args, out string output, ITestOutputHelper logger)
{
output = null;
logger.WriteLine($"Calling: {cmd} {args}");
using Process process = new Process();
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
string errorText = null;
process.StartInfo.RedirectStandardError = true;
process.ErrorDataReceived +=
new DataReceivedEventHandler((sender, e) => { errorText += e.Data; });
process.StartInfo.FileName = cmd;
process.StartInfo.Arguments = args;
process.Start();
process.BeginErrorReadLine();
output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
output += errorText;
return process.ExitCode;
}
}
}

Просмотреть файл

@ -0,0 +1,255 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Dia2Lib;
namespace VtablesFromPdb
{
class Program
{
private enum BasicType
{
btNoType = 0,
btVoid = 1,
btChar = 2,
btWChar = 3,
btInt = 6,
btUInt = 7,
btFloat = 8,
btBCD = 9,
btBool = 10,
btLong = 13,
btULong = 14,
btCurrency = 25,
btDate = 26,
btVariant = 27,
btComplex = 28,
btBit = 29,
btBSTR = 30,
btHresult = 31,
btChar16 = 32, // char16_t
btChar32 = 33, // char32_t
btChar8 = 34, // char8_t
}
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Expected: <pdb file name> <output json name>");
}
string pdbFileName = args[0];
string jsonFileName = args[1];
IDiaDataSource dia = new DiaSource();
dia.loadDataFromPdb(pdbFileName);
dia.openSession(out IDiaSession session);
session.globalScope.findChildren(SymTagEnum.SymTagUDT, null, 0, out var symbols);
List<InterfaceInfo> interfaceInfos = new List<InterfaceInfo>();
foreach (IDiaSymbol type in symbols)
{
if (!type.name.StartsWith('I'))
{
continue;
}
System.Diagnostics.Debug.WriteLine(type.name);
List<string> functions = new List<string>();
type.findChildren(SymTagEnum.SymTagNull, null, 0, out IDiaEnumSymbols members);
foreach (IDiaSymbol member in members)
{
var memberTag = (SymTagEnum)member.symTag;
if (memberTag == SymTagEnum.SymTagFunction && member.@virtual == 1)
{
StringBuilder methodText = new StringBuilder();
IDiaSymbol funcType = member.type;
IDiaSymbol returnType = funcType.type;
AppendType(returnType, methodText);
methodText.Append($" {member.name}(");
funcType.findChildren(SymTagEnum.SymTagNull, null, 0, out IDiaEnumSymbols parameters);
bool first = true;
foreach (IDiaSymbol p in parameters)
{
if (first)
{
first = false;
}
else
{
methodText.Append(", ");
}
AppendType(p.type, methodText);
}
methodText.Append(')');
functions.Add(methodText.ToString());
}
}
if (functions.Count != 0)
{
InterfaceInfo info = new InterfaceInfo() { Name = type.name, Methods = functions.ToArray() };
interfaceInfos.Add(info);
}
}
var interfacesText = Newtonsoft.Json.JsonConvert.SerializeObject(interfaceInfos, formatting: Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(jsonFileName, interfacesText);
}
private static readonly string[] baseTypes = new string[]
{
"<NoType>", // btNoType = 0,
"void", // btVoid = 1,
"Byte", // btChar = 2,
"UShort", // btWChar = 3,
"SByte",
"Byte",
"Int", // btInt = 6,
"UInt", // btUInt = 7,
"Single", // btFloat = 8,
"<BCD>", // btBCD = 9,
"bool", // btBool = 10,
"Short",
"UShort",
"Int", // btLong = 13,
"UInt", // btULong = 14,
"SByte",
"Short",
"Int",
"Long",
"__int128",
"Byte",
"UShort",
"UInt",
"ULong",
"unsigned __int128",
"<currency>", // btCurrency = 25,
"<date>", // btDate = 26,
"VARIANT", // btVariant = 27,
"<complex>", // btComplex = 28,
"<bit>", // btBit = 29,
"BSTR", // btBSTR = 30,
"HRESULT", // btHresult = 31
"UShort", // btChar16 = 32
"char32_t", // btChar32 = 33
"Byte", // btChar8 = 34
};
private static void AppendType(IDiaSymbol type, StringBuilder output)
{
SymTagEnum tag = (SymTagEnum)type.symTag;
var length = type.length;
switch (tag)
{
case SymTagEnum.SymTagUDT:
case SymTagEnum.SymTagEnum:
{
var name = type.name;
if (name == "_GUID")
{
name = "Guid";
}
output.Append(name);
break;
}
case SymTagEnum.SymTagPointerType:
{
var baseType = type.type;
AppendType(baseType, output);
output.Append('*');
break;
}
case SymTagEnum.SymTagBaseType:
{
BasicType basicType = (BasicType)type.baseType;
switch (basicType)
{
case BasicType.btUInt:
case BasicType.btInt:
if (basicType == BasicType.btUInt)
{
output.Append('U');
}
switch (length)
{
case 1:
output.Append("Byte");
break;
case 2:
output.Append("Short");
break;
case 4:
output.Append("Int");
break;
case 8:
output.Append("Long");
break;
default:
throw new NotSupportedException();
}
break;
case BasicType.btFloat:
switch (length)
{
case 4:
output.Append("Single");
break;
case 8:
output.Append("Double");
break;
default:
throw new NotSupportedException();
}
break;
default:
output.Append(baseTypes[(int)basicType]);
break;
}
break;
}
default:
throw new NotSupportedException();
}
}
private class InterfaceInfo
{
public string Name { get; set; }
public string[] Methods { get; set; }
}
}
}

Просмотреть файл

@ -0,0 +1,8 @@
{
"profiles": {
"VtablesFromPdb": {
"commandName": "Project",
"commandLineArgs": "$(ProjectDir)..\\PdbsApp\\Debug\\PdbsApp.pdb $(ProjectDir)..\\PdbsApp\\Interfaces.json"
}
}
}

Просмотреть файл

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectionMetadataWinmd Remove="C:\Users\sotte\.nuget\packages\microsoft.windows.sdk.win32metadata\10.2.185-preview\buildTransitive\..\Windows.Win32.winmd" />
<ProjectionMetadataWinmd Include="..\..\bin\*.winmd" />
</ItemGroup>
<ItemGroup>
<COMReference Include="Dia2Lib">
<WrapperTool>tlbimp</WrapperTool>
<VersionMinor>0</VersionMinor>
<VersionMajor>2</VersionMajor>
<Guid>106173a0-0173-4e5c-84e7-e915422be997</Guid>
<Lcid>0</Lcid>
<Isolated>false</Isolated>
<EmbedInteropTypes>true</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>

Двоичные данные
tests/VtablesFromPdb/dia2lib.dll Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,63 @@
using System.IO;
using TestCommon;
using Xunit;
using Xunit.Abstractions;
namespace Windows.Win32.Tests
{
public class IntegrityTests
{
private ITestOutputHelper outputHelper;
public IntegrityTests(ITestOutputHelper outputHelper)
{
this.outputHelper = outputHelper;
}
[Fact]
public void NoDuplicateImports()
{
string args = $"showDuplicateImports --winmd \"{TestUtils.Win32WinmdPath}\"";
this.ExecWinmdUtils(args);
}
[Fact]
public void NoDuplicateTypes()
{
string args = $"showDuplicateTypes --winmd \"{TestUtils.Win32WinmdPath}\"";
this.ExecWinmdUtils(args);
}
[Fact]
public void NoDuplicateConstants()
{
string args = $"showDuplicateConstants --winmd \"{TestUtils.Win32WinmdPath}\"";
this.ExecWinmdUtils(args);
}
[Fact]
public void NoInvalidEmptyDelegates()
{
string allowedEmptyDelegatesFileName = TestUtils.GetAssetFile("emptyDelegatesAllowList.rsp");
string args = $"showEmptyDelegates --winmd \"{TestUtils.Win32WinmdPath}\" \"@{allowedEmptyDelegatesFileName}\"";
this.ExecWinmdUtils(args);
}
[Fact]
public void NoInvalidPointersToDelegates()
{
string pointersToDelegatesFileName = TestUtils.GetAssetFile("pointersToDelegatesAllowList.rsp");
string args = $"showPointersToDelegates --winmd \"{TestUtils.Win32WinmdPath}\" \"@{pointersToDelegatesFileName}\"";
this.ExecWinmdUtils(args);
}
private void ExecWinmdUtils(string args)
{
string winmdUtilsDll = Path.Combine(TestUtils.BinPath, "winmdutils.dll");
string fullArgs = $"\"{winmdUtilsDll}\" {args}";
int ret = TestUtils.ExecuteCmd("dotnet", fullArgs, out var outputText, this.outputHelper);
this.outputHelper.WriteLine(outputText);
Assert.Equal(0, ret);
}
}
}

Просмотреть файл

@ -0,0 +1,8 @@
namespace Windows.Win32.Tests
{
public class InterfaceInfo
{
public string Name { get; set; }
public string[] Methods { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,45 @@
using System.Collections.Generic;
using System.IO;
using ICSharpCode.Decompiler.TypeSystem;
using MetadataUtils;
using Xunit;
namespace Windows.Win32.Tests
{
public class InterfaceTests
{
private DecompilerTypeSystem typeSystem;
public InterfaceTests()
{
this.typeSystem = DecompilerUtils.LoadDecompilerTypeSystem(TestCommon.TestUtils.Win32WinmdPath);
}
[Theory]
[MemberData(nameof(GetInterfaceData))]
public void Interface_Layouts_Correct(InterfaceInfo info)
{
var winmdInterface = WinmdTestUtils.GetInterfaceInfo(this.typeSystem, info.Name);
var jsonText = Newtonsoft.Json.JsonConvert.SerializeObject(winmdInterface, formatting: Newtonsoft.Json.Formatting.Indented);
System.Diagnostics.Debug.WriteLine($"Read {info.Name} from winmd as:\n{jsonText}");
Assert.Equal(info.Name, winmdInterface.Name);
Assert.Equal(info.Methods.Length, winmdInterface.Methods.Length);
for (int i = 0; i < winmdInterface.Methods.Length; i++)
{
Assert.Equal(info.Methods[i], winmdInterface.Methods[i]);
}
}
public static IEnumerable<object[]> GetInterfaceData()
{
var jsonPath = TestCommon.TestUtils.GetAssetFile("InterfacesToVerify.json");
var interfaceItems = Newtonsoft.Json.JsonConvert.DeserializeObject<InterfaceInfo[]>(File.ReadAllText(jsonPath));
foreach (var item in interfaceItems)
{
yield return new object[] { item };
}
}
}
}

Просмотреть файл

@ -0,0 +1,44 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ICSharpCode.Decompiler" Version="7.0.0.6488" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\sources\MetadataUtils\MetadataUtils.csproj" />
<ProjectReference Include="..\TestCommon\TestCommon.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="assets\emptyDelegatesAllowList.rsp">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="assets\InterfacesToVerify.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="assets\pointersToDelegatesAllowList.rsp">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="InterfacesToVerify.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,51 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.Decompiler.TypeSystem;
using MetadataUtils;
namespace Windows.Win32.Tests
{
public static class WinmdTestUtils
{
public static InterfaceInfo GetInterfaceInfo(DecompilerTypeSystem typeSystem, string typeName)
{
var type = DecompilerUtils.GetSelfDefinedWinmdToplevelTypes(typeSystem).Where(t => t.Kind == TypeKind.Interface && t.Name == typeName).Single();
InterfaceInfo ret = new InterfaceInfo() { Name = type.Name };
List<string> protoTypes = new List<string>();
foreach (IMethod method in type.Methods)
{
protoTypes.Add(GetMethodPrototype(method));
}
ret.Methods = protoTypes.ToArray();
return ret;
}
public static string GetMethodPrototype(IMethod method)
{
StringBuilder ret = new StringBuilder();
ret.AppendFormat($"{method.ReturnType.Name} {method.Name}(");
bool first = true;
foreach (var p in method.Parameters)
{
if (!first)
{
ret.Append(", ");
}
else
{
first = false;
}
ret.Append(p.Type.Name);
}
ret.Append(')');
return ret.ToString();
}
}
}

Просмотреть файл

@ -0,0 +1,5 @@
<configuration>
<appSettings>
<add key="xunit.shadowCopy" value="false"/>
</appSettings>
</configuration>

Просмотреть файл

@ -0,0 +1,57 @@
[
{
"Name": "ID2D1SvgStrokeDashArray",
"Methods": [
"HRESULT RemoveDashesAtEnd(UInt32)",
"HRESULT UpdateDashes(D2D1_SVG_LENGTH*, UInt32, UInt32)",
"HRESULT UpdateDashes(Single*, UInt32, UInt32)",
"HRESULT GetDashes(D2D1_SVG_LENGTH*, UInt32, UInt32)",
"HRESULT GetDashes(Single*, UInt32, UInt32)",
"UInt32 GetDashesCount()"
]
},
{
"Name": "IDCompositionVisual",
"Methods": [
"HRESULT SetOffsetX(IDCompositionAnimation)",
"HRESULT SetOffsetX(Single)",
"HRESULT SetOffsetY(IDCompositionAnimation)",
"HRESULT SetOffsetY(Single)",
"HRESULT SetTransform(IDCompositionTransform)",
"HRESULT SetTransform(D2D_MATRIX_3X2_F*)",
"HRESULT SetTransformParent(IDCompositionVisual)",
"HRESULT SetEffect(IDCompositionEffect)",
"HRESULT SetBitmapInterpolationMode(DCOMPOSITION_BITMAP_INTERPOLATION_MODE)",
"HRESULT SetBorderMode(DCOMPOSITION_BORDER_MODE)",
"HRESULT SetClip(IDCompositionClip)",
"HRESULT SetClip(D2D_RECT_F*)",
"HRESULT SetContent(IUnknown)",
"HRESULT AddVisual(IDCompositionVisual, BOOL, IDCompositionVisual)",
"HRESULT RemoveVisual(IDCompositionVisual)",
"HRESULT RemoveAllVisuals()",
"HRESULT SetCompositeMode(DCOMPOSITION_COMPOSITE_MODE)"
]
},
{
"Name": "IDCompositionGaussianBlurEffect",
"Methods": [
"HRESULT SetStandardDeviation(IDCompositionAnimation)",
"HRESULT SetStandardDeviation(Single)",
"HRESULT SetBorderMode(D2D1_BORDER_MODE)"
]
},
{
"Name": "IDWriteFactory3",
"Methods": [
"HRESULT CreateGlyphRunAnalysis(DWRITE_GLYPH_RUN*, DWRITE_MATRIX*, DWRITE_RENDERING_MODE1, DWRITE_MEASURING_MODE, DWRITE_GRID_FIT_MODE, DWRITE_TEXT_ANTIALIAS_MODE, Single, Single, IDWriteGlyphRunAnalysis*)",
"HRESULT CreateCustomRenderingParams(Single, Single, Single, Single, DWRITE_PIXEL_GEOMETRY, DWRITE_RENDERING_MODE1, DWRITE_GRID_FIT_MODE, IDWriteRenderingParams3*)",
"HRESULT CreateFontFaceReference(IDWriteFontFile, UInt32, DWRITE_FONT_SIMULATIONS, IDWriteFontFaceReference*)",
"HRESULT CreateFontFaceReference(PWSTR, FILETIME*, UInt32, DWRITE_FONT_SIMULATIONS, IDWriteFontFaceReference*)",
"HRESULT GetSystemFontSet(IDWriteFontSet*)",
"HRESULT CreateFontSetBuilder(IDWriteFontSetBuilder*)",
"HRESULT CreateFontCollectionFromFontSet(IDWriteFontSet, IDWriteFontCollection1*)",
"HRESULT GetSystemFontCollection(BOOL, IDWriteFontCollection1*, BOOL)",
"HRESULT GetFontDownloadQueue(IDWriteFontDownloadQueue*)"
]
}
]

Просмотреть файл

@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
"version": "10.3-preview",
"version": "11.0-preview",
"assemblyVersion": {
"precision": "revision"
},