├── test
├── pch.cpp
├── pch.h
├── main.cpp
├── database.cpp
├── filter.cpp
├── winmd.sln
├── cache.cpp
└── winmd.vcxproj
├── .gitignore
├── nuget
├── SignConfig.xml
├── readme.md
├── readme.txt
├── Microsoft.Windows.WinMD.props
└── Microsoft.Windows.WinMD.nuspec
├── CODE_OF_CONDUCT.md
├── src
├── winmd_reader.h
└── impl
│ ├── winmd_reader
│ ├── type_helpers.h
│ ├── index.h
│ ├── filter.h
│ ├── helpers.h
│ ├── pe.h
│ ├── key.h
│ ├── enum_traits.h
│ ├── cache.h
│ ├── view.h
│ ├── enum.h
│ ├── table.h
│ ├── custom_attribute.h
│ ├── schema.h
│ ├── column.h
│ ├── signature.h
│ └── flags.h
│ └── base.h
├── .github
└── workflows
│ └── stale.yml
├── .config
└── 1espt
│ └── PipelineAutobaseliningConfig.yml
├── LICENSE
├── README.md
├── .pipelines
├── SyncMirror-Pipeline.yml
└── Pipeline.yml
├── SECURITY.md
└── vs
└── winmd.natvis
/test/pch.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | .vs
3 | x86
4 | x64
5 | *.user
6 |
--------------------------------------------------------------------------------
/test/pch.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "catch.hpp"
4 |
--------------------------------------------------------------------------------
/test/main.cpp:
--------------------------------------------------------------------------------
1 | #define CATCH_CONFIG_RUNNER
2 | #include "catch.hpp"
3 |
4 | int main(int const argc, char** argv)
5 | {
6 | return Catch::Session().run(argc, argv);
7 | }
8 |
--------------------------------------------------------------------------------
/nuget/SignConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 |
--------------------------------------------------------------------------------
/nuget/readme.md:
--------------------------------------------------------------------------------
1 | # Microsoft.Windows.WinMD NuGet Package
2 |
3 | ## Overview
4 |
5 | Please visit [Microsoft.Windows.WinMD](https://www.nuget.org/packages/Microsoft.Windows.WinMD/) for official Microsoft-signed builds of the NuGet package.
6 |
7 | The Microsoft.Windows.WinMD NuGet package provides a pure C++ header metadata parsing library. Adding a reference to this package adds the library to the project's additional include directories. For details on library use, please consult the Microsoft.Windows.WinMD github repo's [readme.md](https://github.com/microsoft/winmd/blob/master/README.md).
8 |
--------------------------------------------------------------------------------
/nuget/readme.txt:
--------------------------------------------------------------------------------
1 | ========================================================================
2 | Microsoft.Windows.WinMD C++ metadata parsing library
3 | ========================================================================
4 |
5 | The Microsoft.Windows.WinMD NuGet package provides a pure C++ header metadata parsing library.
6 | Adding a reference to this package adds the library to the project's additional include directories.
7 |
8 | ========================================================================
9 | For more information, visit:
10 | https://github.com/microsoft/winmd/
11 | ========================================================================
12 |
--------------------------------------------------------------------------------
/src/winmd_reader.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "impl/base.h"
4 | #include "impl/winmd_reader/pe.h"
5 | #include "impl/winmd_reader/view.h"
6 | #include "impl/winmd_reader/enum.h"
7 | #include "impl/winmd_reader/enum_traits.h"
8 | #include "impl/winmd_reader/flags.h"
9 | #include "impl/winmd_reader/table.h"
10 | #include "impl/winmd_reader/index.h"
11 | #include "impl/winmd_reader/signature.h"
12 | #include "impl/winmd_reader/schema.h"
13 | #include "impl/winmd_reader/database.h"
14 | #include "impl/winmd_reader/column.h"
15 | #include "impl/winmd_reader/type_helpers.h"
16 | #include "impl/winmd_reader/key.h"
17 | #include "impl/winmd_reader/cache.h"
18 | #include "impl/winmd_reader/filter.h"
19 | #include "impl/winmd_reader/custom_attribute.h"
20 | #include "impl/winmd_reader/helpers.h"
21 |
--------------------------------------------------------------------------------
/nuget/Microsoft.Windows.WinMD.props:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 | $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)))..\..\
10 |
11 |
12 |
13 |
14 | $(WinMDPackageDir);%(AdditionalIncludeDirectories)
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: Mark stale issues and pull requests
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * *'
6 |
7 | jobs:
8 | stale:
9 |
10 | runs-on: ubuntu-latest
11 | permissions:
12 | issues: write
13 | pull-requests: write
14 |
15 | steps:
16 | - uses: actions/stale@v6
17 | with:
18 | repo-token: ${{ secrets.GITHUB_TOKEN }}
19 | days-before-stale: 10
20 | days-before-close: 5
21 | stale-issue-message: 'This issue is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
22 | stale-pr-message: 'This pull request is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
23 | stale-issue-label: 'no-issue-activity'
24 | stale-pr-label: 'no-pr-activity'
25 |
--------------------------------------------------------------------------------
/.config/1espt/PipelineAutobaseliningConfig.yml:
--------------------------------------------------------------------------------
1 | ## DO NOT MODIFY THIS FILE MANUALLY. This is part of auto-baselining from 1ES Pipeline Templates. Go to [https://aka.ms/1espt-autobaselining] for more details.
2 |
3 | pipelines:
4 | 108608:
5 | retail:
6 | source:
7 | credscan:
8 | lastModifiedDate: 2023-10-27
9 | eslint:
10 | lastModifiedDate: 2023-10-27
11 | psscriptanalyzer:
12 | lastModifiedDate: 2023-10-27
13 | armory:
14 | lastModifiedDate: 2023-10-27
15 | 108527:
16 | retail:
17 | source:
18 | credscan:
19 | lastModifiedDate: 2023-10-27
20 | eslint:
21 | lastModifiedDate: 2023-10-27
22 | psscriptanalyzer:
23 | lastModifiedDate: 2023-10-27
24 | armory:
25 | lastModifiedDate: 2023-10-27
26 | binary:
27 | credscan:
28 | lastModifiedDate: 2023-10-27
29 | binskim:
30 | lastModifiedDate: 2023-10-27
31 | spotbugs:
32 | lastModifiedDate: 2023-10-27
33 |
--------------------------------------------------------------------------------
/nuget/Microsoft.Windows.WinMD.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Windows.WinMD
5 | 1.0.0.0
6 | Windows Metadata Parsing Library
7 | Microsoft
8 | Microsoft
9 | false
10 | Microsoft.Windows.WinMD is a pure C++ header library for parsing Windows Metadata (WinMD) files.
11 |
12 | native C++ WinRT WinMD nativepackage
13 | © Microsoft Corporation. All rights reserved.
14 | LICENSE
15 | https://github.com/Microsoft/winmd/tree/master/
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
22 |
--------------------------------------------------------------------------------
/test/database.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include
3 |
4 | using namespace winmd::reader;
5 |
6 | TEST_CASE("database")
7 | {
8 | std::array local{};
9 |
10 | #ifdef _WIN64
11 | ExpandEnvironmentStringsA("%windir%\\System32\\WinMetadata", local.data(), static_cast(local.size()));
12 | #else
13 | ExpandEnvironmentStringsA("%windir%\\SysNative\\WinMetadata", local.data(), static_cast(local.size()));
14 | #endif
15 |
16 | std::filesystem::path path = local.data();
17 | path.append("Windows.Foundation.winmd");
18 | database db(path.string());
19 |
20 | TypeDef stringable;
21 |
22 | for (auto&& type : db.TypeDef)
23 | {
24 | if (type.TypeName() == "IStringable")
25 | {
26 | stringable = type;
27 | break;
28 | }
29 | }
30 |
31 | REQUIRE(stringable.TypeName() == "IStringable");
32 | REQUIRE(stringable.TypeNamespace() == "Windows.Foundation");
33 | REQUIRE(stringable.Flags().WindowsRuntime());
34 | REQUIRE(stringable.Flags().Semantics() == TypeSemantics::Interface);
35 |
36 | auto methods = stringable.MethodList();
37 | REQUIRE(methods.first + 1 == methods.second);
38 | MethodDef method = methods.first;
39 | REQUIRE(method.Name() == "ToString");
40 | }
41 |
--------------------------------------------------------------------------------
/test/filter.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include
3 |
4 | using namespace winmd::reader;
5 |
6 | TEST_CASE("filter_simple")
7 | {
8 | std::vector include = { "N1", "N3", "N3.N4.N5" };
9 | std::vector exclude = { "N2", "N3.N4" };
10 |
11 | filter f{ include, exclude };
12 |
13 | REQUIRE(!f.empty());
14 |
15 | REQUIRE(!f.includes("NN.T"));
16 |
17 | REQUIRE(f.includes("N1.T"));
18 | REQUIRE(f.includes("N3.T"));
19 |
20 | REQUIRE(!f.includes("N2.T"));
21 | REQUIRE(!f.includes("N3.N4.T"));
22 |
23 | REQUIRE(f.includes("N3.N4.N5.T"));
24 | }
25 |
26 | TEST_CASE("filter_excludes_same_length")
27 | {
28 | std::vector include = { "N.N1", "N.N2" };
29 | std::vector exclude = { "N.N3", "N.N4" };
30 |
31 | filter f{ include, exclude };
32 |
33 | REQUIRE(!f.empty());
34 |
35 | REQUIRE(f.includes("N.N1.T"));
36 | REQUIRE(f.includes("N.N2.T"));
37 |
38 | REQUIRE(!f.includes("N.N3.T"));
39 | REQUIRE(!f.includes("N.N4.T"));
40 | }
41 |
42 | TEST_CASE("filter_exclude_include_precedence")
43 | {
44 | std::vector include = { "N.T" };
45 | std::vector exclude = { "N.T" };
46 |
47 | filter f{ include, exclude };
48 |
49 | REQUIRE(!f.empty());
50 |
51 | REQUIRE(!f.includes("N.T"));
52 | }
53 |
--------------------------------------------------------------------------------
/test/winmd.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29319.158
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winmd", "winmd.vcxproj", "{50FE79EA-0FCE-489B-B6B4-3303DAE2E9A1}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {50FE79EA-0FCE-489B-B6B4-3303DAE2E9A1}.Debug|x64.ActiveCfg = Debug|x64
17 | {50FE79EA-0FCE-489B-B6B4-3303DAE2E9A1}.Debug|x64.Build.0 = Debug|x64
18 | {50FE79EA-0FCE-489B-B6B4-3303DAE2E9A1}.Debug|x86.ActiveCfg = Debug|Win32
19 | {50FE79EA-0FCE-489B-B6B4-3303DAE2E9A1}.Debug|x86.Build.0 = Debug|Win32
20 | {50FE79EA-0FCE-489B-B6B4-3303DAE2E9A1}.Release|x64.ActiveCfg = Release|x64
21 | {50FE79EA-0FCE-489B-B6B4-3303DAE2E9A1}.Release|x64.Build.0 = Release|x64
22 | {50FE79EA-0FCE-489B-B6B4-3303DAE2E9A1}.Release|x86.ActiveCfg = Release|Win32
23 | {50FE79EA-0FCE-489B-B6B4-3303DAE2E9A1}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {F3E277AB-1E32-4C6E-A287-CAA07465622A}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/src/impl/winmd_reader/type_helpers.h:
--------------------------------------------------------------------------------
1 |
2 | namespace winmd::reader
3 | {
4 | inline std::pair get_type_namespace_and_name(coded_index const& type)
5 | {
6 | if (type.type() == TypeDefOrRef::TypeDef)
7 | {
8 | auto const def = type.TypeDef();
9 | return { def.TypeNamespace(), def.TypeName() };
10 | }
11 | else if (type.type() == TypeDefOrRef::TypeRef)
12 | {
13 | auto const ref = type.TypeRef();
14 | return { ref.TypeNamespace(), ref.TypeName() };
15 | }
16 | else
17 | {
18 | XLANG_ASSERT(false);
19 | return {};
20 | }
21 | }
22 |
23 | inline std::pair get_base_class_namespace_and_name(TypeDef const& type)
24 | {
25 | return get_type_namespace_and_name(type.Extends());
26 | }
27 |
28 | inline auto extends_type(TypeDef type, std::string_view typeNamespace, std::string_view typeName)
29 | {
30 | return get_base_class_namespace_and_name(type) == std::pair(typeNamespace, typeName);
31 | }
32 |
33 | inline bool is_nested(TypeDef const& type)
34 | {
35 | const auto visibility = type.Flags().Visibility();
36 | return !(visibility == TypeVisibility::Public || visibility == TypeVisibility::NotPublic);
37 | }
38 |
39 | inline bool is_nested(TypeRef const& type)
40 | {
41 | return type.ResolutionScope().type() == ResolutionScope::TypeRef;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://dev.azure.com/microsoft/Dart/_build/latest?definitionId=44715&branchName=master)
2 |
3 | # C++ winmd parser
4 |
5 | A winmd parser written in C++ and based on the [ECMA-335](https://ecma-international.org/publications-and-standards/standards/ecma-335/) standard. This winmd parser powers [C++/WinRT](https://github.com/microsoft/cppwinrt).
6 |
7 | * NuGet package: http://aka.ms/winmd/nuget
8 |
9 | The C++ winmd parser is part of the [xlang](https://github.com/microsoft/xlang) family of projects that help developers create APIs that can run on multiple platforms and be used with a variety of languages.
10 |
11 | # Contributing
12 |
13 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
14 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
15 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
16 |
17 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide
18 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
19 | provided by the bot. You will only need to do this once across all repos using our CLA.
20 |
21 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
22 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
23 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
24 |
--------------------------------------------------------------------------------
/src/impl/winmd_reader/index.h:
--------------------------------------------------------------------------------
1 |
2 | namespace winmd::reader
3 | {
4 | template <> struct typed_index : index_base
5 | {
6 | using index_base::index_base;
7 |
8 | auto MemberRef() const;
9 | auto MethodDef() const;
10 | };
11 |
12 | template <> struct typed_index : index_base
13 | {
14 | using index_base::index_base;
15 |
16 | auto Field() const;
17 | auto Param() const;
18 | auto Property() const;
19 | };
20 |
21 | template <> struct typed_index : index_base
22 | {
23 | using index_base::index_base;
24 |
25 | auto Property() const;
26 | auto Event() const;
27 | };
28 |
29 | template <> struct typed_index : index_base
30 | {
31 | using index_base::index_base;
32 |
33 | auto MethodDef() const;
34 | auto MemberRef() const;
35 | };
36 |
37 | template <> struct typed_index : index_base
38 | {
39 | using index_base::index_base;
40 |
41 | auto Module() const;
42 | auto ModuleRef() const;
43 | auto AssemblyRef() const;
44 | auto TypeRef() const;
45 | };
46 |
47 | template <> struct typed_index : index_base
48 | {
49 | using index_base::index_base;
50 |
51 | reader::TypeDef TypeDef() const;
52 | reader::TypeRef TypeRef() const;
53 | reader::TypeSpec TypeSpec() const;
54 | auto CustomAttribute() const;
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/src/impl/base.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #if defined(_WIN32)
4 | #include
5 | #include
6 | #else
7 | #include
8 | #include
9 | #include
10 | #include
11 | #endif
12 |
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include