diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9ef481f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+
+/target
+/**/*.rs.bk
+/Cargo.lock
+.DS_Store
+.vs
+
+[Bb]in/
+[Oo]bj/
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..4768290
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/windows-runtime.iml b/.idea/windows-runtime.iml
new file mode 100644
index 0000000..0f4b92c
--- /dev/null
+++ b/.idea/windows-runtime.iml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100755
index 0000000..bac9d82
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,12 @@
+[workspace]
+
+members = ["core", "core-bindings"]
+
+[profile.release]
+panic = "abort"
+codegen-units = 1
+lto = true
+#opt-level = 3
+opt-level = "z"
+debug = false
+incremental = false
\ No newline at end of file
diff --git a/TestApp/TestApp.sln b/TestApp/TestApp.sln
new file mode 100755
index 0000000..91b6f5e
--- /dev/null
+++ b/TestApp/TestApp.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31321.278
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApp", "TestApp\TestApp.csproj", "{BF77710B-81A6-4F79-9608-B9D8A7C2DF55}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BF77710B-81A6-4F79-9608-B9D8A7C2DF55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BF77710B-81A6-4F79-9608-B9D8A7C2DF55}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BF77710B-81A6-4F79-9608-B9D8A7C2DF55}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BF77710B-81A6-4F79-9608-B9D8A7C2DF55}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {D42E46BA-4BE0-4971-ADDF-4D22BFD6F2C8}
+ EndGlobalSection
+EndGlobal
diff --git a/TestApp/TestApp/App/main.js b/TestApp/TestApp/App/main.js
new file mode 100755
index 0000000..98fb8fd
--- /dev/null
+++ b/TestApp/TestApp/App/main.js
@@ -0,0 +1,7 @@
+console.log("me");
+
+console.log(Date.now(), time(), performance.now());
+
+const MessageDialog = $("Windows.UI.Popups.MessageDialog");
+const dialog = new MessageDialog("Hello, World!");
+dialog.ShowAsync();
\ No newline at end of file
diff --git a/TestApp/TestApp/Program.cs b/TestApp/TestApp/Program.cs
new file mode 100755
index 0000000..dda9bc3
--- /dev/null
+++ b/TestApp/TestApp/Program.cs
@@ -0,0 +1,29 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+namespace TestApp
+{
+ class Program
+
+ {
+
+
+
+ [DllImport("nativescript.dll")]
+ public static extern void hello();
+
+ [DllImport("nativescript.dll")]
+ public static extern Int64 runtime_init([MarshalAs(UnmanagedType.LPUTF8Str)] string entry);
+
+ [DllImport("nativescript.dll")]
+ public static extern void runtime_runscript(Int64 runtime, [MarshalAs(UnmanagedType.LPUTF8Str)] string entry);
+
+ static void Main(string[] args)
+ {
+
+ string entry = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "App\\main.js");
+ Int64 runtime = runtime_init(AppContext.BaseDirectory);
+ runtime_runscript(runtime, File.ReadAllText(Path.GetFullPath(entry)));
+ }
+ }
+}
diff --git a/TestApp/TestApp/Properties/launchSettings.json b/TestApp/TestApp/Properties/launchSettings.json
new file mode 100755
index 0000000..ce70851
--- /dev/null
+++ b/TestApp/TestApp/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "TestApp": {
+ "commandName": "Project",
+ "nativeDebugging": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/TestApp/TestApp/TestApp.csproj b/TestApp/TestApp/TestApp.csproj
new file mode 100755
index 0000000..cc7892f
--- /dev/null
+++ b/TestApp/TestApp/TestApp.csproj
@@ -0,0 +1,21 @@
+
+
+
+ Exe
+ net5.0
+
+
+
+
+ Always
+
+
+ Always
+
+
+
+
+
+
+
+
diff --git a/core-bindings/Cargo.toml b/core-bindings/Cargo.toml
new file mode 100644
index 0000000..4abc516
--- /dev/null
+++ b/core-bindings/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "core_bindings"
+version = "0.1.0"
+edition = "2018"
+build = "build.rs"
+
+[dependencies]
+windows = "0.10.0"
+
+[build-dependencies]
+windows = "0.10.0"
+cc = "1.0"
+bindgen = "0.53.1"
\ No newline at end of file
diff --git a/core-bindings/build.rs b/core-bindings/build.rs
new file mode 100644
index 0000000..ca42594
--- /dev/null
+++ b/core-bindings/build.rs
@@ -0,0 +1,64 @@
+use std::env;
+
+use std::path::PathBuf;
+use bindgen::EnumVariation;
+
+
+fn main() {
+ windows::build!(
+ Windows::Win32::System::Console::WriteConsoleA,
+ Windows::Win32::System::WindowsProgramming::STD_OUTPUT_HANDLE,
+ Windows::Win32::System::WindowsProgramming::GetStdHandle,
+ Windows::Win32::System::SystemServices::GetProcAddress,
+ Windows::Win32::System::SystemServices::LoadLibraryA,
+ Windows::Win32::System::SystemServices::FARPROC
+ );
+
+ let mut build = cc::Build::default() ;
+ build.file("src/bindings.cpp")
+ .cpp(true)
+ .include("C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\Include\\um")
+ .static_crt(true)
+ .compile("libcorebindings");
+
+ println!("cargo:rerun-if-changed=src/bindings.cpp");
+
+
+
+ let bindgen = bindgen::builder()
+ .generate_comments(false)
+ .default_enum_style(
+ EnumVariation::Rust {
+ non_exhaustive: false
+ }
+ )
+ .size_t_is_usize(true)
+ .use_core()
+ .clang_arg("-std=c++17")
+ .clang_args(&["-x", "c++"])
+ .clang_arg("-v")
+ .whitelist_function("RoResolveNamespace")
+ .whitelist_function("Rometadataresolution_.*")
+ .whitelist_function("IMetaDataImport2_.*")
+ .whitelist_function("Enums_.*")
+ .whitelist_function("Helpers_.*")
+ .whitelist_function("IRoSimpleMetaDataBuilder_.*")
+ .whitelist_var("Helpers_.*")
+ //.blacklist_type("HSTRING")
+ //.raw_line("pub type HSTRING = windows::HSTRING;")
+ .clang_args(&["-I", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\Include\\um"])
+ .header("src/bindings.cpp")
+ // Tell cargo to invalidate the built crate whenever any of the
+ // included header files changed.
+ .parse_callbacks(Box::new(bindgen::CargoCallbacks))
+ // Finish the builder and generate the bindings.
+ .generate()
+ // Unwrap the Result and panic on failure.
+ .expect("Unable to generate bindings");
+
+ // Write the bindings to the $OUT_DIR/bindings.rs file.
+ let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
+ bindgen
+ .write_to_file(out_path.join("bindings.rs"))
+ .expect("Couldn't write bindings!");
+}
\ No newline at end of file
diff --git a/core-bindings/src/bindings.cpp b/core-bindings/src/bindings.cpp
new file mode 100644
index 0000000..8443b59
--- /dev/null
+++ b/core-bindings/src/bindings.cpp
@@ -0,0 +1,691 @@
+#include "headers.h"
+
+
+typedef HRESULT (__cdecl *ProcRoGetMetaDataFile)(const HSTRING name, IMetaDataDispenserEx *, HSTRING *,
+ IMetaDataImport2 **, mdTypeDef *typeDefToken);
+
+
+typedef HRESULT(__cdecl *ProcRoParseTypeName)(const HSTRING typeName, DWORD *partsCount, HSTRING **typeNameParts);
+
+typedef HRESULT(__cdecl *ProcRoGetParameterizedTypeInstanceIID)(UINT32 nameElementCount,
+ PCWSTR *nameElements,
+ const IRoMetaDataLocator &metaDataLocator,
+ GUID *iid,
+ ROPARAMIIDHANDLE *pExtra);
+
+
+extern "C" HRESULT
+Rometadataresolution_RoGetMetaDataFile(const HSTRING name, void *metaDataDispenser, void *metaDataFilePath,
+ void **metaDataImport, mdTypeDef *typeDefToken) {
+ auto dispenser = reinterpret_cast(metaDataDispenser);
+ auto filePath = reinterpret_cast(metaDataFilePath);
+ auto import = (IMetaDataImport2 * *)(metaDataImport);
+
+ /* auto proc = (ProcRoGetMetaDataFile)GetProcAddress(
+ LoadLibraryA("api-ms-win-ro-typeresolution-l1-1-0.dll"),
+ "RoGetMetaDataFile");
+
+ return proc(name, dispenser, filePath, import, typeDefToken);
+ */
+ return RoGetMetaDataFile(name, dispenser, filePath, import, typeDefToken);
+}
+
+
+extern "C" HRESULT
+Rometadataresolution_RoParseTypeName(const HSTRING typeName, DWORD *partsCount, HSTRING **typeNameParts) {
+ /*auto proc = (ProcRoParseTypeName)GetProcAddress(
+ LoadLibraryA("api-ms-win-ro-typeresolution-l1-1-0.dll"),
+ "RoParseTypeName");
+
+ return proc(typeName, partsCount, typeNameParts);*/
+ return RoParseTypeName(typeName, partsCount, typeNameParts);
+}
+
+
+
+extern "C" HRESULT Rometadataresolution_RoGetParameterizedTypeInstanceIID(UINT32 nameElementCount,
+ PCWSTR *nameElements,
+ HRESULT(*fn)(PCWSTR name, IRoSimpleMetaDataBuilder & builder),
+ GUID *iid,
+ ROPARAMIIDHANDLE *pExtra) {
+
+
+
+ auto locatorImpl{ [&](PCWSTR name, IRoSimpleMetaDataBuilder& builder) {
+ return fn(name, builder);
+ } };
+
+
+ //auto const locator = locatorImpl;
+
+ return RoGetParameterizedTypeInstanceIID(nameElementCount, nameElements, Ro::Locator(locatorImpl), iid, pExtra);
+}
+
+//typedef HRESULT(void* RoLocator)(PCWSTR name, iro_simple_meta_data_builder& builder);
+
+
+//typedef HRESULT(*RoLocator)(PCWSTR name, iro_simple_meta_data_builder& builder);
+
+struct _locator {
+ Ro::detail::_Locator locator;
+};
+
+
+extern "C" void
+Rometadataresolution_Ro_Locator(HRESULT(*fn)(PCWSTR name, IRoSimpleMetaDataBuilder &builder), Locator *locator) {
+ /*auto proc = (ProcRoGetParameterizedTypeInstanceIID)GetProcAddress(
+ LoadLibraryA("api-ms-win-ro-typeresolution-l1-1-0.dll"),
+ "ro_get_parameterized_type_instance_iid");
+
+ return proc(nameElementCount, nameElements, metaDataLocator, iid, pExtra); */
+ locator->locator = Ro::Locator(fn);
+}
+
+/*
+extern "C" void
+Rometadataresolution_RoResolveNamespace(const HSTRING name,
+ const HSTRING windowsMetaDataDir,
+ const DWORD packageGraphDirsCount,
+ const HSTRING * packageGraphDirs,
+ DWORD * metaDataFilePathsCount,
+ HSTRING * *metaDataFilePaths,
+ DWORD * subNamespacesCount,
+ HSTRING * *subNamespaces) {
+ RoResolveNamespace()
+}
+
+
+*/
+
+extern "C" HRESULT IMetaDataImport2_GetMethodProps(IMetaDataImport2 *metadata,
+ mdMethodDef tkMethodDef,
+ mdTypeDef *ptkClass,
+ LPWSTR szMethod,
+ ULONG cchMethod,
+ ULONG *pchMethod,
+ DWORD *pdwAttr,
+ PCCOR_SIGNATURE *ppvSigBlob,
+ ULONG *pcbSigBlob,
+ ULONG *pulCodeRVA,
+ DWORD *pdwImplFlags) {
+ return metadata->GetMethodProps(tkMethodDef, ptkClass, szMethod, cchMethod, pchMethod, pdwAttr, ppvSigBlob, pcbSigBlob,
+ pulCodeRVA, pdwImplFlags);
+}
+
+extern "C" HRESULT IMetaDataImport2_GetPropertyProps(IMetaDataImport2 *metadata, mdProperty prop,
+ mdTypeDef *pClass,
+ LPCWSTR szProperty,
+ ULONG cchProperty,
+ ULONG *pchProperty,
+ DWORD *pdwPropFlags,
+ PCCOR_SIGNATURE *ppvSig,
+ ULONG *pbSig,
+ DWORD *pdwCPlusTypeFlag,
+ UVCP_CONSTANT *ppDefaultValue,
+ ULONG *pcchDefaultValue,
+ mdMethodDef *pmdSetter,
+ mdMethodDef *pmdGetter,
+ mdMethodDef *rmdOtherMethod,
+ ULONG cMax,
+ ULONG *pcOtherMethod) {
+ return metadata->GetPropertyProps(prop, pClass, szProperty, cchProperty, pchProperty, pdwPropFlags, ppvSig, pbSig,
+ pdwCPlusTypeFlag,
+ ppDefaultValue, pcchDefaultValue, pmdSetter, pmdGetter, rmdOtherMethod, cMax,
+ pcOtherMethod);
+}
+
+
+
+extern "C" HRESULT
+IMetaDataImport2_GetFieldProps(IMetaDataImport2 *metadata,
+ mdFieldDef mb,
+ mdTypeDef *pClass,
+ LPWSTR szField,
+ ULONG cchField,
+ ULONG *pchField,
+ DWORD *pdwAttr,
+ PCCOR_SIGNATURE *ppvSigBlob,
+ ULONG *pcbSigBlob,
+ DWORD *pdwCPlusTypeFlag,
+ UVCP_CONSTANT *ppValue,
+ ULONG *pcchValue) {
+
+ return metadata->GetFieldProps(mb, pClass, szField, cchField, pchField, pdwAttr, ppvSigBlob, pcbSigBlob,
+ pdwCPlusTypeFlag, ppValue, pcchValue);
+}
+
+extern "C" HRESULT
+IMetaDataImport2_GetTypeDefProps(IMetaDataImport2 *metadata, uint32_t mdTypeDef, LPWSTR szTypeDef, ULONG cchTypeDef,
+ ULONG *pchTypeDef, DWORD *pdwTypeDefFlags, mdToken *ptkExtends) {
+
+ return metadata->GetTypeDefProps(mdTypeDef, szTypeDef, cchTypeDef, pchTypeDef, pdwTypeDefFlags, ptkExtends);
+}
+
+extern "C" HRESULT IMetaDataImport2_GetTypeDefPropsNameSize(IMetaDataImport2 *metadata, uint32_t token, ULONG *pchTypeDef) {
+
+ auto size = reinterpret_cast(&pchTypeDef);
+ return metadata->GetTypeDefProps(token, 0, 0, size, 0, 0);
+}
+
+extern "C" HRESULT IMetaDataImport2_EnumParams(IMetaDataImport2 *metadata, HCORENUM *phEnum,
+ mdMethodDef mb,
+ mdParamDef *rParams,
+ ULONG cMax,
+ ULONG *pcTokens) {
+
+ return metadata->EnumParams(phEnum, mb, rParams, cMax, pcTokens);
+}
+
+extern "C" void IMetaDataImport2_CloseEnum(IMetaDataImport2 *metadata, HCORENUM phEnum) {
+
+ metadata->CloseEnum(phEnum);
+}
+
+
+
+extern "C" HRESULT IMetaDataImport2_GetParamProps(IMetaDataImport2 *metadata,
+ mdParamDef tk,
+ mdMethodDef *pmd,
+ ULONG *pulSequence,
+ LPWSTR szName,
+ ULONG cchName,
+ ULONG *pchName,
+ DWORD *pdwAttr,
+ DWORD *pdwCPlusTypeFlag,
+ UVCP_CONSTANT *ppValue,
+ ULONG *pcchValue) {
+
+ return metadata->GetParamProps(tk, pmd, pulSequence, szName, cchName, pchName, pdwAttr, pdwCPlusTypeFlag, ppValue,
+ pcchValue);
+}
+
+extern "C" HRESULT IMetaDataImport2_GetCustomAttributeByName(IMetaDataImport2 *metadata,
+ mdToken tkObj,
+ LPCWSTR szName,
+ const void **ppData,
+ ULONG *pcbData) {
+
+ return metadata->GetCustomAttributeByName(tkObj, szName, ppData, pcbData);
+}
+
+extern "C" HRESULT IMetaDataImport2_EnumInterfaceImpls(IMetaDataImport2 *metadata, HCORENUM *phEnum,
+ mdTypeDef td,
+ mdInterfaceImpl *rImpls,
+ ULONG cMax,
+ ULONG *pcImpls) {
+
+ return metadata->EnumInterfaceImpls(phEnum, td, rImpls, cMax, pcImpls);
+}
+
+extern "C" HRESULT IMetaDataImport2_GetTypeRefProps(IMetaDataImport2 *metadata, mdTypeRef tr,
+ mdToken *ptkResolutionScope,
+ LPWSTR szName,
+ ULONG cchName,
+ ULONG *pchName) {
+
+ return metadata->GetTypeRefProps(tr, ptkResolutionScope, szName, cchName, pchName);
+}
+
+extern "C" HRESULT IMetaDataImport2_FindMethod(IMetaDataImport2 *metadata, mdTypeDef td,
+ LPCWSTR szName,
+ PCCOR_SIGNATURE pvSigBlob,
+ ULONG cbSigBlob,
+ mdMethodDef *pmb) {
+
+ return metadata->FindMethod(td, szName, pvSigBlob, cbSigBlob, pmb);
+}
+
+extern "C" HRESULT IMetaDataImport2_EnumGenericParams(IMetaDataImport2 *metadata, HCORENUM *phEnum,
+ mdToken tk,
+ mdGenericParam rGenericParams[],
+ ULONG cMax,
+ ULONG *pcGenericParams) {
+
+ return metadata->EnumGenericParams(phEnum, tk, rGenericParams, cMax, pcGenericParams);
+}
+
+
+extern "C" HRESULT IMetaDataImport2_CountEnum(IMetaDataImport2 *metadata, HCORENUM hEnum, ULONG *pulCount) {
+
+ return metadata->CountEnum(hEnum, pulCount);
+}
+
+extern "C" HRESULT IMetaDataImport2_GetTypeSpecFromToken(IMetaDataImport2 *metadata, mdTypeSpec typespec,
+ PCCOR_SIGNATURE *ppvSig,
+ ULONG *pcbSig) {
+
+ return metadata->GetTypeSpecFromToken(typespec, ppvSig, pcbSig);
+}
+
+
+extern "C" HRESULT IMetaDataImport2_EnumFields(IMetaDataImport2 *metadata, HCORENUM *phEnum,
+ mdTypeDef tkTypeDef,
+ mdFieldDef rgFields[],
+ ULONG cMax,
+ ULONG *pcTokens) {
+
+ return metadata->EnumFields(phEnum, tkTypeDef, rgFields, cMax, pcTokens);
+}
+
+
+extern "C" HRESULT IMetaDataImport2_EnumMethodsWithName(IMetaDataImport2 *metadata, HCORENUM *phEnum,
+ mdTypeDef tkTypeDef,
+ LPCWSTR szName,
+ mdMethodDef rgMethods[],
+ ULONG cMax,
+ ULONG *pcTokens) {
+
+ return metadata->EnumMethodsWithName(phEnum, tkTypeDef, szName, rgMethods, cMax, pcTokens);
+}
+
+extern "C" HRESULT IMetaDataImport2_GetInterfaceImplProps(IMetaDataImport2 *metadata, mdInterfaceImpl tkInterfaceImpl,
+ mdTypeDef *ptkClass,
+ mdToken *ptkIface) {
+
+ return metadata->GetInterfaceImplProps(tkInterfaceImpl, ptkClass, ptkIface);
+}
+
+extern "C" HRESULT IMetaDataImport2_EnumMethods(IMetaDataImport2 *metadata, HCORENUM *phEnum,
+ mdTypeDef tkTypeDef,
+ mdMethodDef rgMethods[],
+ ULONG cMax,
+ ULONG *pcTokens) {
+
+ return metadata->EnumMethods(phEnum, tkTypeDef, rgMethods, cMax, pcTokens);
+}
+
+
+extern "C" HRESULT IMetaDataImport2_EnumProperties(IMetaDataImport2 *metadata, HCORENUM *phEnum,
+ mdTypeDef tkTypDef,
+ mdProperty rgProperties[],
+ ULONG cMax,
+ ULONG *pcProperties) {
+
+ return metadata->EnumProperties(phEnum, tkTypDef, rgProperties, cMax, pcProperties);
+}
+
+extern "C" HRESULT IMetaDataImport2_EnumEvents(IMetaDataImport2 *metadata, HCORENUM *phEnum,
+ mdTypeDef tkTypDef,
+ mdEvent rgEvents[],
+ ULONG cMax,
+ ULONG *pcEvents) {
+
+ return metadata->EnumEvents(phEnum, tkTypDef, rgEvents, cMax, pcEvents);
+}
+
+extern "C" HRESULT IMetaDataImport2_GetEventProps(IMetaDataImport2 *metadata, mdEvent ev,
+ mdTypeDef *pClass,
+ LPCWSTR szEvent,
+ ULONG cchEvent,
+ ULONG *pchEvent,
+ DWORD *pdwEventFlags,
+ mdToken *ptkEventType,
+ mdMethodDef *pmdAddOn,
+ mdMethodDef *pmdRemoveOn,
+ mdMethodDef *pmdFire,
+ mdMethodDef rmdOtherMethod[],
+ ULONG cMax,
+ ULONG *pcOtherMethod) {
+
+ return metadata->GetEventProps(ev, pClass, szEvent, cchEvent, pchEvent, pdwEventFlags, ptkEventType, pmdAddOn,
+ pmdRemoveOn, pmdFire, rmdOtherMethod, cMax, pcOtherMethod);
+}
+
+
+extern "C" HRESULT IMetaDataImport2_FindField(IMetaDataImport2* metadata, mdTypeDef td,
+ LPCWSTR szName,
+ PCCOR_SIGNATURE pvSigBlob,
+ ULONG cbSigBlob,
+ mdFieldDef * pmb) {
+ return metadata->FindField(td, szName, pvSigBlob, cbSigBlob, pmb);
+}
+
+extern "C" HRESULT IMetaDataImport2_GetMemberRefProps(IMetaDataImport2* metadata, mdMemberRef tkMemberRef,
+ mdToken * ptk,
+ LPWSTR szMember,
+ ULONG cchMember,
+ ULONG * pchMember,
+ PCCOR_SIGNATURE * ppvSigBlob,
+ ULONG * pcbSigBlob) {
+ return metadata->GetMemberRefProps(tkMemberRef, ptk, szMember, cchMember, pchMember, ppvSigBlob, pcbSigBlob);
+}
+
+extern "C" HRESULT IMetaDataImport2_GetCustomAttributeProps(IMetaDataImport2* metadata, mdCustomAttribute cv,
+ mdToken * ptkObj,
+ mdToken * ptkType,
+ const BYTE * *ppBlob,
+ ULONG * pcbBlob) {
+ auto blob = reinterpret_cast(ppBlob);
+ return metadata->GetCustomAttributeProps(cv, ptkObj, ptkType, blob, pcbBlob);
+}
+
+extern "C" HRESULT IMetaDataImport2_EnumCustomAttributes(IMetaDataImport2 * metadata, HCORENUM * phEnum,
+ mdToken tk,
+ mdToken tkType,
+ mdCustomAttribute rgCustomAttributes[],
+ ULONG cMax,
+ ULONG * pcCustomAttributes) {
+ return metadata->EnumCustomAttributes(phEnum, tk, tkType, rgCustomAttributes, cMax, pcCustomAttributes);
+}
+
+extern "C" HRESULT IMetaDataImport2_FindTypeDefByName(IMetaDataImport2 * metadata, LPCWSTR szTypeDef,
+ mdToken tkEnclosingClass,
+ mdTypeDef * ptkTypeDef) {
+ return metadata->FindTypeDefByName(szTypeDef, tkEnclosingClass, ptkTypeDef);
+}
+
+extern "C" HRESULT IMetaDataImport2_EnumMethodImpls(IMetaDataImport2 * metadata, HCORENUM * phEnum,
+ mdTypeDef tkTypeDef,
+ mdToken rMethodBody[],
+ mdToken rMethodDecl[],
+ ULONG cMax,
+ ULONG * pcTokens) {
+ return metadata->EnumMethodImpls(phEnum, tkTypeDef, rMethodBody, rMethodDecl, cMax, pcTokens);
+}
+
+
+
+extern "C" HRESULT IRoSimpleMetaDataBuilder_SetRuntimeClassSimpleDefault(IRoSimpleMetaDataBuilder* builder, PCWSTR name,
+ PCWSTR defaultInterfaceName,
+ const GUID * defaultInterfaceIID) {
+ return builder->SetRuntimeClassSimpleDefault(name, defaultInterfaceName, defaultInterfaceIID);
+}
+
+extern "C" HRESULT IRoSimpleMetaDataBuilder_SetWinRtInterface(IRoSimpleMetaDataBuilder * builder, GUID iid) {
+ return builder->SetWinRtInterface(iid);
+}
+
+extern "C" HRESULT IRoSimpleMetaDataBuilder_SetParameterizedInterface(IRoSimpleMetaDataBuilder* builder, GUID piid,
+ UINT32 numArgs) {
+ return builder->SetParameterizedInterface(piid,numArgs);
+}
+
+extern "C" HRESULT IRoSimpleMetaDataBuilder_SetEnum(IRoSimpleMetaDataBuilder * builder, PCWSTR name,
+ PCWSTR baseType) {
+ return builder->SetEnum(name, baseType);
+}
+
+
+extern "C" HRESULT IRoSimpleMetaDataBuilder_SetStruct(IRoSimpleMetaDataBuilder * builder, PCWSTR name,
+ UINT32 numFields,
+ const PCWSTR * fieldTypeNames) {
+ return builder->SetStruct(name, numFields, fieldTypeNames);
+}
+
+
+extern "C" HRESULT IRoSimpleMetaDataBuilder_SetDelegate(IRoSimpleMetaDataBuilder * builder, GUID iid) {
+ return builder->SetDelegate(iid);
+}
+
+
+extern "C" HRESULT IRoSimpleMetaDataBuilder_SetParameterizedDelegate(IRoSimpleMetaDataBuilder * builder, GUID piid,
+ UINT32 numArgs) {
+ return builder->SetParameterizedDelegate(piid, numArgs);
+}
+
+
+
+extern "C" ULONG32 Enums_TypeFromToken(mdToken token) {
+ return TypeFromToken(token);
+}
+
+
+extern "C" ULONG Helpers_Get_Type_Name(IMetaDataImport2 *metadata, mdToken token, uint16_t *nameData, ULONG nameSize) {
+
+ ULONG nameLength{0};
+ auto data = reinterpret_cast(nameData);
+
+ switch (TypeFromToken(token)) {
+ case CorTokenType::mdtTypeDef: {
+ metadata->GetTypeDefProps(token, data, nameSize, &nameLength, nullptr, nullptr);
+ break;
+ }
+ case CorTokenType::mdtTypeRef: {
+ metadata->GetTypeRefProps(token, nullptr, data, nameSize, &nameLength);
+ break;
+ }
+ default:
+ assert(false);
+ break;
+ }
+
+ return nameLength - 1;
+}
+
+extern "C" BOOL Helpers_IsTdPublic(DWORD value) {
+ return IsTdPublic(value);
+}
+
+extern "C" BOOL Helpers_IsTdSpecialName(DWORD value) {
+ return IsTdSpecialName(value);
+}
+
+extern "C" ULONG Helpers_CorSigUncompressCallingConv(PCCOR_SIGNATURE pData) {
+ return CorSigUncompressCallingConv(pData);
+}
+
+
+extern "C" ULONG Helpers_CorSigUncompressData(PCCOR_SIGNATURE pData) {
+ return CorSigUncompressData(pData);
+}
+
+extern "C" CorElementType Helpers_CorSigUncompressElementType(PCCOR_SIGNATURE pData) {
+ return CorSigUncompressElementType(pData);
+}
+
+extern "C" mdToken Helpers_CorSigUncompressToken(PCCOR_SIGNATURE pData) {
+ return CorSigUncompressToken(pData);
+}
+
+extern "C" size_t Helpers_to_wstring(ULONG index, wchar_t *text) {
+ using namespace std;
+ auto str = to_wstring(index);
+ auto txt = std::wstring(text);
+ txt += str;
+ wcscpy(text, txt.c_str());
+ return str.length() - 1;
+}
+
+extern "C" BOOL Helpers_IsMdPublic(DWORD value) {
+ return IsMdPublic(value);
+}
+
+extern "C" BOOL Helpers_IsMdFamily(DWORD value) {
+ return IsMdFamily(value);
+}
+
+extern "C" BOOL Helpers_IsMdFamORAssem(DWORD value) {
+ return IsMdFamORAssem(value);
+}
+
+extern "C" BOOL Helpers_IsMdSpecialName(DWORD value) {
+ return IsMdSpecialName(value);
+}
+
+extern "C" BOOL Helpers_IsMdStatic(DWORD value) {
+ return IsMdStatic(value);
+}
+
+extern "C" BOOL Helpers_IsMdFinal(DWORD value) {
+ return IsMdFinal(value);
+}
+
+extern "C" BOOL Helpers_IsMdInstanceInitializerW(DWORD flags, const wchar_t *nameData) {
+ return IsMdInstanceInitializerW(flags, nameData);
+}
+
+extern "C" BOOL Helpers_IsPrSpecialName(DWORD value) {
+ return IsPrSpecialName(value);
+}
+
+
+extern "C" void Helpers_bytesToGuid(uint8_t *data, GUID *iid) {
+ *iid = *reinterpret_cast(data);
+}
+
+extern "C" PCWSTR Helpers_WindowsGetStringRawBuffer(HSTRING string,
+ UINT32 *length) {
+ return WindowsGetStringRawBuffer(string, length);
+}
+
+extern "C" BOOL Helpers_IsTdInterface(DWORD value) {
+ return IsTdInterface(value);
+}
+
+extern "C" BOOL Helpers_IsTdClass(DWORD value) {
+ return IsTdClass(value);
+}
+
+extern "C" BOOL Helpers_IsEvSpecialName(DWORD value) {
+ return IsEvSpecialName(value);
+}
+
+extern "C" void Helpers_generate_id_name(PCWSTR* namePartsW, wchar_t* declarationFullName, DWORD * namePartsCount) {
+ using namespace Microsoft::WRL::Wrappers;
+ HSTRING* nameParts{ nullptr };
+ RoParseTypeName(HStringReference(declarationFullName).Get(), namePartsCount, &nameParts);
+
+ size_t count = (size_t)(namePartsCount);
+ for (size_t i = 0; i < count; ++i) {
+ namePartsW[i] = WindowsGetStringRawBuffer(nameParts[i], nullptr);
+ }
+
+
+}
+
+extern "C" void Helpers_toString_length(PCWSTR value, size_t * count) {
+ using namespace Microsoft::WRL::Wrappers;
+ *count = wcslen(value);
+}
+
+
+extern "C" BOOL Helpers_IsTdSealed(DWORD value) {
+ return IsTdSealed(value);
+}
+
+
+/*
+extern "C" HRESULT GenericInstanceIdBuilder_locatorImpl(PCWSTR name, iro_simple_meta_data_builder & builder) {
+ shared_ptr declaration{ metadataReader.findByName(name) };
+ ASSERT(declaration);
+
+ DeclarationKind kind{ declaration->kind() };
+ switch (kind) {
+ case DeclarationKind::Class: {
+ ClassDeclaration* classDeclaration{ static_cast(declaration.get()) };
+ const InterfaceDeclaration& defaultInterface{ classDeclaration->defaultInterface() };
+ IID defaultInterfaceId = defaultInterface.id();
+ ASSERT_SUCCESS(builder.set_runtime_class_simple_default(name, defaultInterface.fullName().data(), &defaultInterfaceId));
+ return S_OK;
+ }
+
+ case DeclarationKind::Interface: {
+ InterfaceDeclaration* interfaceDeclaration{ static_cast(declaration.get()) };
+ ASSERT_SUCCESS(builder.set_win_rt_interface(interfaceDeclaration->id()));
+ return S_OK;
+ }
+
+ case DeclarationKind::GenericInterface: {
+ GenericInterfaceDeclaration* genericInterfaceDeclaration{ static_cast(declaration.get()) };
+ ASSERT_SUCCESS(builder.set_parameterized_interface(genericInterfaceDeclaration->id(), genericInterfaceDeclaration->number_of_generic_parameters()));
+ return S_OK;
+ }
+
+ case DeclarationKind::Enum: {
+ EnumDeclaration* enumDeclaration{ static_cast(declaration.get()) };
+ ASSERT_SUCCESS(builder.set_enum(enumDeclaration->fullName().data(), Signature::toString(nullptr, enumDeclaration->type()).data()));
+ return S_OK;
+ }
+
+ case DeclarationKind::Struct: {
+ StructDeclaration* structDeclaration{ static_cast(declaration.get()) };
+
+ vector fieldNames;
+ for (const StructFieldDeclaration& field : *structDeclaration) {
+ fieldNames.push_back(Signature::toString(field._metadata.Get(), field.type()));
+ }
+
+ vector fieldNamesW;
+ for (wstring& fieldName : fieldNames) {
+ fieldNamesW.push_back(const_cast(fieldName.data()));
+ }
+
+ ASSERT_SUCCESS(builder.set_struct(structDeclaration->fullName().data(), structDeclaration->size(), fieldNamesW.data()));
+ return S_OK;
+ }
+
+ case DeclarationKind::Delegate: {
+ DelegateDeclaration* delegateDeclaration{ static_cast(declaration.get()) };
+ ASSERT_SUCCESS(builder.set_delegate(delegateDeclaration->id()));
+ return S_OK;
+ }
+
+ case DeclarationKind::GenericDelegate: {
+ GenericDelegateDeclaration* genericDelegateDeclaration{ static_cast(declaration.get()) };
+ ASSERT_SUCCESS(builder.set_parameterized_delegate(genericDelegateDeclaration->id(), genericDelegateDeclaration->number_of_generic_parameters()));
+ return S_OK;
+ }
+
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+
+extern "C" void GenericInstanceIdBuilder_generateId(wchar_t * fullName, GUID * iid) {
+ wstring declarationFullName = std::wstring(fullName);
+
+ HSTRING* nameParts{ nullptr };
+ DWORD namePartsCount{ 0 };
+ ASSERT_SUCCESS(RoParseTypeName(HStringReference(declarationFullName.data()).Get(), &namePartsCount, &nameParts));
+
+ array namePartsW;
+ ASSERT(namePartsCount < namePartsW.size());
+
+ for (size_t i = 0; i < namePartsCount; ++i) {
+ namePartsW[i] = WindowsGetStringRawBuffer(nameParts[i], nullptr);
+ }
+
+
+ ASSERT_SUCCESS(ro_get_parameterized_type_instance_iid(namePartsCount, namePartsW.data(), Ro::Locator(&GenericInstanceIdBuilder_locatorImpl), &guid, nullptr));
+
+ for (size_t i = 0; i < namePartsCount; ++i) {
+ ASSERT_SUCCESS(WindowsDeleteString(nameParts[i]));
+ }
+
+ CoTaskMemFree(nameParts);
+
+ return guid;
+}
+
+*/
+
+extern "C" HRESULT Helpers_RO_E_METADATA_NAME_IS_NAMESPACE = RO_E_METADATA_NAME_IS_NAMESPACE;
+
+extern "C" mdToken Helpers_mdTokenNil = mdTokenNil;
+extern "C" mdToken Helpers_mdModuleNil = mdModuleNil;
+extern "C" mdToken Helpers_mdTypeRefNil = mdTypeRefNil;
+extern "C" mdToken Helpers_mdTypeDefNil = mdTypeDefNil;
+extern "C" mdToken Helpers_mdFieldDefNil = mdFieldDefNil;
+extern "C" mdToken Helpers_mdMethodDefNil = mdMethodDefNil;
+extern "C" mdToken Helpers_mdParamDefNil = mdParamDefNil;
+extern "C" mdToken Helpers_mdInterfaceImplNil = mdInterfaceImplNil;
+extern "C" mdToken Helpers_mdMemberRefNil = mdMemberRefNil;
+extern "C" mdToken Helpers_mdCustomAttributeNil = mdCustomAttributeNil;
+extern "C" mdToken Helpers_mdPermissionNil = mdPermissionNil;
+extern "C" mdToken Helpers_mdSignatureNil = mdSignatureNil;
+extern "C" mdToken Helpers_mdEventNil = mdEventNil;
+extern "C" mdToken Helpers_mdPropertyNil = mdPropertyNil;
+extern "C" mdToken Helpers_mdModuleRefNil = mdModuleRefNil;
+extern "C" mdToken Helpers_mdTypeSpecNil = mdTypeSpecNil;
+extern "C" mdToken Helpers_mdAssemblyNil = mdAssemblyNil;
+extern "C" mdToken Helpers_mdAssemblyRefNil = mdAssemblyRefNil;
+extern "C" mdToken Helpers_mdFileNil = mdFileNil;
+extern "C" mdToken Helpers_mdExportedTypeNil = mdExportedTypeNil;
+extern "C" mdToken Helpers_mdManifestResourceNil = mdManifestResourceNil;
+
+extern "C" mdToken Helpers_mdGenericParamNil = mdGenericParamNil;
+extern "C" mdToken Helpers_mdGenericParamConstraintNil = mdGenericParamConstraintNil;
+extern "C" mdToken Helpers_mdMethodSpecNil = mdMethodSpecNil;
+
+extern "C" mdToken Helpers_mdStringNil = mdStringNil;
\ No newline at end of file
diff --git a/core-bindings/src/headers.h b/core-bindings/src/headers.h
new file mode 100644
index 0000000..ac2769c
--- /dev/null
+++ b/core-bindings/src/headers.h
@@ -0,0 +1,21 @@
+#include
+#include
+#include
+# define NDEBUG
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+
+const size_t MAX_IDENTIFIER_LENGTH{ 511 };
+using identifier = std::array;
+
+typedef struct _locator Locator;
\ No newline at end of file
diff --git a/core-bindings/src/lib.rs b/core-bindings/src/lib.rs
new file mode 100644
index 0000000..02f8704
--- /dev/null
+++ b/core-bindings/src/lib.rs
@@ -0,0 +1,26 @@
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+windows::include_bindings!();
+
+
+include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+
+
+impl GUID {
+ pub fn new() -> Self {
+ Self {
+ Data1: 0,
+ Data2: 0,
+ Data3: 0,
+ Data4: [0_u8;8]
+ }
+ }
+}
+
+impl Default for GUID {
+ fn default() -> Self {
+ Self::new()
+ }
+}
\ No newline at end of file
diff --git a/core/.gitignore b/core/.gitignore
new file mode 100755
index 0000000..96ef6c0
--- /dev/null
+++ b/core/.gitignore
@@ -0,0 +1,2 @@
+/target
+Cargo.lock
diff --git a/core/.idea/.gitignore b/core/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/core/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/core/.idea/core.iml b/core/.idea/core.iml
new file mode 100644
index 0000000..bc2cd87
--- /dev/null
+++ b/core/.idea/core.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/.idea/modules.xml b/core/.idea/modules.xml
new file mode 100644
index 0000000..402ffa7
--- /dev/null
+++ b/core/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/.idea/vcs.xml b/core/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/core/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/Cargo.toml b/core/Cargo.toml
new file mode 100755
index 0000000..c5838a3
--- /dev/null
+++ b/core/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "core"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+name = "nativescript"
+crate-type = ["dylib"]
+
+
+[dependencies]
+windows = "0.13.0"
+rusty_v8 = "0.23.0"
+core_bindings = { package = "core_bindings", path = "../core-bindings" }
+chrono = "0.4.19"
+libc = "0.2.97"
+lazy_static = "1.4.0"
diff --git a/core/src/bindings/imeta_data_import2.rs b/core/src/bindings/imeta_data_import2.rs
new file mode 100644
index 0000000..a6bfa47
--- /dev/null
+++ b/core/src/bindings/imeta_data_import2.rs
@@ -0,0 +1,608 @@
+use crate::prelude::*;
+use windows::HRESULT;
+pub struct IMetaDataImport2(IMetaDataImport2_);
+
+
+impl IMetaDataImport2 {
+ pub(crate) fn empty() -> Self {
+ Self(std::ptr::null_mut())
+ }
+ pub(crate) fn inner(&self) -> &core_bindings::IMetaDataImport2 {
+ &self.0
+ }
+ pub fn get_type_def_props(
+ &self,
+ md_type_def: c_uint,
+ sz_type_def: Option<&mut [u16]>,
+ cch_type_def: Option,
+ pch_type_def: Option<&mut ULONG>,
+ pdw_type_def_flags: Option<&mut ULONG>,
+ md_token: Option<&mut ULONG32>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_GetTypeDefProps(
+ &self.0 as _,
+ md_type_def,
+ sz_type_def.unwrap_or_default().as_mut_ptr(),
+ cch_type_def.unwrap_or(0),
+ pch_type_def.unwrap_or(&mut 0),
+ pdw_type_def_flags.unwrap_or(0 as _),
+ md_token.unwrap_or(&mut 0),
+ ) as u32)
+ }
+ }
+
+ pub fn get_type_def_props_name_size(
+ &self,
+ md_type_def: c_uint,
+ pch_type_def: &mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_GetTypeDefPropsNameSize(
+ &self.0 as _,
+ md_type_def,
+ pch_type_def,
+ ) as u32)
+ }
+ }
+
+ pub fn get_field_props(
+ &self,
+ mb: mdFieldDef,
+ p_class: Option<&mut mdTypeDef>,
+ sz_field: Option<&mut [u16]>,
+ cch_field: Option,
+ pch_field: Option<&mut ULONG>,
+ pdw_attr: Option<&mut DWORD>,
+ ppv_sig_blob: Option<*mut PCCOR_SIGNATURE>,
+ pcb_sig_blob: Option<&mut ULONG>,
+ pdw_cplus_type_flag: Option<&mut DWORD>,
+ pp_value: Option<&mut UVCP_CONSTANT>,
+ pcch_value: Option<&mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_GetFieldProps(
+ &self.0 as _,
+ mb,
+ p_class.unwrap_or(0 as _),
+ sz_field.unwrap_or_default().as_mut_ptr(),
+ cch_field.unwrap_or_default(),
+ pch_field.unwrap_or(0 as _),
+ pdw_attr.unwrap_or(0 as _),
+ ppv_sig_blob.unwrap_or(0 as _),
+ pcb_sig_blob.unwrap_or(0 as _),
+ pdw_cplus_type_flag.unwrap_or(0 as _),
+ pp_value.unwrap_or(0 as _),
+ pcch_value.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn get_property_props(
+ &self,
+ prop: mdProperty,
+ p_class: Option<&mut mdTypeDef>,
+ sz_property: Option<&mut [u16]>,
+ cch_property: Option,
+ pch_property: Option<&mut ULONG>,
+ pdw_prop_flags: Option<*mut DWORD>,
+ ppv_sig: Option<*mut PCCOR_SIGNATURE>,
+ pb_sig: Option<&mut ULONG>,
+ pdw_cplus_type_flag: Option<&mut DWORD>,
+ pp_default_value: Option<*mut UVCP_CONSTANT>,
+ pcch_default_value: Option<*mut ULONG>,
+ pmd_setter: Option<&mut mdMethodDef>,
+ pmd_getter: Option<&mut mdMethodDef>,
+ rmd_other_method: Option<&mut [mdMethodDef]>,
+ c_max: Option,
+ pc_other_method: Option<*mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_GetPropertyProps(
+ &self.0 as _,
+ prop,
+ p_class.unwrap_or(0 as _),
+ sz_property.unwrap_or_default().as_mut_ptr(),
+ cch_property.unwrap_or_default(),
+ pch_property.unwrap_or(0 as _),
+ pdw_prop_flags.unwrap_or(0 as _),
+ ppv_sig.unwrap_or(0 as _),
+ pb_sig.unwrap_or(0 as _),
+ pdw_cplus_type_flag.unwrap_or(0 as _),
+ pp_default_value.unwrap_or(0 as _),
+ pcch_default_value.unwrap_or(0 as _),
+ pmd_setter.unwrap_or(0 as _),
+ pmd_getter.unwrap_or(0 as _),
+ rmd_other_method.unwrap_or_default().as_mut_ptr(),
+ c_max.unwrap_or_default(),
+ pc_other_method.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn get_method_props(
+ &self,
+ tk_method_def: mdMethodDef,
+ ptk_class: Option<&mut mdTypeDef>,
+ sz_method: Option<&mut [u16]>,
+ cch_method: Option,
+ pch_method: Option<&mut ULONG>,
+ pdw_attr: Option<&mut DWORD>,
+ ppv_sig_blob: Option<*mut PCCOR_SIGNATURE>,
+ pcb_sig_blob: Option<&mut ULONG>,
+ pul_code_rva: Option<&mut ULONG>,
+ pdw_impl_flags: Option<&mut DWORD>,
+ ) -> windows::HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_GetMethodProps(
+ &self.0 as _,
+ tk_method_def,
+ ptk_class.unwrap_or(0 as _),
+ sz_method.unwrap_or_default().as_mut_ptr(),
+ cch_method.unwrap_or_default(),
+ pch_method.unwrap_or(0 as _),
+ pdw_attr.unwrap_or(0 as _),
+ ppv_sig_blob.unwrap_or(0 as _),
+ pcb_sig_blob.unwrap_or(0 as _),
+ pul_code_rva.unwrap_or(0 as _),
+ pdw_impl_flags.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn enum_params(
+ &self,
+ ph_enum: *mut HCORENUM,
+ mb: mdMethodDef,
+ r_params: &mut [mdParamDef],
+ c_max: ULONG,
+ pc_tokens: &mut ULONG,
+ ) -> windows::HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_EnumParams(
+ &self.0 as _,
+ ph_enum,
+ mb,
+ r_params.as_mut_ptr(),
+ c_max,
+ pc_tokens,
+ ) as u32)
+ }
+ }
+
+ pub fn close_enum(&self, ph_enum: HCORENUM) {
+ unsafe { core_bindings::IMetaDataImport2_CloseEnum(&self.0 as _, ph_enum) }
+ }
+
+ pub fn get_param_props(
+ &self,
+ tk: mdParamDef,
+ pmd: Option<&mut mdMethodDef>,
+ pul_sequence: Option<&mut ULONG>,
+ sz_name: Option<&mut [u16]>,
+ cch_name: Option,
+ pch_name: Option<&mut ULONG>,
+ pdw_attr: Option<&mut DWORD>,
+ pdw_cplus_type_flag: Option<&mut DWORD>,
+ pp_value: Option<*mut UVCP_CONSTANT>,
+ pcch_value: Option<&mut ULONG>,
+ ) -> windows::HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_GetParamProps(
+ self.0 as _,
+ tk,
+ pmd.unwrap_or(0 as _),
+ pul_sequence.unwrap_or(0 as _),
+ sz_name.unwrap_or_default().as_mut_ptr(),
+ cch_name.unwrap_or_default(),
+ pch_name.unwrap_or(0 as _),
+ pdw_attr.unwrap_or(0 as _),
+ pdw_cplus_type_flag.unwrap_or(0 as _),
+ pp_value.unwrap_or(0 as _),
+ pcch_value.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn get_custom_attribute_by_name(
+ &self,
+ tk_obj: mdToken,
+ sz_name: Option<&[u16]>,
+ pp_data: Option<*mut *const ::core::ffi::c_void>,
+ pcb_data: Option<&mut ULONG>,
+ ) -> windows::HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_GetCustomAttributeByName(
+ &self.0 as _,
+ tk_obj,
+ sz_name.unwrap_or_default().as_ptr(),
+ pp_data.unwrap_or(0 as _),
+ pcb_data.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn enum_interface_impls(
+ &self,
+ ph_enum: *mut HCORENUM,
+ td: Option,
+ r_impls: Option<&mut [mdInterfaceImpl]>,
+ c_max: Option,
+ pc_impls: Option<&mut ULONG>,
+ ) -> windows::HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_EnumInterfaceImpls(
+ &self.0 as _,
+ ph_enum,
+ td.unwrap_or_default(),
+ r_impls.unwrap_or_default().as_mut_ptr(),
+ c_max.unwrap_or(0 as _),
+ pc_impls.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn get_type_ref_props(
+ &self,
+ tr: mdTypeRef,
+ ptk_resolution_scope: Option<&mut mdToken>,
+ sz_name: Option<&mut [u16]>,
+ cch_name: Option,
+ pch_name: Option<&mut ULONG>,
+ ) -> windows::HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_GetTypeRefProps(
+ &self.0 as _,
+ tr,
+ ptk_resolution_scope.unwrap_or(0 as _),
+ sz_name.unwrap_or_default().as_mut_ptr(),
+ cch_name.unwrap_or_default(),
+ pch_name.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn find_method(
+ &self,
+ td: mdTypeDef,
+ sz_name: LPCWSTR,
+ pv_sig_blob: Option,
+ cb_sig_blob: Option,
+ pmb: Option<&mut mdMethodDef>,
+ ) -> windows::HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_FindMethod(
+ &self.0 as _,
+ td,
+ sz_name,
+ pv_sig_blob.unwrap_or(0 as _),
+ cb_sig_blob.unwrap_or_default(),
+ pmb.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn enum_generic_params(
+ &self,
+ ph_enum: *mut HCORENUM,
+ tk: mdToken,
+ r_generic_params: Option<&mut [mdGenericParam]>,
+ c_max: Option,
+ pc_generic_params: Option<&mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_EnumGenericParams(
+ &self.0 as _,
+ ph_enum,
+ tk,
+ r_generic_params.unwrap_or_default().as_mut_ptr(),
+ c_max.unwrap_or_default(),
+ pc_generic_params.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn count_enum(&self, h_enum: HCORENUM, pul_count: *mut ULONG) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_CountEnum(
+ &self.0 as _,
+ h_enum,
+ pul_count,
+ ) as u32)
+ }
+ }
+
+ pub fn get_type_spec_from_token(
+ &self,
+ typespec: mdTypeSpec,
+ ppv_sig: *mut PCCOR_SIGNATURE,
+ pcb_sig: &mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_GetTypeSpecFromToken(
+ &self.0 as _,
+ typespec,
+ ppv_sig,
+ pcb_sig,
+ ) as u32)
+ }
+ }
+
+ pub fn enum_fields(
+ &self,
+ ph_enum: *mut HCORENUM,
+ tk_type_def: mdTypeDef,
+ rg_fields: &mut [mdFieldDef],
+ c_max: ULONG,
+ pc_tokens: &mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_EnumFields(
+ &self.0 as _,
+ ph_enum,
+ tk_type_def,
+ rg_fields,
+ c_max,
+ pc_tokens,
+ ) as u32)
+ }
+ }
+
+ pub fn enum_methods_with_name(
+ &self,
+ ph_enum: &mut HCORENUM,
+ tk_type_def: mdTypeDef,
+ sz_name: LPCWSTR,
+ rg_methods: &mut [mdMethodDef],
+ c_max: ULONG,
+ pc_tokens: &mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_EnumMethodsWithName(
+ &self.0 as _,
+ ph_enum,
+ tk_type_def,
+ sz_name,
+ rg_methods.as_mut_ptr(),
+ c_max,
+ pc_tokens,
+ ) as u32)
+ }
+ }
+
+ pub fn get_interface_impl_props(
+ &self,
+ tk_interface_impl: mdInterfaceImpl,
+ ptk_class: Option<&mut mdTypeDef>,
+ ptk_iface: Option<&mut mdToken>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_GetInterfaceImplProps(
+ &self.0 as _,
+ tk_interface_impl,
+ ptk_class.unwrap_or(0 as _),
+ ptk_iface.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn enum_methods(
+ &self,
+ ph_enum: &mut HCORENUM,
+ tk_type_def: mdTypeDef,
+ rg_methods: &mut [mdMethodDef],
+ c_max: ULONG,
+ pc_tokens: &mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_EnumMethods(
+ &self.0 as _,
+ ph_enum,
+ tk_type_def,
+ rg_methods.as_mut_ptr(),
+ c_max,
+ pc_tokens,
+ ) as u32)
+ }
+ }
+
+ pub fn enum_properties(
+ &self,
+ ph_enum: *mut HCORENUM,
+ tk_typ_def: mdTypeDef,
+ rg_properties: &mut [mdProperty],
+ c_max: ULONG,
+ pc_properties: &mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_EnumProperties(
+ &self.0 as _,
+ ph_enum,
+ tk_typ_def,
+ rg_properties,
+ c_max,
+ pc_properties,
+ ) as u32)
+ }
+ }
+
+ pub fn enum_events(
+ &self,
+ ph_enum: *mut HCORENUM,
+ tk_typ_def: mdTypeDef,
+ rg_events: &mut [mdEvent],
+ c_max: ULONG,
+ pc_events: &mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_EnumEvents(
+ &self.0 as _,
+ ph_enum,
+ tk_typ_def,
+ rg_events,
+ c_max,
+ pc_events,
+ ) as u32)
+ }
+ }
+
+ pub fn get_event_props(
+ &self,
+ ev: mdEvent,
+ p_class: Option<&mut mdTypeDef>,
+ sz_event: Option,
+ cch_event: Option,
+ pch_event: Option<&mut ULONG>,
+ pdw_event_flags: Option<&mut DWORD>,
+ ptk_event_type: Option<&mut mdToken>,
+ pmd_add_on: Option<&mut mdMethodDef>,
+ pmd_remove_on: Option<&mut mdMethodDef>,
+ pmd_fire: Option<&mut mdMethodDef>,
+ rmd_other_method: Option<&mut [mdMethodDef]>,
+ c_max: Option,
+ pc_other_method: Option<&mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_GetEventProps(
+ &self.0 as _,
+ ev,
+ p_class.unwrap_or(0 as _),
+ sz_event.unwrap_or(0 as _),
+ cch_event.unwrap_or_default(),
+ pch_event.unwrap_or(0 as _),
+ pdw_event_flags.unwrap_or(0 as _),
+ ptk_event_type.unwrap_or(0 as _),
+ pmd_add_on.unwrap_or(0 as _),
+ pmd_remove_on.unwrap_or(0 as _),
+ pmd_fire.unwrap_or(0 as _),
+ rmd_other_method.unwrap_or_default().as_mut_ptr(),
+ c_max.unwrap_or_default(),
+ pc_other_method.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn find_field(
+ &self,
+ td: mdTypeDef,
+ sz_name: Option,
+ pv_sig_blob: Option,
+ cb_sig_blob: Option,
+ pmb: Option<&mut mdFieldDef>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_FindField(
+ &self.0 as _,
+ td,
+ sz_name.unwrap_or(0 as _),
+ pv_sig_blob.unwrap_or(0 as _),
+ cb_sig_blob.unwrap_or_default(),
+ pmb.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn get_member_ref_props(
+ &self,
+ tk_member_ref: mdMemberRef,
+ ptk: Option<&mut mdToken>,
+ sz_member: Option,
+ cch_member: Option,
+ pch_member: Option<&mut ULONG>,
+ ppv_sig_blob: Option<*mut PCCOR_SIGNATURE>,
+ pcb_sig_blob: Option<&mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_GetMemberRefProps(
+ &self.0 as _,
+ tk_member_ref,
+ ptk.unwrap_or(0 as _),
+ sz_member.unwrap_or(0 as _),
+ cch_member.unwrap_or_default(),
+ pch_member.unwrap_or(0 as _),
+ ppv_sig_blob.unwrap_or(0 as _),
+ pcb_sig_blob.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn get_custom_attribute_props(
+ &self,
+ cv: mdCustomAttribute,
+ ptk_obj: Option<&mut mdToken>,
+ ptk_type: Option<&mut mdToken>,
+ pp_blob: Option<*mut *const BYTE>,
+ pcb_blob: Option<&mut ULONG>,
+ ) -> HRESULT {
+ HRESULT::from_win32(unsafe {
+ core_bindings::IMetaDataImport2_GetCustomAttributeProps(
+ &self.0 as _,
+ cv,
+ ptk_obj.unwrap_or(0 as _),
+ ptk_type.unwrap_or(0 as _),
+ pp_blob.unwrap_or(0 as _),
+ pcb_blob.unwrap_or(0 as _),
+ )
+ } as u32)
+ }
+
+ pub fn enum_custom_attributes(
+ &self,
+ ph_enum: Option<*mut HCORENUM>,
+ tk: Option,
+ tk_type: Option,
+ rg_custom_attributes: Option<&mut [mdCustomAttribute]>,
+ c_max: Option,
+ pc_custom_attributes: Option<*mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_EnumCustomAttributes(
+ &self.0 as _,
+ ph_enum.unwrap_or(0 as _),
+ tk.unwrap_or_default(),
+ tk_type.unwrap_or_default(),
+ rg_custom_attributes.unwrap_or(0 as _),
+ c_max.unwrap_or_default(),
+ pc_custom_attributes.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn find_type_def_by_name(
+ &self,
+ sz_type_def: Option,
+ tk_enclosing_class: Option,
+ ptk_type_def: Option<&mut mdTypeDef>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_FindTypeDefByName(
+ &self.0 as _,
+ sz_type_def.unwrap_or(0 as _),
+ tk_enclosing_class.unwrap_or(0 as _),
+ ptk_type_def.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn enum_method_impls(
+ &self,
+ ph_enum: *mut HCORENUM,
+ tk_type_def: Option,
+ r_method_body: Option<&mut [mdToken]>,
+ r_method_decl: Option<&mut [mdToken]>,
+ c_max: Option,
+ pc_tokens: Option<&mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(core_bindings::IMetaDataImport2_EnumMethodImpls(
+ &self.0 as _,
+ ph_enum,
+ tk_type_def.unwrap_or_default(),
+ r_method_body.unwrap_or_default().as_mut_ptr(),
+ r_method_decl.unwrap_or_default().as_mut_ptr(),
+ c_max.unwrap_or_default(),
+ pc_tokens.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+}
diff --git a/core/src/bindings/mod.rs b/core/src/bindings/mod.rs
new file mode 100644
index 0000000..deaebb1
--- /dev/null
+++ b/core/src/bindings/mod.rs
@@ -0,0 +1,937 @@
+pub mod imeta_data_import2;
+
+use crate::prelude::*;
+use windows::Abi;
+
+pub(crate) fn ro_resolve_namespace(
+ name: &windows::HSTRING,
+ windows_meta_data_dir: Option<&windows::HSTRING>,
+ package_graph_dirs_count: DWORD,
+ package_graph_dirs: Option<&windows::HSTRING>,
+ meta_data_file_paths_count: Option<&mut DWORD>,
+ meta_data_file_paths: Option<&mut windows::HSTRING>,
+ sub_namespaces_count: &mut DWORD,
+ sub_namespaces: Option<&mut windows::HSTRING>,
+) -> HRESULT {
+ unsafe {
+ let name = name.abi() as HSTRING;
+ let windows_meta_data_dir = match windows_meta_data_dir {
+ None => 0 as _,
+ Some(windows_meta_data_dir) => windows_meta_data_dir.abi(),
+ } as HSTRING;
+ let mut package_graph_dirs = match package_graph_dirs {
+ None => 0 as _,
+ Some(package_graph_dirs) => package_graph_dirs.abi(),
+ };
+
+ let package_graph_dirs: *const *mut HSTRING__ = &mut package_graph_dirs as _;
+ let mut meta_data_file_paths = match meta_data_file_paths {
+ None => 0 as _,
+ Some(meta_data_file_paths) => meta_data_file_paths.abi(),
+ };
+
+ let mut meta_data_file_paths = &mut meta_data_file_paths;
+ let meta_data_file_paths: *mut *mut HSTRING = &mut meta_data_file_paths as _;
+
+ let mut sub_namespaces = match sub_namespaces {
+ None => 0 as _,
+ Some(sub_namespaces) => sub_namespaces.abi(),
+ };
+
+ let mut sub_namespaces = &mut sub_namespaces;
+ let sub_namespaces: *mut *mut HSTRING = &mut sub_namespaces as _;
+
+ core_bindings::RoResolveNamespace(
+ name,
+ windows_meta_data_dir,
+ package_graph_dirs_count,
+ package_graph_dirs,
+ meta_data_file_paths_count.unwrap_or(0 as _),
+ meta_data_file_paths,
+ sub_namespaces_count,
+ sub_namespaces,
+ )
+ }
+}
+
+pub mod rometadataresolution {
+ use crate::prelude::*;
+ use windows::{Abi, HRESULT, HSTRING};
+
+ pub(crate) fn ro_get_meta_data_file(
+ name: &mut windows::HSTRING,
+ meta_data_dispenser: Option<*mut c_void>,
+ meta_data_file_path: Option<*mut c_void>,
+ meta_data_import: Option<*mut *mut IMetaDataImport2>,
+ type_def_token: Option<*mut u32>,
+ ) -> HRESULT {
+ unsafe {
+ windows::HRESULT(core_bindings::Rometadataresolution_RoGetMetaDataFile(
+ std::mem::transmute(name),
+ meta_data_dispenser.unwrap_or(0 as _),
+ meta_data_file_path.unwrap_or(0 as _),
+ meta_data_import.unwrap_or(0 as _) as _,
+ type_def_token.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub(crate) fn ro_parse_type_name(
+ type_name: &mut windows::HSTRING,
+ parts_count: &mut DWORD,
+ type_name_parts: &mut windows::HSTRING,
+ ) -> HRESULT {
+ let type_name = type_name.abi() as _;
+ let type_name_parts = type_name_parts.abi() as _;
+ unsafe {
+ HRESULT(core_bindings::Rometadataresolution_RoParseTypeName(
+ type_name,
+ parts_count,
+ type_name_parts,
+ ) as u32)
+ }
+ }
+
+ pub(crate) fn ro_get_parameterized_type_instance_iid(
+ name_element_count: UINT32,
+ name_elements: *mut PCWSTR,
+ fn_: ::core::option::Option<
+ unsafe extern "C" fn(name: PCWSTR, builder: *mut IRoSimpleMetaDataBuilder) -> i32,
+ >,
+ iid: *mut GUID,
+ p_extra: Option<*mut ROPARAMIIDHANDLE>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::Rometadataresolution_RoGetParameterizedTypeInstanceIID(
+ name_element_count,
+ name_elements,
+ fn_,
+ iid,
+ p_extra.unwrap_or(0 as _),
+ ) as u32,
+ )
+ }
+ }
+
+ pub(crate) fn ro_locator(
+ fn_: ::core::option::Option<
+ unsafe extern "C" fn(name: PCWSTR, builder: *mut IRoSimpleMetaDataBuilder) -> i32,
+ >,
+ locator: *mut Locator,
+ ) {
+ unsafe { core_bindings::Rometadataresolution_Ro_Locator(fn_, locator) }
+ }
+}
+
+/*
+
+pub mod imeta_data_import2 {
+ use crate::prelude::*;
+ use core_bindings::*;
+ use windows::HRESULT;
+
+ pub(crate) fn get_type_def_props(metadata: &mut IMetaDataImport2, md_type_def: c_uint, sz_type_def: Option<&mut [u16]>, cch_type_def: Option, pch_type_def: Option<*mut ULONG>, pdw_type_def_flags: Option<*mut ULONG>, md_token: Option<*mut ULONG32>) -> HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_GetTypeDefProps(metadata, md_type_def, sz_type_def.unwrap_or_default().as_mut_ptr(), cch_type_def.unwrap_or(0), pch_type_def.unwrap_or(&mut 0), pdw_type_def_flags.unwrap_or(0 as _), md_token.unwrap_or(&mut 0)) as u32)
+ }
+ }
+
+ fn get_type_def_props_name_size(metadata: *mut IMetaDataImport2, md_type_def: c_uint, pch_type_def: *mut ULONG) -> HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_GetTypeDefPropsNameSize(metadata, md_type_def, pch_type_def) as u32)
+ }
+ }
+
+ pub(crate) fn get_field_props(metadata: *mut IMetaDataImport2,
+ mb: mdFieldDef,
+ p_class: Option<*mut mdTypeDef>,
+ sz_field: Option<*mut u16>,
+ cch_field: Option,
+ pch_field: Option<*mut ULONG>,
+ pdw_attr: Option<*mut DWORD>,
+ ppv_sig_blob: Option<*mut PCCOR_SIGNATURE>,
+ pcb_sig_blob: Option<*mut ULONG>,
+ pdw_cplus_type_flag: Option<*mut DWORD>,
+ pp_value: Option<*mut UVCP_CONSTANT>,
+ pcch_value: Option<*mut ULONG>) -> windows::HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_GetFieldProps(metadata,
+ mb,
+ p_class.unwrap_or(0 as _),
+ sz_field.unwrap_or(0 as _),
+ cch_field.unwrap_or_default(),
+ pch_field.unwrap_or(0 as _),
+ pdw_attr.unwrap_or(0 as _),
+ ppv_sig_blob.unwrap_or(0 as _),
+ pcb_sig_blob.unwrap_or(0 as _),
+ pdw_cplus_type_flag.unwrap_or(0 as _),
+ pp_value.unwrap_or(0 as _),
+ pcch_value.unwrap_or(0 as _)) as u32)
+ }
+ }
+
+ pub(crate) fn get_property_props(metadata: *mut IMetaDataImport2, prop: mdProperty, p_class: Option<*mut mdTypeDef>,
+ sz_property: Option<*mut u16>,
+ cch_property: Option,
+ pch_property: Option<*mut ULONG>,
+ pdw_prop_flags: Option<*mut DWORD>,
+ ppv_sig: Option<*mut PCCOR_SIGNATURE>,
+ pb_sig: Option<*mut ULONG>,
+ pdw_cplus_type_flag: Option<*mut DWORD>,
+ pp_default_value: Option<*mut UVCP_CONSTANT>,
+ pcch_default_value: Option<*mut ULONG>,
+ pmd_setter: Option<*mut mdMethodDef>,
+ pmd_getter: Option<*mut mdMethodDef>,
+ rmd_other_method: Option<*mut mdMethodDef>,
+ c_max: Option,
+ pc_other_method: Option<*mut ULONG>) -> windows::HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_GetPropertyProps(
+ metadata, prop,
+ p_class.unwrap_or(0 as _),
+ sz_property.unwrap_or(0 as _),
+ cch_property.unwrap_or_default(),
+ pch_property.unwrap_or(0 as _),
+ pdw_prop_flags.unwrap_or(0 as _),
+ ppv_sig.unwrap_or(0 as _),
+ pb_sig.unwrap_or(0 as _),
+ pdw_cplus_type_flag.unwrap_or(0 as _),
+ pp_default_value.unwrap_or(0 as _),
+ pcch_default_value.unwrap_or(0 as _),
+ pmd_setter.unwrap_or(0 as _),
+ pmd_getter.unwrap_or(0 as _),
+ rmd_other_method.unwrap_or(0 as _),
+ c_max.unwrap_or_default(),
+ pc_other_method.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub(crate) fn get_method_props(metadata: &mut IMetaDataImport2,
+ tk_method_def: mdMethodDef,
+ ptk_class: Option<&mut mdTypeDef>,
+ sz_method: Option<&mut [u16]>,
+ cch_method: Option,
+ pch_method: Option<&mut ULONG>,
+ pdw_attr: Option<&mut DWORD>,
+ ppv_sig_blob: Option<*mut PCCOR_SIGNATURE>,
+ pcb_sig_blob: Option<&mut ULONG>,
+ pul_code_rva: Option<&mut ULONG>,
+ pdw_impl_flags: Option<&mut DWORD>) -> windows::HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_GetMethodProps(
+ metadata, tk_method_def,
+ ptk_class.unwrap_or(0 as _), sz_method.unwrap_or(0 as _),
+ cch_method.unwrap_or_default(), pch_method.unwrap_or(0 as _),
+ pdw_attr.unwrap_or(0 as _), ppv_sig_blob.unwrap_or(0 as _),
+ pcb_sig_blob.unwrap_or(0 as _), pul_code_rva.unwrap_or(0 as _),
+ pdw_impl_flags.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+
+ pub(crate) fn enum_params(metadata: *mut IMetaDataImport2, ph_enum: *mut HCORENUM, mb: mdMethodDef, r_params: *mut mdParamDef, c_max: ULONG,
+ pc_tokens: *mut ULONG) -> windows::HRESULT {
+ unsafe { HRESULT(core_bindings::IMetaDataImport2_EnumParams(metadata, ph_enum, mb, r_params, c_max, pc_tokens) as u32) }
+ }
+
+ pub(crate) fn close_enum(metadata: &mut IMetaDataImport2, ph_enum: HCORENUM) {
+ unsafe {
+ core_bindings::IMetaDataImport2_CloseEnum(metadata, ph_enum)
+ }
+ }
+
+ pub(crate) fn get_param_props(metadata: *mut IMetaDataImport2, tk: mdParamDef,
+ pmd: Option<*mut mdMethodDef>,
+ pul_sequence: Option<*mut ULONG>,
+ sz_name: Option<*mut u16>,
+ cch_name: Option,
+ pch_name: Option<*mut ULONG>,
+ pdw_attr: Option<*mut DWORD>,
+ pdw_cplus_type_flag: Option<*mut DWORD>,
+ pp_value: Option<*mut UVCP_CONSTANT>,
+ pcch_value: Option<*mut ULONG>) -> windows::HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_GetParamProps(metadata, tk,
+ pmd.unwrap_or(0 as _),
+ pul_sequence.unwrap_or(0 as _),
+ sz_name.unwrap_or(0 as _),
+ cch_name.unwrap_or_default(),
+ pch_name.unwrap_or(0 as _),
+ pdw_attr.unwrap_or(0 as _),
+ pdw_cplus_type_flag.unwrap_or(0 as _),
+ pp_value.unwrap_or(0 as _),
+ pcch_value.unwrap_or(0 as _)) as u32
+ )
+ }
+ }
+
+ pub(crate) fn get_custom_attribute_by_name(metadata: &mut IMetaDataImport2,
+ tk_obj: mdToken,
+ sz_name: Option<&[u16]>,
+ pp_data: Option<*mut *const ::core::ffi::c_void>,
+ pcb_data: Option<&mut ULONG>) -> windows::HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_GetCustomAttributeByName(metadata,
+ tk_obj,
+ sz_name.unwrap_or_default().as_ptr(),
+ pp_data.unwrap_or(0 as _),
+ pcb_data.unwrap_or(0 as _)) as u32)
+ }
+ }
+
+ pub(crate) fn enum_interface_impls(metadata: *mut IMetaDataImport2, ph_enum: *mut HCORENUM,
+ td: Option,
+ r_impls: Option<*mut mdInterfaceImpl>,
+ c_max: Option,
+ pc_impls: Option<*mut ULONG>) -> windows::HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_EnumInterfaceImpls(metadata, ph_enum,
+ td.unwrap_or_default(),
+ r_impls.unwrap_or(0 as _),
+ c_max.unwrap_or(0 as _),
+ pc_impls.unwrap_or(0 as _)) as u32)
+ }
+ }
+
+ pub(crate) fn get_type_ref_props(metadata: &mut IMetaDataImport2,
+ tr: mdTypeRef,
+ ptk_resolution_scope: Option<*mut mdToken>,
+ sz_name: Option<&mut [u16]>,
+ cch_name: Option,
+ pch_name: Option<*mut ULONG>) -> windows::HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_GetTypeRefProps(metadata, tr,
+ ptk_resolution_scope.unwrap_or(0 as _),
+ sz_name.unwrap_or_default().as_mut_ptr(),
+ cch_name.unwrap_or_default(),
+ pch_name.unwrap_or(0 as _)) as u32
+ )
+ }
+ }
+
+ pub(crate) fn find_method(metadata: *mut IMetaDataImport2,
+ td: mdTypeDef,
+ sz_name: LPCWSTR,
+ pv_sig_blob: Option,
+ cb_sig_blob: Option,
+ pmb: Option<*mut mdMethodDef>) -> windows::HRESULT {
+ unsafe {
+ HRESULT(
+ IMetaDataImport2_FindMethod(metadata, td, sz_name, pv_sig_blob.unwrap_or(0 as _), cb_sig_blob.unwrap_or_default(), pmb.unwrap_or(0 as _)) as u32
+ )
+ }
+ }
+
+ pub(crate) fn enum_generic_params(
+ metadata: *mut IMetaDataImport2,
+ ph_enum: *mut HCORENUM,
+ tk: mdToken,
+ r_generic_params: Option<*mut mdGenericParam>,
+ c_max: Option,
+ pc_generic_params: Option<*mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_EnumGenericParams(
+ metadata,
+ ph_enum,
+ tk,
+ r_generic_params.unwrap_or(0 as _),
+ c_max.unwrap_or_default(),
+ pc_generic_params.unwrap_or(0 as _),
+ ) as u32
+ )
+ }
+ }
+
+
+ pub fn count_enum(
+ metadata: *mut IMetaDataImport2,
+ h_enum: HCORENUM,
+ pul_count: *mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_CountEnum(metadata, h_enum, pul_count) as u32
+ )
+ }
+ }
+
+ pub fn get_type_spec_from_token(
+ metadata: *mut IMetaDataImport2,
+ typespec: mdTypeSpec,
+ ppv_sig: *mut PCCOR_SIGNATURE,
+ pcb_sig: *mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ IMetaDataImport2_GetTypeSpecFromToken(
+ metadata,
+ typespec,
+ ppv_sig,
+ pcb_sig,
+ ) as u32
+ )
+ }
+ }
+
+
+ pub(crate) fn enum_fields(
+ metadata: *mut IMetaDataImport2,
+ ph_enum: *mut HCORENUM,
+ tk_type_def: mdTypeDef,
+ rg_fields: *mut mdFieldDef,
+ c_max: ULONG,
+ pc_tokens: *mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_EnumFields(
+ metadata,
+ ph_enum,
+ tk_type_def,
+ rg_fields,
+ c_max,
+ pc_tokens,
+ ) as u32
+ )
+ }
+ }
+
+ pub(crate) fn enum_methods_with_name(
+ metadata: &mut IMetaDataImport2,
+ ph_enum: &mut HCORENUM,
+ tk_type_def: mdTypeDef,
+ sz_name: LPCWSTR,
+ rg_methods: &mut [mdMethodDef],
+ c_max: ULONG,
+ pc_tokens: &mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_EnumMethodsWithName(
+ metadata,
+ ph_enum,
+ tk_type_def,
+ sz_name,
+ rg_methods.as_mut_ptr(),
+ c_max,
+ pc_tokens,
+ ) as u32
+ )
+ }
+ }
+
+ pub(crate) fn get_interface_impl_props(
+ metadata: *mut IMetaDataImport2,
+ tk_interface_impl: mdInterfaceImpl,
+ ptk_class: Option<*mut mdTypeDef>,
+ ptk_iface: Option<*mut mdToken>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_GetInterfaceImplProps(
+ metadata,
+ tk_interface_impl,
+ ptk_class.unwrap_or(0 as _),
+ ptk_iface.unwrap_or(0 as _),
+ ) as u32
+ )
+ }
+ }
+
+ pub(crate) fn enum_methods(
+ metadata: &mut IMetaDataImport2,
+ ph_enum: &mut HCORENUM,
+ tk_type_def: mdTypeDef,
+ rg_methods: &mut [mdMethodDef],
+ c_max: ULONG,
+ pc_tokens: &mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_EnumMethods(
+ metadata,
+ ph_enum,
+ tk_type_def,
+ rg_methods.as_mut_ptr(),
+ c_max,
+ pc_tokens,
+ ) as u32
+ )
+ }
+ }
+
+ pub(crate) fn enum_properties(
+ metadata: *mut IMetaDataImport2,
+ ph_enum: *mut HCORENUM,
+ tk_typ_def: mdTypeDef,
+ rg_properties: *mut mdProperty,
+ c_max: ULONG,
+ pc_properties: *mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_EnumProperties(
+ metadata,
+ ph_enum,
+ tk_typ_def,
+ rg_properties,
+ c_max,
+ pc_properties,
+ ) as u32
+ )
+ }
+ }
+
+ pub fn enum_events(
+ metadata: *mut IMetaDataImport2,
+ ph_enum: *mut HCORENUM,
+ tk_typ_def: mdTypeDef,
+ rg_events: *mut mdEvent,
+ c_max: ULONG,
+ pc_events: *mut ULONG,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_EnumEvents(
+ metadata,
+ ph_enum,
+ tk_typ_def,
+ rg_events,
+ c_max,
+ pc_events,
+ ) as u32
+ )
+ }
+ }
+
+ pub(crate) fn get_event_props(
+ metadata: *mut IMetaDataImport2,
+ ev: mdEvent,
+ p_class: Option<*mut mdTypeDef>,
+ sz_event: Option,
+ cch_event: Option,
+ pch_event: Option<*mut ULONG>,
+ pdw_event_flags: Option<*mut DWORD>,
+ ptk_event_type: Option<*mut mdToken>,
+ pmd_add_on: Option<*mut mdMethodDef>,
+ pmd_remove_on: Option<*mut mdMethodDef>,
+ pmd_fire: Option<*mut mdMethodDef>,
+ rmd_other_method: Option<*mut mdMethodDef>,
+ c_max: Option,
+ pc_other_method: Option<*mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_GetEventProps(
+ metadata,
+ ev,
+ p_class.unwrap_or(0 as _),
+ sz_event.unwrap_or(0 as _),
+ cch_event.unwrap_or_default(),
+ pch_event.unwrap_or(0 as _),
+ pdw_event_flags.unwrap_or(0 as _),
+ ptk_event_type.unwrap_or(0 as _),
+ pmd_add_on.unwrap_or(0 as _),
+ pmd_remove_on.unwrap_or(0 as _),
+ pmd_fire.unwrap_or(0 as _),
+ rmd_other_method.unwrap_or(0 as _),
+ c_max.unwrap_or_default(),
+ pc_other_method.unwrap_or(0 as _),
+ ) as u32
+ )
+ }
+ }
+
+
+ pub(crate) fn find_field(
+ metadata: *mut IMetaDataImport2,
+ td: mdTypeDef,
+ sz_name: Option,
+ pv_sig_blob: Option,
+ cb_sig_blob: Option,
+ pmb: Option<*mut mdFieldDef>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IMetaDataImport2_FindField(
+ metadata,
+ td,
+ sz_name.unwrap_or(0 as _),
+ pv_sig_blob.unwrap_or(0 as _),
+ cb_sig_blob.unwrap_or_default(),
+ pmb.unwrap_or(0 as _),
+ ) as u32
+ )
+ }
+ }
+
+ pub(crate) fn get_member_ref_props(
+ metadata: *mut IMetaDataImport2,
+ tk_member_ref: mdMemberRef,
+ ptk: Option<*mut mdToken>,
+ sz_member: Option,
+ cch_member: Option,
+ pch_member: Option<*mut ULONG>,
+ ppv_sig_blob: Option<*mut PCCOR_SIGNATURE>,
+ pcb_sig_blob: Option<*mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IMetaDataImport2_GetMemberRefProps(
+ metadata,
+ tk_member_ref,
+ ptk.unwrap_or(0 as _),
+ sz_member.unwrap_or(0 as _),
+ cch_member.unwrap_or_default(),
+ pch_member.unwrap_or(0 as _),
+ ppv_sig_blob.unwrap_or(0 as _),
+ pcb_sig_blob.unwrap_or(0 as _),
+ ) as u32)
+ }
+ }
+
+ pub fn get_custom_attribute_props(
+ metadata: *mut IMetaDataImport2,
+ cv: mdCustomAttribute,
+ ptk_obj: Option<*mut mdToken>,
+ ptk_type: Option<*mut mdToken>,
+ pp_blob: Option<*mut *const BYTE>,
+ pcb_blob: Option<*mut ULONG>,
+ ) -> HRESULT {
+ HRESULT::from_win32(
+ unsafe {
+ core_bindings::IMetaDataImport2_GetCustomAttributeProps(
+ metadata,
+ cv,
+ ptk_obj.unwrap_or(0 as _),
+ ptk_type.unwrap_or(0 as _),
+ pp_blob.unwrap_or(0 as _),
+ pcb_blob.unwrap_or(0 as _),
+ )
+ } as u32
+ )
+ }
+
+ pub fn enum_custom_attributes(
+ metadata: *mut IMetaDataImport2,
+ ph_enum: Option<*mut HCORENUM>,
+ tk: Option,
+ tk_type: Option,
+ rg_custom_attributes: Option<*mut mdCustomAttribute>,
+ c_max: Option,
+ pc_custom_attributes: Option<*mut ULONG>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(
+ core_bindings::IMetaDataImport2_EnumCustomAttributes(
+ metadata,
+ ph_enum.unwrap_or(0 as _),
+ tk.unwrap_or_default(),
+ tk_type.unwrap_or_default(),
+ rg_custom_attributes.unwrap_or(0 as _),
+ c_max.unwrap_or_default(),
+ pc_custom_attributes.unwrap_or(0 as _),
+ ) as u32
+ )
+ }
+ }
+
+ pub(crate) fn find_type_def_by_name(
+ metadata: *mut IMetaDataImport2,
+ sz_type_def: Option,
+ tk_enclosing_class: Option,
+ ptk_type_def: Option<*mut mdTypeDef>,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT::from_win32(
+ core_bindings::IMetaDataImport2_FindTypeDefByName(
+ metadata,
+ sz_type_def.unwrap_or(0 as _),
+ tk_enclosing_class.unwrap_or(0 as _),
+ ptk_type_def.unwrap_or(0 as _),
+ ) as u32
+ )
+ }
+ }
+
+ pub fn enum_method_impls(
+ metadata: *mut IMetaDataImport2,
+ ph_enum: *mut HCORENUM,
+ tk_type_def: Option,
+ r_method_body: Option<&mut [mdToken]>,
+ r_method_decl: Option<&mut [mdToken]>,
+ c_max: Option,
+ pc_tokens: Option<&mut ULONG>,
+ ) -> HRESULT {
+ let r_method_body = if let Some(r_method_body) = r_method_body {
+ r_method_body.as_mut_ptr()
+ } else {
+ 0 as _
+ };
+
+ let r_method_decl = if let Some(r_method_decl) = r_method_decl {
+ r_method_decl.as_mut_ptr()
+ } else {
+ 0 as _
+ };
+
+ unsafe {
+ HRESULT::from_win32(
+ core_bindings::IMetaDataImport2_EnumMethodImpls(
+ metadata,
+ ph_enum,
+ tk_type_def.unwrap_or_default(),
+ r_method_body,
+ r_method_decl,
+ c_max.unwrap_or_default(),
+ pc_tokens.unwrap_or(0 as _),
+ ) as u32
+ )
+ }
+ }
+}
+
+*/
+
+pub mod iro_simple_meta_data_builder {
+ use crate::prelude::*;
+ use windows::{HRESULT, HSTRING};
+
+ pub(crate) fn set_runtime_class_simple_default(
+ builder: *mut IRoSimpleMetaDataBuilder,
+ name: PCWSTR,
+ default_interface_name: PCWSTR,
+ default_interface_iid: *const GUID,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IRoSimpleMetaDataBuilder_SetRuntimeClassSimpleDefault(
+ builder,
+ name,
+ default_interface_name,
+ default_interface_iid,
+ ) as u32,
+ )
+ }
+ }
+
+ pub(crate) fn set_win_rt_interface(
+ builder: *mut IRoSimpleMetaDataBuilder,
+ iid: GUID,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IRoSimpleMetaDataBuilder_SetWinRtInterface(builder, iid) as u32)
+ }
+ }
+
+ pub fn set_parameterized_interface(
+ builder: *mut IRoSimpleMetaDataBuilder,
+ piid: GUID,
+ num_args: UINT32,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IRoSimpleMetaDataBuilder_SetParameterizedInterface(
+ builder, piid, num_args,
+ ) as u32,
+ )
+ }
+ }
+
+ pub fn set_enum(
+ builder: *mut IRoSimpleMetaDataBuilder,
+ name: PCWSTR,
+ base_type: PCWSTR,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IRoSimpleMetaDataBuilder_SetEnum(builder, name, base_type) as u32,
+ )
+ }
+ }
+
+ pub fn set_struct(
+ builder: *mut IRoSimpleMetaDataBuilder,
+ name: PCWSTR,
+ num_fields: UINT32,
+ field_type_names: *const PCWSTR,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(core_bindings::IRoSimpleMetaDataBuilder_SetStruct(
+ builder,
+ name,
+ num_fields,
+ field_type_names,
+ ) as u32)
+ }
+ }
+
+ pub fn set_delegate(builder: *mut IRoSimpleMetaDataBuilder, iid: GUID) -> HRESULT {
+ unsafe { HRESULT(core_bindings::IRoSimpleMetaDataBuilder_SetDelegate(builder, iid) as u32) }
+ }
+
+ pub fn set_parameterized_delegate(
+ builder: *mut IRoSimpleMetaDataBuilder,
+ piid: GUID,
+ num_args: UINT32,
+ ) -> HRESULT {
+ unsafe {
+ HRESULT(
+ core_bindings::IRoSimpleMetaDataBuilder_SetParameterizedDelegate(
+ builder, piid, num_args,
+ ) as u32,
+ )
+ }
+ }
+}
+
+pub mod enums {
+ use crate::prelude::*;
+
+ pub(crate) fn type_from_token(token: mdToken) -> ULONG {
+ unsafe { core_bindings::Enums_TypeFromToken(token) }
+ }
+}
+
+pub mod helpers {
+ use crate::prelude::*;
+ use core_bindings::PCCOR_SIGNATURE;
+ use windows::HSTRING;
+
+ pub(crate) fn get_type_name(
+ metadata: &IMetaDataImport2,
+ md_token: mdToken,
+ name: &mut [u16],
+ ) -> ULONG {
+ unsafe {
+ core_bindings::Helpers_Get_Type_Name(
+ metadata.inner() as _,
+ md_token,
+ name.as_mut_ptr(),
+ name.len(),
+ )
+ }
+ }
+
+ pub(crate) fn is_td_public(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsTdPublic(value) == 1 }
+ }
+
+ pub(crate) fn is_td_special_name(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsTdSpecialName(value) == 1 }
+ }
+
+ pub(crate) fn cor_sig_uncompress_calling_conv(p_data: PCCOR_SIGNATURE) -> ULONG {
+ unsafe { core_bindings::Helpers_CorSigUncompressCallingConv(p_data) }
+ }
+
+ pub(crate) fn cor_sig_uncompress_data(p_data: PCCOR_SIGNATURE) -> ULONG {
+ unsafe { core_bindings::Helpers_CorSigUncompressData(p_data) }
+ }
+
+ pub(crate) fn cor_sig_uncompress_element_type(
+ p_data: PCCOR_SIGNATURE,
+ ) -> crate::enums::CorElementType {
+ unsafe { core_bindings::Helpers_CorSigUncompressElementType(p_data).into() }
+ }
+
+ pub(crate) fn cor_sig_uncompress_token(p_data: PCCOR_SIGNATURE) -> mdToken {
+ unsafe { core_bindings::Helpers_CorSigUncompressToken(p_data) }
+ }
+
+ pub(crate) fn to_wstring(index: ULONG, text: &mut [u16]) -> usize {
+ unsafe { core_bindings::Helpers_to_wstring(index, text.as_mut_ptr()) }
+ }
+
+ pub(crate) fn is_md_public(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsMdPublic(value) == 1 }
+ }
+
+ pub(crate) fn is_md_family(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsMdFamily(value) == 1 }
+ }
+
+ pub(crate) fn is_md_fam_orassem(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsMdFamORAssem(value) == 1 }
+ }
+
+ pub(crate) fn is_md_special_name(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsMdSpecialName(value) == 1 }
+ }
+
+ pub(crate) fn is_md_static(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsMdStatic(value) == 1 }
+ }
+
+ pub(crate) fn is_md_final(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsMdFinal(value) == 1 }
+ }
+
+ pub(crate) fn is_md_instance_initializer_w(flags: DWORD, name_data: *const u16) -> bool {
+ unsafe { core_bindings::Helpers_IsMdInstanceInitializerW(flags, name_data) == 1 }
+ }
+
+ pub(crate) fn is_pr_special_name(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsPrSpecialName(value) == 1 }
+ }
+
+ pub(crate) fn bytes_to_guid(data: *mut u8, guid: *mut GUID) {
+ unsafe { core_bindings::Helpers_bytesToGuid(data, guid) }
+ }
+
+ pub(crate) fn windows_get_string_raw_buffer(
+ mut string: HSTRING,
+ length: Option<*mut UINT32>,
+ ) -> PCWSTR {
+ unsafe {
+ core_bindings::Helpers_WindowsGetStringRawBuffer(
+ std::mem::transmute(&mut string),
+ length.unwrap_or(0 as _),
+ )
+ }
+ }
+
+ pub(crate) fn is_td_interface(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsTdInterface(value) == 1 }
+ }
+
+ pub(crate) fn is_td_class(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsTdClass(value) == 1 }
+ }
+
+ pub fn is_ev_special_name(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsEvSpecialName(value) == 1 }
+ }
+
+ pub(crate) fn generate_id_name(declaration_full_name: &str) -> ([u16], usize) {
+ let mut declaration_full_name = windows::HSTRING::from(declaration_full_name);
+ let mut declaration_full_name = declaration_full_name.as_wide();
+ let mut name_parts = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let mut name_parts_count = 0;
+ let mut name_parts_w = &mut name_parts.as_ptr();
+ unsafe {
+ core_bindings::Helpers_generate_id_name(
+ name_parts_w as _,
+ declaration_full_name.as_ptr() as _,
+ &mut name_parts_count,
+ )
+ }
+ (*name_parts, name_parts_count)
+ }
+
+ pub(crate) fn to_string_length(value: PCWSTR, count: *mut usize) {
+ unsafe {
+ core_bindings::Helpers_toString_length(value, count);
+ }
+ }
+
+ pub(crate) fn is_td_sealed(value: DWORD) -> bool {
+ unsafe { core_bindings::Helpers_IsTdSealed(value) == 1 }
+ }
+}
diff --git a/core/src/enums.rs b/core/src/enums.rs
new file mode 100644
index 0000000..51c6182
--- /dev/null
+++ b/core/src/enums.rs
@@ -0,0 +1,292 @@
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+#[repr(C)]
+#[derive(Copy, Clone, Debug)]
+pub enum Initialization {
+ Activation,
+ Composition,
+}
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+#[repr(C)]
+pub enum CorCallingConvention {
+ ImageCeeCsCallconvDefault = 0x0,
+
+ ImageCeeCsCallconvVararg = 0x5,
+ ImageCeeCsCallconvField = 0x6,
+ ImageCeeCsCallconvLocalSig = 0x7,
+ ImageCeeCsCallconvProperty = 0x8,
+ ImageCeeCsCallconvUnmgd = 0x9,
+ ImageCeeCsCallconvGenericinst = 0xa,
+ // generic method instantiation
+ ImageCeeCsCallconvNativevararg = 0xb,
+ // used ONLY for 64bit vararg PInvoke calls
+ ImageCeeCsCallconvMax = 0xc, // first invalid calling convention
+
+ // The high bits of the calling convention convey additional info
+ ImageCeeCsCallconvMask = 0x0f,
+ // Calling convention is bottom 4 bits
+ ImageCeeCsCallconvHasthis = 0x20,
+ // Top bit indicates a 'this' parameter
+ ImageCeeCsCallconvExplicitthis = 0x40,
+ // This parameter is explicitly in the signature
+ ImageCeeCsCallconvGeneric = 0x10, // Generic method sig with explicit number of type arguments (precedes ordinary parameter count)
+ // 0x80 is reserved for internal use
+}
+
+impl From for CorCallingConvention {
+ fn from(value: u32) -> Self {
+ match value {
+ 0x0 => CorCallingConvention::ImageCeeCsCallconvDefault,
+
+ 0x5 => CorCallingConvention::ImageCeeCsCallconvVararg,
+ 0x6 => CorCallingConvention::ImageCeeCsCallconvField,
+ 0x7 => CorCallingConvention::ImageCeeCsCallconvLocalSig,
+ 0x8 => CorCallingConvention::ImageCeeCsCallconvProperty,
+ 0x9 => CorCallingConvention::ImageCeeCsCallconvUnmgd,
+ 0xa => CorCallingConvention::ImageCeeCsCallconvGenericinst,
+ // generic method instantiation
+ 0xb => CorCallingConvention::ImageCeeCsCallconvNativevararg,
+ // used ONLY for 64bit vararg PInvoke calls
+ 0xc => CorCallingConvention::ImageCeeCsCallconvMax, // first invalid calling convention
+
+ // The high bits of the calling convention convey additional info
+ 0x0f => CorCallingConvention::ImageCeeCsCallconvMask,
+ // Calling convention is bottom 4 bits
+ 0x20 => CorCallingConvention::ImageCeeCsCallconvHasthis,
+ // Top bit indicates a 'this' parameter
+ 0x40 => CorCallingConvention::ImageCeeCsCallconvExplicitthis,
+ // This parameter is explicitly in the signature
+ 0x10 => CorCallingConvention::ImageCeeCsCallconvGeneric, // Generic method sig with explicit number of type arguments (precedes ordinary parameter count)
+ // 0x80 is reserved for internal use
+ _ => std::unreachable!()
+ }
+ }
+}
+
+impl From for u32 {
+ fn from(value: CorCallingConvention) -> Self {
+ match value {
+ CorCallingConvention::ImageCeeCsCallconvDefault => 0x0,
+
+ CorCallingConvention::ImageCeeCsCallconvVararg => 0x5,
+ CorCallingConvention::ImageCeeCsCallconvField => 0x6,
+ CorCallingConvention::ImageCeeCsCallconvLocalSig => 0x7,
+ CorCallingConvention::ImageCeeCsCallconvProperty => 0x8 ,
+ CorCallingConvention::ImageCeeCsCallconvUnmgd => 0x9,
+ CorCallingConvention::ImageCeeCsCallconvGenericinst => 0xa,
+ // generic method instantiation
+ CorCallingConvention::ImageCeeCsCallconvNativevararg => 0xb,
+ // used ONLY for 64bit vararg PInvoke calls
+ CorCallingConvention::ImageCeeCsCallconvMax => 0xc, // first invalid calling convention
+
+ // The high bits of the calling convention convey additional info
+ CorCallingConvention::ImageCeeCsCallconvMask => 0x0f,
+ // Calling convention is bottom 4 bits
+ CorCallingConvention::ImageCeeCsCallconvHasthis => 0x20,
+ // Top bit indicates a 'this' parameter
+ CorCallingConvention::ImageCeeCsCallconvExplicitthis => 0x40,
+ // This parameter is explicitly in the signature
+ CorCallingConvention::ImageCeeCsCallconvGeneric => 0x10, // Generic method sig with explicit number of type arguments (precedes ordinary parameter count)
+ // 0x80 is reserved for internal use
+ _ => std::unreachable!()
+ }
+ }
+}
+
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[repr(C)]
+pub enum CorElementType {
+ ElementTypeEnd = 0x00,
+ ElementTypeVoid = 0x01,
+ ElementTypeBoolean = 0x02,
+ ElementTypeChar = 0x03,
+ ElementTypeI1 = 0x04,
+ ElementTypeU1 = 0x05,
+ ElementTypeI2 = 0x06,
+ ElementTypeU2 = 0x07,
+ ElementTypeI4 = 0x08,
+ ElementTypeU4 = 0x09,
+ ElementTypeI8 = 0x0a,
+ ElementTypeU8 = 0x0b,
+ ElementTypeR4 = 0x0c,
+ ElementTypeR8 = 0x0d,
+ ElementTypeString = 0x0e,
+
+ // every type above PTR will be simple type
+ ElementTypePtr = 0x0f,
+ // PTR
+ ElementTypeByref = 0x10, // BYREF
+
+ // Please use ElementTypeValuetype. ELEMENT_TYPE_VALUECLASS is deprecated.
+ ElementTypeValuetype = 0x11,
+ // VALUETYPE
+ ElementTypeClass = 0x12,
+ // CLASS
+ ElementTypeVar = 0x13,
+ // a class type variable VAR
+ ElementTypeArray = 0x14,
+ // MDARRAY ... ...
+ ElementTypeGenericinst = 0x15,
+ // GENERICINST ...
+ ElementTypeTypedbyref = 0x16, // TYPEDREF (it takes no args) a typed referece to some other type
+
+ ElementTypeI = 0x18,
+ // native integer size
+ ElementTypeU = 0x19,
+ // native unsigned integer size
+ ElementTypeFnptr = 0x1b,
+ // FNPTR
+ ElementTypeObject = 0x1c,
+ // Shortcut for System.Object
+ ElementTypeSzarray = 0x1d,
+ // Shortcut for single dimension zero lower bound array
+ // SZARRAY
+ ElementTypeMvar = 0x1e, // a method type variable MVAR
+
+ // This is only for binding
+ ElementTypeCmodReqd = 0x1f,
+ // required C modifier : E_T_CMOD_REQD
+ ElementTypeCmodOpt = 0x20, // optional C modifier : E_T_CMOD_OPT
+
+ // This is for signatures generated internally (which will not be persisted in any way).
+ ElementTypeInternal = 0x21, // INTERNAL
+
+ // Note that this is the max of base type excluding modifiers
+ ElementTypeMax = 0x22, // first invalid element type
+
+ ElementTypeModifier = 0x40,
+ ElementTypeSentinel = 0x01 | 0x40,
+ // sentinel for varargs
+ ElementTypePinned = 0x05 | 0x40,
+}
+
+impl From for CorElementType {
+ fn from(cet: core_bindings::CorElementType) -> Self {
+ match cet {
+ core_bindings::CorElementType::ELEMENT_TYPE_END => CorElementType::ElementTypeEnd,
+ core_bindings::CorElementType::ELEMENT_TYPE_VOID => CorElementType::ElementTypeVoid,
+ core_bindings::CorElementType::ELEMENT_TYPE_BOOLEAN => {
+ CorElementType::ElementTypeBoolean
+ }
+ core_bindings::CorElementType::ELEMENT_TYPE_CHAR => CorElementType::ElementTypeChar,
+ core_bindings::CorElementType::ELEMENT_TYPE_I1 => CorElementType::ElementTypeI1,
+ core_bindings::CorElementType::ELEMENT_TYPE_U1 => CorElementType::ElementTypeU1,
+ core_bindings::CorElementType::ELEMENT_TYPE_I2 => CorElementType::ElementTypeI2,
+ core_bindings::CorElementType::ELEMENT_TYPE_U2 => CorElementType::ElementTypeU2,
+ core_bindings::CorElementType::ELEMENT_TYPE_I4 => CorElementType::ElementTypeI4,
+ core_bindings::CorElementType::ELEMENT_TYPE_U4 => CorElementType::ElementTypeU4,
+ core_bindings::CorElementType::ELEMENT_TYPE_I8 => CorElementType::ElementTypeI8,
+ core_bindings::CorElementType::ELEMENT_TYPE_U8 => CorElementType::ElementTypeU8,
+ core_bindings::CorElementType::ELEMENT_TYPE_R4 => CorElementType::ElementTypeR4,
+ core_bindings::CorElementType::ELEMENT_TYPE_R8 => CorElementType::ElementTypeR8,
+ core_bindings::CorElementType::ELEMENT_TYPE_STRING => CorElementType::ElementTypeString,
+ core_bindings::CorElementType::ELEMENT_TYPE_PTR => CorElementType::ElementTypePtr,
+ core_bindings::CorElementType::ELEMENT_TYPE_BYREF => CorElementType::ElementTypeByref,
+ core_bindings::CorElementType::ELEMENT_TYPE_VALUETYPE => {
+ CorElementType::ElementTypeValuetype
+ }
+ core_bindings::CorElementType::ELEMENT_TYPE_CLASS => CorElementType::ElementTypeClass,
+ core_bindings::CorElementType::ELEMENT_TYPE_VAR => CorElementType::ElementTypeVar,
+ core_bindings::CorElementType::ELEMENT_TYPE_ARRAY => CorElementType::ElementTypeArray,
+ core_bindings::CorElementType::ELEMENT_TYPE_GENERICINST => {
+ CorElementType::ElementTypeGenericinst
+ }
+ core_bindings::CorElementType::ELEMENT_TYPE_TYPEDBYREF => {
+ CorElementType::ElementTypeTypedbyref
+ }
+ core_bindings::CorElementType::ELEMENT_TYPE_I => CorElementType::ElementTypeI,
+ core_bindings::CorElementType::ELEMENT_TYPE_U => CorElementType::ElementTypeU,
+ core_bindings::CorElementType::ELEMENT_TYPE_FNPTR => CorElementType::ElementTypeFnptr,
+ core_bindings::CorElementType::ELEMENT_TYPE_OBJECT => CorElementType::ElementTypeObject,
+ core_bindings::CorElementType::ELEMENT_TYPE_SZARRAY => {
+ CorElementType::ElementTypeSzarray
+ }
+ core_bindings::CorElementType::ELEMENT_TYPE_MVAR => CorElementType::ElementTypeMvar,
+ core_bindings::CorElementType::ELEMENT_TYPE_CMOD_REQD => {
+ CorElementType::ElementTypeCmodReqd
+ }
+ core_bindings::CorElementType::ELEMENT_TYPE_CMOD_OPT => {
+ CorElementType::ElementTypeCmodOpt
+ }
+ core_bindings::CorElementType::ELEMENT_TYPE_INTERNAL => {
+ CorElementType::ElementTypeInternal
+ }
+ core_bindings::CorElementType::ELEMENT_TYPE_MAX => CorElementType::ElementTypeMax,
+ core_bindings::CorElementType::ELEMENT_TYPE_MODIFIER => {
+ CorElementType::ElementTypeModifier
+ }
+ core_bindings::CorElementType::ELEMENT_TYPE_SENTINEL => {
+ CorElementType::ElementTypeSentinel
+ }
+ core_bindings::CorElementType::ELEMENT_TYPE_PINNED => CorElementType::ElementTypePinned,
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq)]
+#[repr(C)]
+pub enum CorTokenType {
+ mdtModule = 0x00000000,
+ mdtTypeRef = 0x01000000,
+ mdtTypeDef = 0x02000000,
+ mdtFieldDef = 0x04000000,
+ mdtMethodDef = 0x06000000,
+ mdtParamDef = 0x08000000,
+ mdtInterfaceImpl = 0x09000000,
+ mdtMemberRef = 0x0a000000,
+ mdtCustomAttribute = 0x0c000000,
+ mdtPermission = 0x0e000000,
+ mdtSignature = 0x11000000,
+ mdtEvent = 0x14000000,
+ mdtProperty = 0x17000000,
+ mdtModuleRef = 0x1a000000,
+ mdtTypeSpec = 0x1b000000,
+ mdtAssembly = 0x20000000,
+ mdtAssemblyRef = 0x23000000,
+ mdtFile = 0x26000000,
+ mdtExportedType = 0x27000000,
+ mdtManifestResource = 0x28000000,
+ mdtGenericParam = 0x2a000000,
+ mdtMethodSpec = 0x2b000000,
+ mdtGenericParamConstraint = 0x2c000000,
+ mdtString = 0x70000000,
+ mdtName = 0x71000000,
+ mdtBaseType = 0x72000000
+}
+
+impl From for CorTokenType {
+ fn from(value: u32) -> Self {
+ match value {
+ 0x00000000 => Self::mdtModule,
+ 0x01000000 => Self::mdtTypeRef,
+ 0x02000000 => Self::mdtTypeDef,
+ 0x04000000 => Self::mdtFieldDef,
+ 0x06000000 => Self::mdtMethodDef,
+ 0x08000000 => Self::mdtParamDef,
+ 0x09000000 => Self::mdtInterfaceImpl,
+ 0x0a000000 => Self::mdtMemberRef,
+ 0x0c000000 => Self::mdtCustomAttribute,
+ 0x0e000000 => Self::mdtPermission,
+ 0x11000000 => Self::mdtSignature,
+ 0x14000000 => Self::mdtEvent,
+ 0x17000000 => Self::mdtProperty,
+ 0x1a000000 => Self::mdtModuleRef,
+ 0x1b000000 => Self::mdtTypeSpec,
+ 0x20000000 => Self::mdtAssembly,
+ 0x23000000 => Self::mdtAssemblyRef,
+ 0x26000000 => Self::mdtFile,
+ 0x27000000 => Self::mdtExportedType,
+ 0x28000000 => Self::mdtManifestResource,
+ 0x2a000000 => Self::mdtGenericParam,
+ 0x2b000000 => Self::mdtMethodSpec,
+ 0x2c000000 => Self::mdtGenericParamConstraint,
+ 0x70000000 => Self::mdtString,
+ 0x71000000 => Self::mdtName,
+ 0x72000000 => Self::mdtBaseType,
+ _ => std::unreachable!()
+ }
+ }
+}
diff --git a/core/src/lib.rs b/core/src/lib.rs
new file mode 100755
index 0000000..6c90aae
--- /dev/null
+++ b/core/src/lib.rs
@@ -0,0 +1,5 @@
+pub mod runtime;
+pub mod metadata;
+pub mod bindings;
+pub mod prelude;
+pub mod enums;
diff --git a/core/src/metadata/com_helpers.rs b/core/src/metadata/com_helpers.rs
new file mode 100755
index 0000000..29d33b5
--- /dev/null
+++ b/core/src/metadata/com_helpers.rs
@@ -0,0 +1,166 @@
+use crate::bindings::{enums, helpers, rometadataresolution};
+use crate::prelude::*;
+use core_bindings::GUID;
+use std::borrow::Cow;
+
+const GUID_ATTRIBUTE: &str = "Windows.Foundation.Metadata.GuidAttribute";
+
+pub const SYSTEM_TYPE: &str = "System.Type";
+pub const STATIC_ATTRIBUTE: &str = "Windows.Foundation.Metadata.StaticAttribute";
+pub const ACTIVATABLE_ATTRIBUTE: &str = "Windows.Foundation.Metadata.ActivatableAttribute";
+pub const COMPOSABLE_ATTRIBUTE: &str = "Windows.Foundation.Metadata.ComposableAttribute";
+
+pub fn get_string_value_from_blob<'a>(
+ metadata: &IMetaDataImport2,
+ signature: PCCOR_SIGNATURE,
+) -> Cow<'a, str> {
+ debug_assert!(metadata.is_none());
+ debug_assert!(signature.is_null());
+
+ if signature as u8 == u8::MAX {
+ return "".into();
+ }
+
+ let size = helpers::cor_sig_uncompress_data(signature);
+
+ let slice = unsafe { std::slice::from_raw_parts(signature as *mut u16, size as usize) };
+
+ windows::HSTRING::from_wide(slice).to_string_lossy().into()
+}
+
+pub fn get_unary_custom_attribute_string_value<'a>(
+ metadata: Option<&IMetaDataImport2>,
+ token: mdToken,
+ attribute_name: &str,
+) -> Cow<'a, str> {
+ debug_assert!(metadata.is_none());
+ debug_assert!(token != mdTokenNil);
+ debug_assert!(!attribute_name.is_null());
+
+ match metadata {
+ None => Cow::default(),
+ Some(metadata) => {
+ let mut data = std::mem::MaybeUninit::uninit();
+ let name = OsString::from(attribute_name).to_wide();
+ let data_ptr = &mut data.as_mut_ptr() as *mut *const c_void;
+
+ let result =
+ metadata.get_custom_attribute_by_name(token, Some(&name), Some(data_ptr), None);
+ debug_assert!(result.is_ok());
+ if result.is_err() {
+ return "".into();
+ }
+
+ let mut data = unsafe { data.assume_init() };
+
+ get_string_value_from_blob(metadata, data + 2)
+ }
+ }
+}
+
+pub fn resolve_type_ref(
+ metadata: Option<&IMetaDataImport2>,
+ token: mdTypeRef,
+ external_metadata: &mut IMetaDataImport2,
+ external_token: &mut mdTypeDef,
+) -> bool {
+ debug_assert!(metadata.is_none());
+ debug_assert!(CorTokenType::from(enums::type_from_token(token)) == CorTokenType::mdtTypeRef);
+ //debug_assert!(!external_metadata.is_null());
+ //debug_assert!(!external_token.is_null());
+
+ match metadata {
+ None => false,
+ Some(metadata) => {
+ let mut data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let result = metadata.get_type_ref_props(
+ token,
+ None,
+ Some(&data),
+ Some(data.len() as u32),
+ None,
+ );
+ debug_assert!(result.is_ok());
+ let mut string = windows::HSTRING::from_wide(&data);
+ let mut external_metadata = external_metadata as *mut _;
+ rometadataresolution::ro_get_meta_data_file(
+ &mut string,
+ None,
+ None,
+ Some(&mut external_metadata),
+ Some(external_token),
+ )
+ .is_ok()
+ }
+ }
+}
+
+pub fn get_guid_attribute_value(metadata: Option<&IMetaDataImport2>, token: mdToken) -> GUID {
+ debug_assert!(metadata.is_none());
+ debug_assert!(token != mdTokenNil);
+
+ let mut guid = GUID::default();
+
+ match metadata {
+ None => {}
+ Some(_) => {
+ let mut size = 0;
+ let mut data = std::mem::MaybeUninit::uninit();
+ let name = OsString::from(GUID_ATTRIBUTE).to_wide();
+ let data_ptr = &mut data.as_mut_ptr() as *mut *const c_void;
+
+ metadata.get_custom_attribute_by_name(
+ token,
+ Some(name.as_slice()),
+ Some(data_ptr),
+ Some(&mut size),
+ );
+
+ let mut data = unsafe { data.assume_init() };
+ // Skip prolog
+ let os_data = unsafe { data.as_mut_ptr().offset(2) };
+
+ helpers::bytes_to_guid(os_data, &mut guid);
+ }
+ }
+ guid
+}
+
+pub fn get_type_name<'a>(metadata: Option<&IMetaDataImport2>, token: mdToken) -> Cow<'a, str> {
+ debug_assert!(metadata.is_none());
+ debug_assert!(token != mdTokenNil);
+
+ let mut name_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let mut name_length = 0;
+ match CorTokenType::from(enums::type_from_token(token)) {
+ CorTokenType::mdtTypeDef => {
+ if let Some(metadata) = metadata {
+ let result = metadata.get_type_def_props(
+ token,
+ Some(&mut name_data),
+ Some(name_data.len() as u32),
+ Some(&mut name_length),
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok())
+ }
+ }
+ CorTokenType::mdtTypeRef => {
+ let result = metadata.get_type_ref_props(
+ metadata,
+ token,
+ None,
+ Some(name_data.as_mut_ptr()),
+ Some(name_data.len() as u32),
+ Some(&mut name_length),
+ );
+ debug_assert!(result.is_ok());
+ }
+ _ => {
+ core_unreachable();
+ }
+ }
+
+ OsString::from_wide(name_data[..name_length]).into()
+}
diff --git a/core/src/metadata/declaration_factory.rs b/core/src/metadata/declaration_factory.rs
new file mode 100644
index 0000000..d0da535
--- /dev/null
+++ b/core/src/metadata/declaration_factory.rs
@@ -0,0 +1,178 @@
+use std::sync::{Arc, Mutex, RwLock};
+
+use crate::bindings::{enums, helpers};
+use crate::metadata::com_helpers::resolve_type_ref;
+use crate::metadata::declarations::base_class_declaration::BaseClassDeclarationImpl;
+
+use crate::metadata::declarations::delegate_declaration::{DelegateDeclaration, DelegateDeclarationImpl};
+use crate::metadata::declarations::delegate_declaration::generic_delegate_instance_declaration::GenericDelegateInstanceDeclaration;
+use crate::metadata::declarations::interface_declaration::generic_interface_instance_declaration::GenericInterfaceInstanceDeclaration;
+use crate::prelude::*;
+use crate::metadata::declarations::interface_declaration::InterfaceDeclaration;
+
+#[derive(Clone, Debug)]
+pub struct DeclarationFactory {}
+
+impl DeclarationFactory {
+ pub fn make_delegate_declaration(metadata: Option>>, token: mdToken) -> Option>> {
+ match CorTokenType::from(enums::type_from_token(token))
+ {
+ CorTokenType::mdtTypeDef => Box::new(DelegateDeclaration::new(metadata, token)),
+ CorTokenType::mdtTypeRef => {
+ match get_lock_value(&metadata) {
+ None => {}
+ Some(metadata) => {
+ let mut external_metadata = std::mem::MaybeUninit::uninit();
+ let external_metadata_ptr = &mut external_metadata.as_mut_ptr();
+ let mut external_delegate_token = mdTokenNil;
+ let is_resolved = resolve_type_ref(Some(metadata), token, external_metadata_ptr, &mut external_delegate_token);
+ debug_assert!(is_resolved);
+ let external_metadata = unsafe { external_metadata.assume_init() };
+ Some(
+ Arc::new(
+ RwLock::new(
+ external_metadata
+ )
+ )
+ )
+ }
+ }
+ }
+ CorTokenType::mdtTypeSpec => {
+ let mut signature = [0_u8; MAX_IDENTIFIER_LENGTH];
+ let mut signature_ptr = signature.as_ptr();
+ let mut signature_size = 0;
+ debug_assert!(
+ imeta_data_import2::get_type_spec_from_token(
+ metadata, token, &mut signature_ptr, &mut signature_size,
+ ).is_ok()
+ );
+
+ let type1 = helpers::cor_sig_uncompress_element_type(signature.as_ptr());
+ debug_assert!(
+ type1 == crate::enums::CorElementType::ElementTypeGenericinst
+ );
+
+ let type2 = helpers::cor_sig_uncompress_element_type(signature.as_ptr());
+ debug_assert!(
+ type2 == crate::enums::CorElementType::ElementTypeClass
+ );
+
+ let open_generic_delegate_token = helpers::cor_sig_uncompress_token(signature.as_ptr());
+ match CorTokenType::from(enums::type_from_token(open_generic_delegate_token)) {
+ CorTokenType::mdtTypeDef => {
+ Box::new(GenericDelegateInstanceDeclaration::new(metadata, open_generic_delegate_token, metadata, token))
+ }
+ CorTokenType::mdtTypeRef => {
+ let mut external_metadata: std::mem::MaybeUninit = std::mem::MaybeUninit::uninit();
+ let external_metadata_ptr = &mut external_metadata.as_mut_ptr();
+ let mut external_delegate_token = mdTokenNil;
+
+ let is_resolved = resolve_type_ref(
+ metadata, open_generic_delegate_token, external_metadata_ptr, &mut external_delegate_token,
+ );
+
+ debug_assert!(is_resolved);
+ Box::new(GenericDelegateInstanceDeclaration::new(external_metadata, external_delegate_token, metadata, token))
+ }
+ _ => {
+ std::unreachable!()
+ }
+ }
+ }
+ _ => {
+ std::unreachable!()
+ }
+ }
+ }
+ pub fn make_interface_declaration(metadata: Option>>, token: mdToken) -> Option>> {
+ match CorTokenType::from(enums::type_from_token(token)) {
+ CorTokenType::mdtTypeDef => {
+ Some(
+ Arc::new(
+ RwLock::new(InterfaceDeclaration::new(metadata, token))
+ )
+ )
+ }
+ CorTokenType::mdtTypeRef => {
+ let mut external_metadata = std::mem::MaybeUninit::uninit();
+ let external_metadata_ptr = &mut external_metadata;
+ let mut external_interface_token = mdTokenNil;
+
+ let is_resolved = resolve_type_ref(metadata, token, external_metadata_ptr, &mut external_interface_token);
+
+ debug_assert!(is_resolved);
+
+ Arc::new(
+ Mutex::new(InterfaceDeclaration::new(
+ external_metadata, external_interface_token,
+ ))
+ )
+ }
+ CorTokenType::mdtTypeSpec => {
+ let mut signature = [0_u8; MAX_IDENTIFIER_LENGTH];
+ let mut signature_ptr = &mut signature.as_mut_ptr();
+ let mut signature_size = 0;
+ debug_assert!(
+ imeta_data_import2::get_type_spec_from_token(
+ metadata, token, signature_ptr as *mut _ as *mut *const u8, &mut signature_size,
+ ).is_ok()
+ );
+
+ let type1 = helpers::cor_sig_uncompress_element_type(signature.as_ptr());
+ debug_assert!(
+ type1 == crate::enums::CorElementType::ElementTypeGenericinst
+ );
+
+ let type2 = helpers::cor_sig_uncompress_element_type(signature.as_ptr());
+
+ debug_assert!(
+ type2 == crate::enums::CorElementType::ElementTypeClass
+ );
+ let open_generic_delegate_token = helpers::cor_sig_uncompress_token(signature.as_ptr());
+
+ match CorTokenType::from(enums::type_from_token(token)) {
+ CorTokenType::mdtTypeSpec => match CorTokenType::from(enums::type_from_token(open_generic_delegate_token)) {
+ CorTokenType::mdtTypeDef => {
+ Arc::new(
+ Mutex::new(GenericInterfaceInstanceDeclaration::new(
+ metadata, open_generic_delegate_token, metadata, token,
+ ))
+ )
+ }
+ CorTokenType::mdtTypeRef => {
+ let mut external_metadata = std::mem::MaybeUninit::uninit();
+ let external_metadata_ptr = &mut external_metadata;
+ let mut external_delegate_token = mdTokenNil;
+
+ let is_resolved = resolve_type_ref(
+ metadata, open_generic_delegate_token, external_metadata_ptr, &mut external_delegate_token,
+ );
+
+ debug_assert!(
+ is_resolved
+ );
+
+ Arc::new(
+ Mutex::new(
+ GenericInterfaceInstanceDeclaration::new(
+ external_metadata, external_delegate_token, metadata, token,
+ )
+ )
+ )
+ }
+ _ => {
+ std::unreachable!()
+ }
+ }
+ _ => {
+ std::unreachable!()
+ }
+ }
+ }
+ _ => {
+ std::unreachable!()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/src/metadata/declarations/base_class_declaration.rs b/core/src/metadata/declarations/base_class_declaration.rs
new file mode 100644
index 0000000..9cd40f8
--- /dev/null
+++ b/core/src/metadata/declarations/base_class_declaration.rs
@@ -0,0 +1,352 @@
+use std::borrow::Cow;
+
+use std::sync::{Arc, RwLock};
+
+use crate::metadata::declarations::interface_declaration::InterfaceDeclaration;
+use crate::{
+ metadata::declaration_factory::DeclarationFactory,
+ metadata::declarations::declaration::{Declaration, DeclarationKind},
+ metadata::declarations::event_declaration::EventDeclaration,
+ metadata::declarations::method_declaration::MethodDeclaration,
+ metadata::declarations::property_declaration::PropertyDeclaration,
+ metadata::declarations::type_declaration::TypeDeclaration,
+ prelude::*,
+};
+
+#[derive(Clone)]
+pub struct BaseClassDeclaration {
+ base: TypeDeclaration,
+ implemented_interfaces: Vec>>,
+ methods: Vec,
+ properties: Vec,
+ events: Vec,
+}
+
+impl BaseClassDeclaration {
+ pub fn metadata(&self) -> Option<&IMetaDataImport2> {
+ self.base.metadata()
+ }
+
+ pub fn make_implemented_interfaces_declarations(
+ metadata: Option>>,
+ token: mdTypeDef,
+ ) -> Vec {
+ let mut result = Vec::new();
+ match Option::as_ref(&metadata) {
+ None => {}
+ Some(metadata) => {
+ let meta = Arc::clone(metadata);
+ match metadata.try_read() {
+ Ok(metadata) => {
+ let mut enumerator = std::ptr::null_mut();
+ let enumerator_ptr = &mut enumerator;
+ let mut count = 0;
+ let mut tokens = [0; 1024];
+
+ let result_inner = metadata.enum_interface_impls(
+ enumerator_ptr,
+ Some(token),
+ Some(&mut tokens),
+ Some(tokens.len() as u32),
+ Some(&mut count),
+ );
+ debug_assert!(result_inner.is_ok());
+
+ debug_assert!(count < (tokens.len() - 1) as u32);
+ metadata.close_enum(enumerator);
+
+ for token in tokens.into_iter() {
+ let mut interface_token = mdTokenNil;
+ let result_inner = metadata.get_interface_impl_props(
+ *token,
+ None,
+ Some(&mut interface_token),
+ );
+ debug_assert!(result_inner.is_ok());
+ result.push(DeclarationFactory::make_interface_declaration(
+ Some(Arc::clone(&meta)),
+ interface_token,
+ ));
+ }
+ }
+ Err(_) => {}
+ }
+ }
+ }
+ result
+ }
+
+ pub fn make_method_declarations(
+ metadata: Option>>,
+ token: mdTypeDef,
+ ) -> Vec {
+ let mut result = Vec::new();
+ match Option::as_ref(&metadata) {
+ None => {}
+ Some(metadata) => {
+ let meta = Arc::clone(&metadata);
+ match metadata.try_read() {
+ Ok(metadata) => {
+ let mut enumerator = std::ptr::null_mut();
+ let enumerator_ptr = &mut enumerator;
+ let mut count = 0;
+ let mut tokens = [0; 1024];
+ let result_inner = metadata.enum_methods(
+ enumerator_ptr,
+ token,
+ &mut tokens,
+ tokens.len() as u32,
+ &mut count,
+ );
+ debug_assert!(result_inner.is_ok());
+
+ debug_assert!(count < (tokens.len() - 1) as u32);
+ metadata.close_enum(enumerator);
+
+ for token in tokens.iter() {
+ let method = MethodDeclaration::new(Some(Arc::clone(&meta)), *token);
+ if !method.is_exported() {
+ continue;
+ }
+ result.push(method);
+ }
+ }
+ Err(_) => {}
+ }
+ }
+ }
+
+ return result;
+ }
+
+ pub fn make_property_declarations<'b>(
+ metadata: Option>>,
+ token: mdTypeDef,
+ ) -> Vec {
+ let mut result = Vec::new();
+ match Option::as_ref(&metadata) {
+ None => {}
+ Some(metadata) => {
+ let meta = Arc::clone(&metadata);
+ match metadata.try_read() {
+ Ok(metadata) => {
+ let mut enumerator = std::ptr::null_mut();
+ let enumerator_ptr = &mut enumerator;
+ let mut count = 0;
+ let mut tokens = [0; 1024];
+ let result_inner = metadata.enum_properties(
+ enumerator_ptr,
+ token,
+ &mut tokens,
+ tokens.len() as u32,
+ &mut count,
+ );
+ debug_assert!(result_inner.is_ok());
+ debug_assert!(count < (tokens.len() - 1) as u32);
+ metadata.close_enum(enumerator);
+
+ for token in tokens.iter() {
+ let property =
+ PropertyDeclaration::new(Some(Arc::clone(&meta)), *token);
+ if !property.is_exported() {
+ continue;
+ }
+ result.push(property);
+ }
+ }
+ Err(_) => {}
+ }
+ }
+ }
+ result
+ }
+
+ pub fn make_event_declarations(
+ metadata: Option>>,
+ token: mdTypeDef,
+ ) -> Vec {
+ let mut result = Vec::new();
+ if let Some(metadata) = Option::as_ref(&metadata) {
+ let meta = Arc::clone(metadata);
+ match metadata.try_read() {
+ Ok(metadata) => {
+ let mut enumerator = std::ptr::null_mut();
+ let enumerator_ptr = &mut enumerator;
+ let mut count = 0;
+ let mut tokens = [0; 1024];
+
+ let result_inner = metadata.enum_events(
+ enumerator_ptr,
+ token,
+ &mut tokens,
+ tokens.len() as u32,
+ &mut count,
+ );
+ debug_assert!(result_inner.is_ok());
+ debug_assert!(count < (tokens.len() - 1) as u32);
+ metadata.close_enum(enumerator);
+
+ for token in tokens.iter() {
+ let event = EventDeclaration::new(Some(Arc::clone(&meta)), *token);
+ if !event.is_exported() {
+ continue;
+ }
+ result.push(event);
+ }
+ }
+ Err(_) => {}
+ }
+ }
+
+ result
+ }
+
+ pub fn new(
+ kind: DeclarationKind,
+ metadata: Option>>,
+ token: mdTypeDef,
+ ) -> Self {
+ Self {
+ base: TypeDeclaration::new(
+ kind,
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ implemented_interfaces: BaseClassDeclaration::make_implemented_interfaces_declarations(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ methods: BaseClassDeclaration::make_method_declarations(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ properties: BaseClassDeclaration::make_property_declarations(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ events: BaseClassDeclaration::make_event_declarations(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ }
+ }
+}
+
+pub trait BaseClassDeclarationImpl {
+ fn base(&self) -> &TypeDeclaration;
+
+ fn implemented_interfaces<'a>(&self) -> &[InterfaceDeclaration];
+
+ fn methods<'a>(&self) -> &[MethodDeclaration];
+
+ fn properties<'a>(&self) -> &[PropertyDeclaration];
+
+ fn events<'a>(&self) -> &[EventDeclaration];
+
+ fn find_members_with_name(&self, name: &str) -> Vec {
+ debug_assert!(!name.is_empty());
+
+ let mut result: Vec> = Vec::new();
+
+ // let mut methods = self.find_methods_with_name(name).into_iter().map(|item| Box::new(item)).collect();
+ // result.append(&mut methods);
+
+ let mut methods = self.find_methods_with_name(name);
+ for method in methods.into_iter() {
+ result.push(Box::new(method));
+ }
+
+ // let mut properties = self.properties().into_iter().filter(|prop| prop.full_name() == name).collect();
+ // result.append(&mut properties);
+
+ let mut properties = self.properties().clone();
+
+ for property in properties.into_iter() {
+ if property.full_name() == name {
+ result.push(Box::new(property));
+ }
+ }
+
+ // let mut events = self.events().into_iter().filter(|event| event.full_name() == name).collect();
+ // result.append(&mut events);
+
+ let mut events = self.events().clone();
+
+ for event in events {
+ if event.full_name() == name {
+ result.push(Box::new(event))
+ }
+ }
+
+ return result;
+ }
+
+ fn find_methods_with_name(&self, name: &str) -> Vec {
+ debug_assert!(!name.is_empty());
+ let mut method_tokens = [0; 1024];
+ let mut meta = None;
+ if let Some(metadata) = self.base().metadata_shared() {
+ meta = Some(Arc::clone(&metadata));
+ let mut enumerator = std::ptr::null_mut();
+ let enumerator_ptr = &mut enumerator;
+
+ let mut methods_count = 0;
+ let name = windows::HSTRING::from(name);
+ let name = name.as_wide();
+ let base = self.base();
+ let result = metadata.enum_methods_with_name(
+ enumerator_ptr,
+ base.token(),
+ name.as_ptr(),
+ &mut method_tokens,
+ method_tokens.len() as u32,
+ &mut methods_count,
+ );
+ debug_assert!(result.is_ok());
+ metadata.close_enum(enumerator);
+ }
+
+ method_tokens
+ .iter()
+ .map(|method_token| {
+ MethodDeclaration::new(Option::as_ref(&meta).map(|v| Arc::clone(v)), *method_token)
+ })
+ .collect()
+ }
+}
+
+impl BaseClassDeclarationImpl for BaseClassDeclaration {
+ fn base(&self) -> &TypeDeclaration {
+ &self.base
+ }
+
+ fn implemented_interfaces(&self) -> &[Arc>] {
+ &self.implemented_interfaces
+ }
+
+ fn methods(&self) -> &[MethodDeclaration] {
+ &self.methods
+ }
+
+ fn properties(&self) -> &[PropertyDeclaration] {
+ &self.properties
+ }
+
+ fn events(&self) -> &[EventDeclaration] {
+ &self.events
+ }
+}
+
+impl Declaration for BaseClassDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.full_name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ self.base().full_name()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base().kind()
+ }
+}
diff --git a/core/src/metadata/declarations/class_declaration.rs b/core/src/metadata/declarations/class_declaration.rs
new file mode 100644
index 0000000..ac3d161
--- /dev/null
+++ b/core/src/metadata/declarations/class_declaration.rs
@@ -0,0 +1,228 @@
+use std::borrow::Cow;
+use std::sync::{Arc, RwLock, TryLockError};
+
+use crate::bindings::helpers;
+use crate::metadata::declaration_factory::DeclarationFactory;
+use crate::metadata::declarations::base_class_declaration::{
+ BaseClassDeclaration, BaseClassDeclarationImpl,
+};
+use crate::metadata::declarations::declaration::{Declaration, DeclarationKind};
+use crate::metadata::declarations::interface_declaration::InterfaceDeclaration;
+use crate::metadata::declarations::method_declaration::MethodDeclaration;
+use crate::prelude::*;
+
+const DEFAULT_ATTRIBUTE: &str = "Windows.Foundation.Metadata.DefaultAttribute";
+
+#[derive(Clone)]
+pub struct ClassDeclaration {
+ initializers: Vec,
+ default_interface: Option>,
+ base: BaseClassDeclaration,
+}
+
+impl ClassDeclaration {
+ pub fn make_initializer_declarations(
+ metadata: Option>>,
+ token: mdTypeDef,
+ ) -> Vec {
+ let mut result = Vec::new();
+
+ if let Some(metadata) = Option::as_ref(&metadata) {
+ let meta = Arc::clone(metadata);
+ match metadata.try_read() {
+ Ok(metadata) => {
+ let mut enumerator = std::ptr::null_mut();
+ let enumerator_ptr = &mut enumerator;
+ let mut count = 0;
+ let mut tokens = [0; 1024];
+
+ let name = windows::HSTRING::from(COR_CTOR_METHOD_NAME);
+ let name = name.as_wide();
+
+ let result = metadata.enum_methods_with_name(
+ enumerator_ptr,
+ token,
+ name.as_ptr(),
+ &mut tokens,
+ tokens.len() as u32,
+ &mut count,
+ );
+ debug_assert!(result.is_ok());
+
+ debug_assert!(count < (tokens.len() - 1) as u32);
+
+ metadata.close_enum(enumerator);
+
+ for i in 0..count as usize {
+ let method_token = tokens[i];
+
+ // TODO: Make a InstanceInitializerDeclaration and check this in it's isExported method
+ let mut flags = 0;
+ let result_inner = metadata.get_method_props(
+ method_token,
+ None,
+ None,
+ None,
+ None,
+ Some(&mut flags),
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result_inner.is_ok());
+
+ if helpers::is_md_public(flags) {
+ continue;
+ }
+
+ result.push(MethodDeclaration::new(
+ Some(Arc::clone(&meta)),
+ method_token,
+ ));
+ }
+ }
+ Err(_) => {}
+ }
+ }
+
+ result
+ }
+
+ pub fn make_default_interface(
+ metadata: Option>>,
+ token: mdTypeDef,
+ ) -> Option>> {
+ match Option::as_ref(&metadata) {
+ None => {}
+ Some(metadata) => {
+ let meta = Arc::clone(metadata);
+
+ match metadata.try_read() {
+ Ok(metadata) => {
+ let mut interface_impl_tokens = [0; 1024];
+ let mut interface_impl_count = 0;
+ let mut interface_enumerator = std::ptr::null_mut();
+ let interface_enumerator_ptr = &mut interface_enumerator;
+ let result = metadata.enum_interface_impls(
+ interface_enumerator_ptr,
+ Some(token),
+ Some(&mut interface_impl_tokens),
+ Some(interface_impl_tokens.len() as u32),
+ Some(&mut interface_impl_count),
+ );
+ debug_assert!(result.is_ok());
+
+ debug_assert!(interface_impl_count < interface_impl_tokens.len() as u32);
+ metadata.close_enum(interface_enumerator);
+ let attr = windows::HSTRING::from(DEFAULT_ATTRIBUTE);
+ let attr = attr.as_wide();
+ for i in 0..interface_impl_count as usize {
+ let interface_impl_token = interface_impl_tokens[i];
+ let get_custom_attribute_result = metadata
+ .get_custom_attribute_by_name(
+ interface_impl_token,
+ Some(attr),
+ None,
+ None,
+ );
+ debug_assert!(get_custom_attribute_result.is_ok());
+ if get_custom_attribute_result.is_ok() {
+ let mut interface_token = mdTokenNil;
+ let result = metadata.get_interface_impl_props(
+ interface_impl_token,
+ None,
+ Some(&mut interface_token),
+ );
+ debug_assert!(result.is_ok());
+ return DeclarationFactory::make_interface_declaration(
+ Some(Arc::clone(&meta)),
+ interface_token,
+ );
+ }
+ }
+ }
+ Err(_) => {}
+ }
+ }
+ }
+
+ core_unreachable();
+ None
+ }
+
+ pub fn new(metadata: Option>>, token: mdTypeDef) -> Self {
+ Self {
+ initializers: ClassDeclaration::make_initializer_declarations(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ default_interface: ClassDeclaration::make_default_interface(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ base: BaseClassDeclaration::new(DeclarationKind::Class, metadata, token),
+ }
+ }
+
+ pub fn base_full_name<'b>(&self) -> Cow<'b, str> {
+ let mut name = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let mut count = 0;
+ let mut parent_token = mdTokenNil;
+ if let Some(metadata) = self.base.metadata() {
+ let result = metadata.get_type_def_props(
+ self.base.base().token(),
+ None,
+ None,
+ None,
+ None,
+ Some(&mut parent_token),
+ );
+ debug_assert!(result.is_ok());
+ count = helpers::get_type_name(metadata, parent_token, &mut name);
+ }
+ OsString::from_wide(&name[..count as usize]).to_string_lossy()
+ }
+
+ pub fn default_interface(&self) -> &InterfaceDeclaration {
+ &self.default_interface
+ }
+
+ pub fn is_instantiable(&self) -> bool {
+ !self.initializers.is_empty()
+ }
+
+ pub fn is_sealed(&self) -> bool {
+ let mut flags = 0;
+ if let Some(metadata) = self.base.base().metadata() {
+ let result = metadata.get_type_def_props(
+ self.base.base().token(),
+ None,
+ None,
+ None,
+ Some(&mut flags),
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ helpers::is_td_sealed(flags)
+ }
+
+ pub fn initializers(&self) -> &[MethodDeclaration] {
+ self.initializers.as_slice()
+ }
+}
+
+impl Declaration for ClassDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ self.base.full_name()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
diff --git a/core/src/metadata/declarations/declaration.rs b/core/src/metadata/declarations/declaration.rs
new file mode 100644
index 0000000..f37ed69
--- /dev/null
+++ b/core/src/metadata/declarations/declaration.rs
@@ -0,0 +1,41 @@
+use std::any::Any;
+use std::borrow::Cow;
+
+#[derive(Copy, Clone, Debug, PartialEq)]
+pub enum DeclarationKind {
+ Namespace,
+ Class,
+ Interface,
+ GenericInterface,
+ GenericInterfaceInstance,
+ Enum,
+ EnumMember,
+ Struct,
+ StructField,
+ Delegate,
+ GenericDelegate,
+ GenericDelegateInstance,
+ Event,
+ Property,
+ Method,
+ Parameter,
+}
+
+pub trait Declaration {
+ fn is_exported(&self) -> bool {
+ return true;
+ }
+
+ /// Specifies the simple name (e.g., "String" rather than "System.String") of a given type.
+ fn name<'a>(&self) -> Cow<'a, str>;
+
+ /// Specifies the fully-qualified name of a given type.
+ /// For generic types, this includes the spelling of generic parameter names.
+ fn full_name<'a>(&self) -> Cow<'a, str>;
+
+ fn kind(&self) -> DeclarationKind;
+
+ fn as_any(&self) -> &dyn Any {
+ self as &dyn Any
+ }
+}
diff --git a/core/src/metadata/declarations/delegate_declaration/generic_delegate_declaration.rs b/core/src/metadata/declarations/delegate_declaration/generic_delegate_declaration.rs
new file mode 100644
index 0000000..98afeee
--- /dev/null
+++ b/core/src/metadata/declarations/delegate_declaration/generic_delegate_declaration.rs
@@ -0,0 +1,74 @@
+use std::borrow::Cow;
+
+use crate::metadata::declarations::declaration::{Declaration, DeclarationKind};
+use crate::metadata::declarations::delegate_declaration::{
+ DelegateDeclaration, DelegateDeclarationImpl,
+};
+use crate::metadata::declarations::method_declaration::MethodDeclaration;
+use crate::metadata::declarations::type_declaration::TypeDeclaration;
+use crate::prelude::*;
+use core_bindings::mdToken;
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct GenericDelegateDeclaration {
+ base: DelegateDeclaration,
+}
+
+impl GenericDelegateDeclaration {
+ pub fn new(metadata: Option>>, token: mdToken) -> Self {
+ Self {
+ base: DelegateDeclaration::new_overload(
+ DeclarationKind::GenericDelegate,
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ }
+ }
+
+ pub fn number_of_generic_parameters(&self) -> usize {
+ let mut count = 0;
+
+ if let Some(metadata) = self.base.base.metadata() {
+ let mut enumerator = std::ptr::null_mut();
+ let enumerator_ptr = &mut enumerator;
+ let result = metadata.enum_generic_params(
+ enumerator_ptr,
+ self.base.base.token(),
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+
+ let result = metadata.count_enum(enumerator, &mut count);
+ debug_assert!(result.is_ok());
+ metadata.close_enum(enumerator);
+ }
+ return count as usize;
+ }
+}
+
+impl Declaration for GenericDelegateDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ self.base.full_name()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
+
+impl DelegateDeclarationImpl for GenericDelegateDeclaration {
+ fn base<'b>(&self) -> &'b TypeDeclaration {
+ &self.base.base
+ }
+
+ fn invoke_method<'b>(&self) -> &'b MethodDeclaration {
+ &self.base.invoke_method
+ }
+}
diff --git a/core/src/metadata/declarations/delegate_declaration/generic_delegate_instance_declaration.rs b/core/src/metadata/declarations/delegate_declaration/generic_delegate_instance_declaration.rs
new file mode 100644
index 0000000..5374806
--- /dev/null
+++ b/core/src/metadata/declarations/delegate_declaration/generic_delegate_instance_declaration.rs
@@ -0,0 +1,93 @@
+use std::borrow::Cow;
+
+use core_bindings::{mdTypeDef, mdTypeSpec};
+
+use crate::bindings::enums;
+use crate::enums::CorTokenType;
+use crate::metadata::declarations::declaration::{Declaration, DeclarationKind};
+use crate::metadata::declarations::delegate_declaration::{
+ DelegateDeclaration, DelegateDeclarationImpl,
+};
+use crate::metadata::declarations::method_declaration::MethodDeclaration;
+use crate::metadata::declarations::type_declaration::TypeDeclaration;
+use crate::metadata::generic_instance_id_builder::GenericInstanceIdBuilder;
+use crate::metadata::signature::Signature;
+use crate::prelude::*;
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct GenericDelegateInstanceDeclaration {
+ base: DelegateDeclaration,
+ closed_token: mdTypeSpec,
+ closed_metadata: Option>>,
+}
+
+impl GenericDelegateInstanceDeclaration {
+ pub fn new(
+ open_metadata: Option>>,
+ open_token: mdTypeDef,
+ closed_metadata: Option>>,
+ closed_token: mdTypeSpec,
+ ) -> Self {
+ debug_assert!(closed_metadata.is_some());
+ debug_assert!(
+ CorTokenType::from(enums::type_from_token(closed_token)) == CorTokenType::mdtTypeSpec
+ );
+ debug_assert!(closed_token != mdTypeSpecNil);
+
+ Self {
+ base: DelegateDeclaration::new_overload(
+ DeclarationKind::GenericDelegateInstance,
+ open_metadata,
+ open_token,
+ ),
+ closed_token,
+ closed_metadata,
+ }
+ }
+}
+
+impl Declaration for GenericDelegateInstanceDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ match Option::as_ref(&self.closed_metadata) {
+ None => Cow::default(),
+ Some(metadata) => {
+ if let Ok(metadata) = metadata.try_read() {
+ let mut signature = [0_u8; MAX_IDENTIFIER_LENGTH];
+ let mut sig = signature.as_ptr();
+ let mut signature_size = 0;
+ let result = metadata.get_type_spec_from_token(
+ self.closed_token,
+ &mut sig,
+ &mut signature_size,
+ );
+ debug_assert!(result.is_ok());
+ signature.resize(signature_size as usize, 0);
+ Signature::to_string(&*metadata, sig).into()
+ }
+ }
+ }
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
+
+impl DelegateDeclarationImpl for GenericDelegateInstanceDeclaration {
+ fn base<'b>(&self) -> &'b TypeDeclaration {
+ &self.base.base
+ }
+
+ fn id(&self) -> CLSID {
+ GenericInstanceIdBuilder::generate_id(self)
+ }
+
+ fn invoke_method<'b>(&self) -> &MethodDeclaration {
+ &self.base.invoke_method
+ }
+}
diff --git a/core/src/metadata/declarations/delegate_declaration/mod.rs b/core/src/metadata/declarations/delegate_declaration/mod.rs
new file mode 100644
index 0000000..52cacca
--- /dev/null
+++ b/core/src/metadata/declarations/delegate_declaration/mod.rs
@@ -0,0 +1,99 @@
+use std::borrow::Cow;
+
+use crate::{
+ metadata::com_helpers::get_guid_attribute_value,
+ metadata::declarations::declaration::{Declaration, DeclarationKind},
+ metadata::declarations::method_declaration::MethodDeclaration,
+ metadata::declarations::type_declaration::TypeDeclaration,
+ prelude::*,
+};
+use core_bindings::GUID;
+use std::sync::{Arc, RwLock};
+
+pub mod generic_delegate_declaration;
+pub mod generic_delegate_instance_declaration;
+
+const INVOKE_METHOD_NAME: &str = "Invoke";
+
+pub fn get_invoke_method_token(
+ metadata: Option>>,
+ token: mdTypeDef,
+) -> mdMethodDef {
+ let mut invoke_method_token = mdTokenNil;
+ let string = windows::HSTRING::from(INVOKE_METHOD_NAME);
+ if let Some(metadata) = Option::as_ref(&metadata) {
+ if let Ok(metadata) = metadata.try_read() {
+ let result = metadata.find_method(
+ token,
+ string.as_wide().as_ptr(),
+ None,
+ None,
+ Some(&mut invoke_method_token),
+ );
+ debug_assert!(result.is_ok());
+ }
+ }
+ return invoke_method_token;
+}
+
+pub trait DelegateDeclarationImpl {
+ fn base(&self) -> &TypeDeclaration;
+ fn id(&self) -> GUID {
+ get_guid_attribute_value(self.base().metadata_mut(), self.base().token())
+ }
+ fn invoke_method(&self) -> &MethodDeclaration;
+}
+
+#[derive(Clone, Debug)]
+pub struct DelegateDeclaration {
+ base: TypeDeclaration,
+ invoke_method: MethodDeclaration,
+}
+
+impl<'a> DelegateDeclaration {
+ pub fn new(metadata: Option>>, token: mdTypeDef) -> Self {
+ Self::new_overload(DeclarationKind::Delegate, metadata, token)
+ }
+
+ pub fn new_overload(
+ kind: DeclarationKind,
+ metadata: Option>>,
+ token: mdTypeDef,
+ ) -> Self {
+ Self {
+ base: TypeDeclaration::new(
+ kind,
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ invoke_method: MethodDeclaration::new(
+ metadata,
+ get_invoke_method_token(Option::as_ref(&metadata).map(|v| Arc::clone(v)), token),
+ ),
+ }
+ }
+}
+
+impl Declaration for DelegateDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ self.base.full_name()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
+
+impl DelegateDeclarationImpl for DelegateDeclaration {
+ fn base<'b>(&self) -> &'b TypeDeclaration {
+ &self.base
+ }
+
+ fn invoke_method<'b>(&self) -> &'b MethodDeclaration {
+ &self.invoke_method
+ }
+}
diff --git a/core/src/metadata/declarations/enum_declaration.rs b/core/src/metadata/declarations/enum_declaration.rs
new file mode 100644
index 0000000..d9cf059
--- /dev/null
+++ b/core/src/metadata/declarations/enum_declaration.rs
@@ -0,0 +1,80 @@
+use crate::prelude::*;
+use crate::bindings::{
+ helpers,
+};
+use super::{
+ declaration::{
+ Declaration,
+ DeclarationKind,
+ },
+ type_declaration::TypeDeclaration,
+};
+use std::borrow::Cow;
+use std::sync::{Arc, RwLock};
+
+#[derive(Debug)]
+pub struct EnumDeclaration {
+ base: TypeDeclaration,
+}
+
+impl Declaration for EnumDeclaration {
+ fn is_exported(&self) -> bool {
+ self.base.is_exported()
+ }
+
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ self.base.full_name()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
+
+impl EnumDeclaration {
+ pub fn new(metadata: Option>>, token: mdTypeDef) -> Self {
+ Self {
+ base: TypeDeclaration::new(DeclarationKind::Enum, metadata, token)
+ }
+ }
+
+ pub fn type_<'b>(&self) -> Cow<'b, &[u8]> {
+ let mut type_field = mdTokenNil;
+ let name_w = OsString::from(COR_ENUM_FIELD_NAME).to_wide();
+ match self.base.metadata() {
+ None => Cow::default(),
+ Some(metadata) => {
+ let result = metadata.find_field(
+ self.base.token(),
+ Some(name_w.as_ptr()), None, None, Some(&mut type_field),
+ );
+ debug_assert!(result.is_ok());
+ let mut signature = [0_u8; MAX_IDENTIFIER_LENGTH];
+ let mut signature_size = 0;
+ metadata.get_field_props(
+ type_field,
+ None, None, None, None, None,
+ Some(&mut signature.as_mut_ptr() as _ as *mut *const u8),
+ Some(&mut signature_size),
+ None, None, None,
+ );
+ debug_assert!(
+ result.is_ok()
+ );
+
+ let header = helpers::cor_sig_uncompress_data(signature.as_ptr());
+ debug_assert!(
+ header == CorCallingConvention::ImageCeeCsCallconvField as u32
+ );
+
+ let result: &[u8] = &signature[0..signature_size];
+
+ result.into()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/src/metadata/declarations/event_declaration.rs b/core/src/metadata/declarations/event_declaration.rs
new file mode 100644
index 0000000..a849082
--- /dev/null
+++ b/core/src/metadata/declarations/event_declaration.rs
@@ -0,0 +1,231 @@
+use crate::bindings::{helpers};
+use crate::metadata::declaration_factory::DeclarationFactory;
+use crate::metadata::declarations::declaration::{Declaration, DeclarationKind};
+use crate::metadata::declarations::delegate_declaration::{
+ DelegateDeclaration, DelegateDeclarationImpl,
+};
+use crate::metadata::declarations::method_declaration::MethodDeclaration;
+use crate::metadata::declarations::type_declaration::TypeDeclaration;
+use crate::prelude::*;
+use std::borrow::Cow;
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct EventDeclaration {
+ base: TypeDeclaration,
+ // Arc ??
+ type_: Option>>,
+ add_method: MethodDeclaration,
+ remove_method: MethodDeclaration,
+}
+
+impl EventDeclaration {
+ pub fn make_add_method(
+ metadata: Option>>,
+ token: mdEvent,
+ ) -> MethodDeclaration {
+ let mut add_method_token = mdTokenNil;
+ if let Some(metadata) = Option::as_ref(&metadata) {
+ match metadata.try_read() {
+ Ok(metadata) => {
+ let result = metadata.get_event_props(
+ token,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ Some(&mut add_method_token),
+ None,
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ Err(_) => {}
+ }
+ }
+ MethodDeclaration::new(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ add_method_token,
+ )
+ }
+
+ pub fn make_remove_method(
+ metadata: Option>>,
+ token: mdEvent,
+ ) -> MethodDeclaration {
+ let mut remove_method_token = mdTokenNil;
+ match Option::as_ref(&metadata) {
+ None => {}
+ Some(metadata) => match metadata.try_read() {
+ Ok(metadata) => {
+ let result = metadata.get_event_props(
+ token,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ Some(&mut remove_method_token),
+ None,
+ None,
+ None,
+ None,
+ );
+
+ debug_assert!(result.is_ok());
+ }
+ Err(_) => {}
+ },
+ }
+ MethodDeclaration::new(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ remove_method_token,
+ )
+ }
+
+ pub fn make_type(
+ metadata: Option>>,
+ token: mdEvent,
+ ) -> Option>> {
+ let mut delegate_token = mdTokenNil;
+ match Option::as_ref(&metadata) {
+ None => {}
+ Some(metadata) => match metadata.try_read() {
+ Ok(metadata) => {
+ let result = metadata.get_event_props(
+ token,
+ None,
+ None,
+ None,
+ None,
+ None,
+ Some(&mut delegate_token),
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ Err(_) => {}
+ },
+ }
+ return DeclarationFactory::make_delegate_declaration(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ delegate_token,
+ );
+ }
+
+ pub fn new(metadata: Option>>, token: mdEvent) -> Self {
+ Self {
+ base: TypeDeclaration::new(
+ DeclarationKind::Event,
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ type_: EventDeclaration::make_type(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ add_method: EventDeclaration::make_add_method(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ remove_method: EventDeclaration::make_remove_method(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ }
+ }
+
+ pub fn is_static(&self) -> bool {
+ self.add_method.is_static()
+ }
+
+ pub fn is_sealed(&self) -> bool {
+ self.add_method.is_sealed()
+ }
+
+ pub fn type_(&self) -> &DelegateDeclaration {
+ &self.type_
+ }
+
+ pub fn add_method(&self) -> &MethodDeclaration {
+ &self.add_method
+ }
+
+ pub fn remove_method(&self) -> &MethodDeclaration {
+ &self.remove_method
+ }
+}
+
+impl Declaration for EventDeclaration {
+ fn is_exported(&self) -> bool {
+ let mut flags = 0;
+ if let Some(metadata) = self.base.metadata() {
+ let result = metadata.get_event_props(
+ self.base.token(),
+ None,
+ None,
+ None,
+ None,
+ Some(&mut flags),
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ if helpers::is_ev_special_name(flags) {
+ return false;
+ }
+
+ return true;
+ }
+
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.full_name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ let mut name_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let mut name_data_length = 0;
+
+ if let Some(metadata) = self.base.metadata() {
+ let result = metadata.get_event_props(
+ self.base.token(),
+ None,
+ Some(name_data.as_mut_ptr()),
+ Some(name_data.len() as u32),
+ Some(&mut name_data_length),
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ OsString::from_wide(&name_data[..name_data_length]).into()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
diff --git a/core/src/metadata/declarations/field_declaration.rs b/core/src/metadata/declarations/field_declaration.rs
new file mode 100644
index 0000000..252fab1
--- /dev/null
+++ b/core/src/metadata/declarations/field_declaration.rs
@@ -0,0 +1,90 @@
+use super::declaration::{Declaration, DeclarationKind};
+use crate::prelude::*;
+
+use crate::bindings::enums;
+use std::sync::{Arc, RwLock};
+use std::{borrow::Cow, ffi::OsString};
+
+#[derive(Clone, Debug)]
+pub struct FieldDeclaration {
+ kind: DeclarationKind,
+ metadata: Option>>,
+ token: mdFieldDef,
+}
+
+impl Declaration for FieldDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ return self.full_name();
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ match self.metadata() {
+ None => Cow::default(),
+ Some(metadata) => {
+ let mut full_name_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let mut length = 0;
+ let result = metadata.get_field_props(
+ self.token,
+ None,
+ Some(&mut full_name_data),
+ Some(full_name_data.len() as u32),
+ Some(&mut length),
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ );
+
+ debug_assert!(result.is_ok());
+
+ OsString::from_wide(full_name_data[..length]).into()
+ }
+ }
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.kind
+ }
+}
+
+impl FieldDeclaration {
+ pub fn metadata_mut<'a>(&mut self) -> Option<&'a mut IMetaDataImport2> {
+ Option::as_mut(&mut self.metadata).map(|v| match v.try_read() {
+ Ok(val) => &mut *val,
+ Err(_) => None,
+ })
+ }
+
+ pub fn metadata<'a>(&self) -> Option<&'a IMetaDataImport2> {
+ Option::as_ref(&self.metadata).map(|v| match v.try_read() {
+ Ok(val) => &mut *val,
+ Err(_) => None,
+ })
+ }
+
+ pub fn kind(&self) -> DeclarationKind {
+ self.kind
+ }
+
+ pub fn token(&self) -> mdFieldDef {
+ self.token
+ }
+ pub fn new(
+ kind: DeclarationKind,
+ metadata: Option>>,
+ token: mdFieldDef,
+ ) -> Self {
+ {
+ debug_assert!(metadata.is_none());
+ debug_assert!(enums::type_from_token(token) == CorTokenType::mdtFieldDef as u32);
+ debug_assert!(token != mdFieldDefNil);
+ }
+ Self {
+ kind,
+ metadata,
+ token,
+ }
+ }
+}
diff --git a/core/src/metadata/declarations/interface_declaration/generic_interface_declaration.rs b/core/src/metadata/declarations/interface_declaration/generic_interface_declaration.rs
new file mode 100644
index 0000000..016e0c6
--- /dev/null
+++ b/core/src/metadata/declarations/interface_declaration/generic_interface_declaration.rs
@@ -0,0 +1,92 @@
+use std::borrow::Cow;
+
+use crate::metadata::declarations::base_class_declaration::BaseClassDeclarationImpl;
+use crate::metadata::declarations::declaration::{Declaration, DeclarationKind};
+use crate::metadata::declarations::event_declaration::EventDeclaration;
+use crate::metadata::declarations::interface_declaration::InterfaceDeclaration;
+use crate::metadata::declarations::method_declaration::MethodDeclaration;
+use crate::metadata::declarations::property_declaration::PropertyDeclaration;
+use crate::metadata::declarations::type_declaration::TypeDeclaration;
+use crate::prelude::*;
+use core_bindings::{mdToken, GUID};
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct GenericInterfaceDeclaration {
+ base: InterfaceDeclaration,
+}
+
+impl GenericInterfaceDeclaration {
+ pub fn new(metadata: Option>>, token: mdToken) -> Self {
+ Self {
+ base: InterfaceDeclaration::new_with_kind(
+ DeclarationKind::GenericInterface,
+ metadata,
+ token,
+ ),
+ }
+ }
+
+ pub fn number_of_generic_parameters(&self) -> usize {
+ let mut count = 0;
+ let mut enumerator = std::ptr::null_mut();
+ let enumerator_ptr = &mut enumerator;
+ let base = self.base();
+ match self.base().metadata() {
+ None => {}
+ Some(metadata) => {
+ let result_1 =
+ metadata.enum_generic_params(enumerator_ptr, base.token(), None, None, None);
+ debug_assert!(result_1.is_ok());
+ let result_2 = metadata.count_enum(enumerator, &mut count);
+ debug_assert!(result_2.is_ok());
+ let result_1 =
+ metadata.enum_generic_params(enumerator_ptr, base.token(), None, None, None);
+ debug_assert!(result_1.is_ok());
+ let result_2 = metadata.count_enum(enumerator, &mut count);
+ debug_assert!(result_2.is_ok());
+ }
+ }
+ return count as usize;
+ }
+
+ pub fn id(&self) -> GUID {
+ self.base.id()
+ }
+}
+
+impl BaseClassDeclarationImpl for GenericInterfaceDeclaration {
+ fn base(&self) -> &TypeDeclaration {
+ self.base.base()
+ }
+
+ fn implemented_interfaces(&self) -> &Vec {
+ self.base.implemented_interfaces()
+ }
+
+ fn methods(&self) -> &[MethodDeclaration] {
+ self.base.methods()
+ }
+
+ fn properties(&self) -> &[PropertyDeclaration] {
+ self.base.properties()
+ }
+
+ fn events(&self) -> &[EventDeclaration] {
+ self.base.events()
+ }
+}
+
+impl Declaration for GenericInterfaceDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ self.base.full_name()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
diff --git a/core/src/metadata/declarations/interface_declaration/generic_interface_instance_declaration.rs b/core/src/metadata/declarations/interface_declaration/generic_interface_instance_declaration.rs
new file mode 100644
index 0000000..844a77b
--- /dev/null
+++ b/core/src/metadata/declarations/interface_declaration/generic_interface_instance_declaration.rs
@@ -0,0 +1,108 @@
+use std::borrow::Cow;
+
+use core_bindings::{mdTypeDef, mdTypeSpec, GUID};
+
+use crate::{
+ bindings::enums,
+ enums::CorTokenType,
+ metadata::declarations::base_class_declaration::BaseClassDeclarationImpl,
+ metadata::declarations::declaration::{Declaration, DeclarationKind},
+ metadata::declarations::event_declaration::EventDeclaration,
+ metadata::declarations::interface_declaration::InterfaceDeclaration,
+ metadata::declarations::method_declaration::MethodDeclaration,
+ metadata::declarations::property_declaration::PropertyDeclaration,
+ metadata::declarations::type_declaration::TypeDeclaration,
+ metadata::generic_instance_id_builder::GenericInstanceIdBuilder,
+ metadata::signature::Signature,
+ prelude::*,
+};
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct GenericInterfaceInstanceDeclaration {
+ base: InterfaceDeclaration,
+ closed_metadata: Option>>,
+ closed_token: mdTypeSpec,
+}
+
+impl GenericInterfaceInstanceDeclaration {
+ pub fn new(
+ open_metadata: Option>>,
+ open_token: mdTypeDef,
+ closed_metadata: Option>>,
+ closed_token: mdTypeSpec,
+ ) -> Self {
+ debug_assert!(closed_metadata.is_none());
+ debug_assert!(
+ CorTokenType::from(enums::type_from_token(closed_token)) == CorTokenType::mdtTypeSpec
+ );
+ debug_assert!(closed_token != mdTypeSpecNil);
+
+ Self {
+ base: InterfaceDeclaration::new_with_kind(
+ DeclarationKind::GenericInterfaceInstance,
+ open_metadata,
+ open_token,
+ ),
+ closed_metadata,
+ closed_token,
+ }
+ }
+ pub fn id(&self) -> GUID {
+ return GenericInstanceIdBuilder::generate_id(self);
+ }
+}
+
+impl BaseClassDeclarationImpl for GenericInterfaceInstanceDeclaration {
+ fn base(&self) -> &TypeDeclaration {
+ self.base.base()
+ }
+
+ fn implemented_interfaces(&self) -> &[InterfaceDeclaration] {
+ self.base.implemented_interfaces()
+ }
+
+ fn methods(&self) -> &[MethodDeclaration] {
+ self.base.methods()
+ }
+
+ fn properties(&self) -> &[PropertyDeclaration] {
+ self.base.properties()
+ }
+
+ fn events(&self) -> &[EventDeclaration] {
+ self.base.events()
+ }
+}
+
+impl Declaration for GenericInterfaceInstanceDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ let mut signature = std::mem::MaybeUninit::uninit();
+ //let mut signature = [0_u8; MAX_IDENTIFIER_LENGTH];
+ let signature_ptr = &mut signature.as_mut_ptr();
+ let mut signature_size = 0;
+ match Option::as_ref(&self.closed_metadata) {
+ None => Cow::default(),
+ Some(metadata) => match metadata.try_read() {
+ Ok(metadata) => {
+ let result = metadata.get_type_spec_from_token(
+ self.closed_token,
+ signature_ptr as _,
+ &mut signature_size,
+ );
+ debug_assert!(result.is_ok());
+ Signature::to_string(&metadata, signature.as_ptr()).into()
+ }
+ Err(_) => Cow::default(),
+ },
+ }
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
diff --git a/core/src/metadata/declarations/interface_declaration/mod.rs b/core/src/metadata/declarations/interface_declaration/mod.rs
new file mode 100644
index 0000000..36a678d
--- /dev/null
+++ b/core/src/metadata/declarations/interface_declaration/mod.rs
@@ -0,0 +1,80 @@
+use std::borrow::Cow;
+
+use crate::metadata::com_helpers::get_guid_attribute_value;
+use crate::metadata::declarations::base_class_declaration::{
+ BaseClassDeclaration, BaseClassDeclarationImpl,
+};
+use crate::metadata::declarations::declaration::{Declaration, DeclarationKind};
+use crate::metadata::declarations::event_declaration::EventDeclaration;
+use crate::metadata::declarations::method_declaration::MethodDeclaration;
+use crate::metadata::declarations::property_declaration::PropertyDeclaration;
+use crate::metadata::declarations::type_declaration::TypeDeclaration;
+use crate::prelude::*;
+
+pub mod generic_interface_declaration;
+pub mod generic_interface_instance_declaration;
+
+use core_bindings::{mdToken, GUID};
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct InterfaceDeclaration {
+ base: BaseClassDeclaration,
+}
+
+impl InterfaceDeclaration {
+ pub fn new(metadata: Option>>, token: mdToken) -> Self {
+ Self::new_with_kind(DeclarationKind::Interface, metadata, token)
+ }
+
+ pub fn new_with_kind(
+ kind: DeclarationKind,
+ metadata: Option>>,
+ token: mdToken,
+ ) -> Self {
+ Self {
+ base: BaseClassDeclaration::new(kind, metadata, token),
+ }
+ }
+
+ pub fn id(&self) -> GUID {
+ let base = self.base.base();
+ get_guid_attribute_value(base.metadata(), base.token())
+ }
+}
+
+impl Declaration for InterfaceDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ self.base.full_name()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
+
+impl BaseClassDeclarationImpl for InterfaceDeclaration {
+ fn base(&self) -> &TypeDeclaration {
+ self.base.base()
+ }
+
+ fn implemented_interfaces(&self) -> &Vec {
+ self.base.implemented_interfaces()
+ }
+
+ fn methods(&self) -> &[MethodDeclaration] {
+ self.base.methods()
+ }
+
+ fn properties(&self) -> &[PropertyDeclaration] {
+ self.base.properties()
+ }
+
+ fn events(&self) -> &[EventDeclaration] {
+ self.base.events()
+ }
+}
diff --git a/core/src/metadata/declarations/method_declaration.rs b/core/src/metadata/declarations/method_declaration.rs
new file mode 100644
index 0000000..65c7fb9
--- /dev/null
+++ b/core/src/metadata/declarations/method_declaration.rs
@@ -0,0 +1,276 @@
+use crate::enums::CorCallingConvention;
+use crate::metadata::com_helpers::get_unary_custom_attribute_string_value;
+use crate::metadata::declarations::parameter_declaration::ParameterDeclaration;
+use crate::{
+ bindings::enums,
+ bindings::helpers,
+ metadata::declarations::declaration::{Declaration, DeclarationKind},
+ metadata::declarations::type_declaration::TypeDeclaration,
+ metadata::signature::Signature,
+ prelude::*,
+};
+use std::borrow::Cow;
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct MethodDeclaration {
+ base: TypeDeclaration,
+ parameters: Vec,
+ return_type: *const u8,
+}
+
+const OVERLOAD_ATTRIBUTE: &str = "Windows.Foundation.Metadata.OverloadAttribute";
+const DEFAULT_OVERLOAD_ATTRIBUTE: &str = "Windows.Foundation.Metadata.DefaultOverloadAttribute";
+
+impl MethodDeclaration {
+ pub fn base<'b>(&self) -> &'b TypeDeclaration {
+ &self.base
+ }
+ pub fn new(metadata: Option>>, token: mdMethodDef) -> Self {
+ debug_assert!(metadata.is_none());
+ debug_assert!(
+ CorTokenType::from(enums::type_from_token(token)) == CorTokenType::mdtMethodDef
+ );
+ debug_assert!(token != mdMethodDefNil);
+
+ let mut parameters: Vec = Vec::new();
+
+ let mut signature = std::mem::MaybeUninit::uninit();
+ let mut signature_ptr = &mut signature.as_mut_ptr();
+ let mut signature_size = 0;
+ let mut return_type = std::ptr::null();
+ unsafe {
+ match Option::as_ref(&metadata) {
+ None => {}
+ Some(metadata) => {
+ let meta = Arc::clone(metadata);
+ if let Ok(metadata) = metadata.try_read() {
+ let result = metadata.get_method_props(
+ token,
+ None,
+ None,
+ None,
+ None,
+ None,
+ Some(signature_ptr as *mut *const u8),
+ Some(&mut signature_size),
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ let signature = signature.assume_init();
+ /*
+ #if _DEBUG
+ PCCOR_SIGNATURE startSignature{ signature };
+ #endif
+ */
+
+ if helpers::cor_sig_uncompress_calling_conv(signature as _)
+ == CorCallingConvention::ImageCeeCsCallconvGeneric as u32
+ {
+ core_unimplemented()
+ }
+
+ let mut arguments_count =
+ { helpers::cor_sig_uncompress_data(signature.as_ptr()) };
+
+ return_type = Signature::consume_type(signature.as_ptr());
+
+ let mut parameter_enumerator = std::ptr::null_mut();
+ let enumerator = &mut parameter_enumerator;
+ let mut parameters_count: ULONG = 0;
+ let mut parameter_tokens = [0; 1024];
+
+ let result = metadata.enum_params(
+ enumerator,
+ token,
+ &mut parameter_tokens,
+ parameter_tokens.len() as u32,
+ &mut parameters_count,
+ );
+ debug_assert!(result.is_ok());
+ debug_assert!(parameters_count < (parameter_tokens.len() - 1) as u32);
+ metadata.close_enum(parameter_enumerator);
+
+ let mut start_index = 0_usize;
+
+ if arguments_count + 1 == parameters_count {
+ start_index += 1;
+ }
+
+ for i in start_index..parameters_count as usize {
+ let sig_type = Signature::consume_type(signature as *const u8);
+ parameters.push(ParameterDeclaration::new(
+ Some(Arc::clone(&meta)),
+ parameter_tokens[i],
+ sig_type,
+ ))
+ }
+
+ // todo
+ //debug_assert!(signature_size == signature);
+ //debug_assert!(start_signature + signature_size == signature);
+ }
+ }
+ }
+ }
+
+ Self {
+ base: TypeDeclaration::new(DeclarationKind::Method, metadata, token),
+ parameters,
+ return_type,
+ }
+ }
+
+ pub fn is_initializer(&self) -> bool {
+ let mut full_name_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let mut method_flags = 0;
+ if let Some(metadata) = self.base.metadata() {
+ let result = metadata.get_method_props(
+ self.base.token(),
+ None,
+ Some(&mut full_name_data),
+ Some(full_name_data.len() as u32),
+ None,
+ Some(&mut method_flags),
+ None,
+ None,
+ None,
+ None,
+ );
+ assert!(result.is_ok());
+ }
+
+ helpers::is_md_instance_initializer_w(method_flags, full_name_data.as_ptr())
+ }
+
+ pub fn is_static(&self) -> bool {
+ let mut method_flags = 0;
+ if let Some(metadata) = self.base.metadata() {
+ let result = metadata.get_method_props(
+ self.base.token(),
+ None,
+ None,
+ None,
+ None,
+ Some(&mut method_flags),
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ helpers::is_md_static(method_flags)
+ }
+
+ pub fn is_sealed(&self) -> bool {
+ let mut method_flags = 0;
+ if let Some(metadata) = self.base.metadata() {
+ let result = metadata.get_method_props(
+ self.base.token(),
+ None,
+ None,
+ None,
+ None,
+ Some(&mut method_flags),
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ helpers::is_md_static(method_flags) || helpers::is_md_final(method_flags)
+ }
+
+ pub fn parameters(&self) -> &Vec {
+ &self.parameters
+ }
+
+ pub fn number_of_parameters(&self) -> usize {
+ self.parameters.len()
+ }
+
+ pub fn overload_name<'b>(&self) -> Cow<'b, str> {
+ get_unary_custom_attribute_string_value(
+ self.base.metadata(),
+ self.base.token(),
+ OVERLOAD_ATTRIBUTE,
+ )
+ }
+
+ pub fn is_default_overload(&self) -> bool {
+ let data = windows::HSTRING::from(DEFAULT_OVERLOAD_ATTRIBUTE).as_wide();
+ if let Some(metadata) = self.base.metadata() {
+ let get_attribute_result =
+ metadata.get_custom_attribute_by_name(self.base.token(), Some(data), None, None);
+ debug_assert!(get_attribute_result.is_ok());
+ return get_attribute_result.0 == 0;
+ }
+ false
+ }
+}
+
+impl Declaration for MethodDeclaration {
+ fn is_exported(&self) -> bool {
+ let mut method_flags: DWORD = 0;
+ if let Some(metadata) = self.base.metadata() {
+ let result = metadata.get_method_props(
+ self.base.token(),
+ None,
+ None,
+ None,
+ None,
+ Some(&mut method_flags),
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+
+ if !(helpers::is_md_public(method_flags)
+ || helpers::is_md_family(method_flags)
+ || helpers::is_md_fam_orassem(method_flags))
+ {
+ return false;
+ }
+
+ if helpers::is_md_special_name(method_flags) {
+ return false;
+ }
+
+ return true;
+ }
+
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.full_name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ let mut name_length = 0;
+ let mut data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ if let Some(metadata) = self.base.metadata() {
+ let result = metadata.get_method_props(
+ self.base.token(),
+ None,
+ Some(&mut data),
+ Some(data.len() as u32),
+ Some(&mut name_length),
+ None,
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ OsString::from_wide(&data[..name_length as usize]).to_string_lossy()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
diff --git a/core/src/metadata/declarations/mod.rs b/core/src/metadata/declarations/mod.rs
new file mode 100644
index 0000000..7b51a98
--- /dev/null
+++ b/core/src/metadata/declarations/mod.rs
@@ -0,0 +1,15 @@
+pub mod declaration;
+pub mod type_declaration;
+pub mod field_declaration;
+pub mod enum_declaration;
+pub mod base_class_declaration;
+pub mod interface_declaration;
+pub mod method_declaration;
+pub mod property_declaration;
+pub mod event_declaration;
+pub mod class_declaration;
+pub mod parameter_declaration;
+pub mod delegate_declaration;
+pub mod namespace_declaration;
+pub mod struct_declaration;
+pub mod struct_field_declaration;
\ No newline at end of file
diff --git a/core/src/metadata/declarations/namespace_declaration.rs b/core/src/metadata/declarations/namespace_declaration.rs
new file mode 100644
index 0000000..abd78db
--- /dev/null
+++ b/core/src/metadata/declarations/namespace_declaration.rs
@@ -0,0 +1,99 @@
+use crate::bindings::ro_resolve_namespace;
+use crate::{
+ metadata::declarations::declaration::{Declaration, DeclarationKind},
+ metadata::declarations::type_declaration::TypeDeclaration,
+};
+use core_bindings::HSTRING__;
+use std::borrow::Cow;
+use std::option::Option::Some;
+
+#[derive(Clone, Debug)]
+pub struct NamespaceDeclaration<'a> {
+ base: TypeDeclaration,
+ children: Vec>,
+ full_name: Cow<'a, str>,
+}
+
+impl<'a> Declaration for NamespaceDeclaration<'a> {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ let mut fully_qualified_name = self.full_name().to_owned();
+ if let Some(index) = fully_qualified_name.find(".") {
+ fully_qualified_name = fully_qualified_name.chars().skip(index + 1).collect()
+ }
+ return fully_qualified_name;
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ self.full_name.into()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
+
+impl<'a> NamespaceDeclaration<'a> {
+ pub fn new(full_name: &str) -> Self {
+ debug_assert!(full_name.is_empty());
+
+ let mut namespaces_count = 0;
+
+ let mut full_name_w = windows::HSTRING::from(full_name);
+ // Grab size
+ unsafe {
+ ro_resolve_namespace(
+ &mut full_name_w,
+ None,
+ 0,
+ None,
+ None,
+ None,
+ &mut namespaces_count,
+ None,
+ );
+ }
+
+ let mut namespaces: Vec = Vec::with_capacity(namespaces_count as usize);
+ let namespaces_ptr = &mut namespaces.as_mut_ptr();
+
+ // https://docs.microsoft.com/en-us/windows/win32/api/rometadataresolution/nf-rometadataresolution-roresolvenamespace
+ // RoResolveNamespace gives incomplete results, find a better way.
+
+ let hr = ro_resolve_namespace(
+ unsafe { std::mem::transmute(windows::HSTRING::from(full_name)) },
+ None,
+ 0,
+ None,
+ None,
+ None,
+ &mut namespaces_count,
+ Some(namespaces_ptr as _),
+ );
+
+ let children = unsafe {
+ namespaces
+ .into_iter()
+ .map(|val| {
+ std::mem::transmute::(val)
+ .to_string_lossy()
+ .into()
+ })
+ .collect()
+ };
+
+ // The search for the "Windows" namespace on Windows Phone 8.1 fails both on a device and on an emulator with corrupted metadata error.
+
+ // if (FAILED(hr)) {
+ // return;
+ // }
+
+ Self {
+ base: TypeDeclaration::new(DeclarationKind::Namespace, None, 0),
+ children,
+ full_name: full_name.into(),
+ }
+ }
+ pub fn children(&self) -> &[Cow<'a, str>] {
+ self.children.as_slice()
+ }
+}
diff --git a/core/src/metadata/declarations/parameter_declaration.rs b/core/src/metadata/declarations/parameter_declaration.rs
new file mode 100644
index 0000000..cf68f03
--- /dev/null
+++ b/core/src/metadata/declarations/parameter_declaration.rs
@@ -0,0 +1,71 @@
+use crate::bindings::{enums, helpers};
+use crate::enums::CorElementType;
+use crate::metadata::declarations::declaration::{Declaration, DeclarationKind};
+use crate::metadata::declarations::type_declaration::TypeDeclaration;
+use crate::prelude::*;
+use std::borrow::Cow;
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct ParameterDeclaration {
+ base: TypeDeclaration,
+ parameter_type: PCCOR_SIGNATURE,
+}
+
+impl ParameterDeclaration {
+ pub fn new(
+ metadata: Option>>,
+ token: mdParamDef,
+ sig_type: PCCOR_SIGNATURE,
+ ) -> Self {
+ debug_assert!(metadata.is_none());
+ debug_assert!(
+ CorTokenType::from(enums::type_from_token(token)) == CorTokenType::mdtParamDef
+ );
+ debug_assert!(token != mdParamDefNil);
+
+ Self {
+ base: TypeDeclaration::new(DeclarationKind::Parameter, metadata, token),
+ parameter_type: sig_type,
+ }
+ }
+ pub fn is_out(&self) -> bool {
+ helpers::cor_sig_uncompress_token(self.parameter_type)
+ == CorElementType::ElementTypeByref as u32
+ }
+}
+
+impl Declaration for ParameterDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.full_name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ match self.base.metadata() {
+ None => Cow::default(),
+ Some(metadata) => {
+ let mut full_name_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let mut length = 0;
+
+ let result = metadata.get_param_props(
+ self.token,
+ None,
+ None,
+ Some(&mut full_name_data),
+ Some(full_name_data.len() as u32),
+ Some(&mut length),
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ OsString::from_wide(full_name_data[..length]).into()
+ }
+ }
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
diff --git a/core/src/metadata/declarations/property_declaration.rs b/core/src/metadata/declarations/property_declaration.rs
new file mode 100644
index 0000000..ee1f161
--- /dev/null
+++ b/core/src/metadata/declarations/property_declaration.rs
@@ -0,0 +1,235 @@
+use crate::enums::CorCallingConvention;
+use crate::{
+ bindings::enums,
+ bindings::helpers,
+ metadata::declarations::declaration::{Declaration, DeclarationKind},
+ metadata::declarations::field_declaration::FieldDeclaration,
+ metadata::declarations::method_declaration::MethodDeclaration,
+ prelude::*,
+};
+use std::borrow::Cow;
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct PropertyDeclaration {
+ base: FieldDeclaration,
+ getter: MethodDeclaration,
+ setter: Option,
+}
+
+impl Declaration for PropertyDeclaration {
+ fn is_exported(&self) -> bool {
+ let mut property_flags = 0;
+ {
+ match self.base.metadata() {
+ None => {}
+ Some(metadata) => {
+ let result = metadata.get_property_props(
+ self.base.token(),
+ None,
+ None,
+ None,
+ None,
+ Some(&mut property_flags),
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ }
+ }
+
+ if helpers::is_pr_special_name(property_flags) {
+ return false;
+ }
+ true
+ }
+
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ let mut full_name_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let mut name_length = 0;
+ if let Some(metadata) = self.base.metadata() {
+ let result = metadata.get_property_props(
+ self.base.token(),
+ None,
+ Some(&mut full_name_data),
+ Some(full_name_data.len() as u32),
+ Some(&mut name_length),
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ OsString::from_wide(&full_name_data[..name_length]).into()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
+
+impl PropertyDeclaration {
+ fn make_getter(
+ metadata: Option>>,
+ token: mdProperty,
+ ) -> MethodDeclaration {
+ let mut getter_token = mdTokenNil;
+ match Option::as_ref(&metadata) {
+ None => {}
+ Some(metadata) => match metadata.try_read() {
+ Ok(metadata) => {
+ let result = metadata.get_property_props(
+ token,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ Some(&mut getter_token),
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+
+ debug_assert!(getter_token != mdMethodDefNil);
+ }
+ Err(_) => {}
+ },
+ }
+ MethodDeclaration::new(metadata, getter_token)
+ }
+
+ fn make_setter<'b>(
+ metadata: Option>>,
+ token: mdProperty,
+ ) -> Option {
+ let mut setter_token = mdTokenNil;
+
+ if let Some(metadata) = Option::as_ref(&metadata) {
+ match metadata.try_read() {
+ Ok(metadata) => {
+ let result = metadata.get_property_props(
+ token,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ Some(&mut setter_token),
+ None,
+ None,
+ None,
+ None,
+ );
+ debug_assert!(result.is_ok());
+ }
+ Err(_) => {}
+ }
+ }
+
+ if setter_token == mdMethodDefNil {
+ return None;
+ }
+
+ return Some(MethodDeclaration::new(metadata, setter_token));
+ }
+
+ pub fn new(metadata: Option>>, token: mdProperty) -> Self {
+ debug_assert!(metadata.is_none());
+ debug_assert!(enums::type_from_token(token) == CorTokenType::mdtProperty as u32);
+ debug_assert!(token != mdPropertyNil);
+
+ Self {
+ base: FieldDeclaration::new(
+ DeclarationKind::Property,
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ getter: PropertyDeclaration::make_getter(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ setter: PropertyDeclaration::make_setter(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ }
+ }
+
+ pub fn is_static(&self) -> bool {
+ let mut signature = [0_u8; MAX_IDENTIFIER_LENGTH];
+ let mut signature_count = 0;
+
+ if let Some(metadata) = self.base.metadata() {
+ let result = metadata.get_property_props(
+ self.base.token(),
+ None,
+ None,
+ None,
+ None,
+ None,
+ Some(signature.as_mut_ptr() as _),
+ Some(&mut signature_count),
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ );
+
+ debug_assert!(result.is_ok());
+
+ debug_assert!(signature_count > 0);
+ }
+
+ (signature[0] & CorCallingConvention::ImageCeeCsCallconvGenericinst) == 0
+ }
+
+ pub fn is_sealed(&self) -> bool {
+ self.getter.is_sealed()
+ }
+
+ pub fn getter(&self) -> &MethodDeclaration {
+ &self.getter
+ }
+
+ pub fn setter(&self) -> Option<&MethodDeclaration> {
+ self.setter.as_ref()
+ }
+}
diff --git a/core/src/metadata/declarations/struct_declaration.rs b/core/src/metadata/declarations/struct_declaration.rs
new file mode 100644
index 0000000..999e593
--- /dev/null
+++ b/core/src/metadata/declarations/struct_declaration.rs
@@ -0,0 +1,88 @@
+use crate::metadata::declarations::declaration::{Declaration, DeclarationKind};
+use crate::metadata::declarations::struct_field_declaration::StructFieldDeclaration;
+use crate::metadata::declarations::type_declaration::TypeDeclaration;
+use crate::prelude::*;
+use std::borrow::Cow;
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct StructDeclaration {
+ base: TypeDeclaration,
+ fields: Vec,
+}
+
+impl Declaration for StructDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ self.base.full_name()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
+
+impl StructDeclaration {
+ pub fn new(metadata: Option>>, token: mdTypeDef) -> Self {
+ Self {
+ base: TypeDeclaration::new(
+ DeclarationKind::Struct,
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ fields: StructDeclaration::make_field_declarations(
+ Option::as_ref(&metadata).map(|v| Arc::clone(v)),
+ token,
+ ),
+ }
+ }
+
+ pub fn size(&self) -> usize {
+ self.fields.len()
+ }
+
+ pub fn fields(&self) -> &[StructFieldDeclaration] {
+ self.fields.as_slice()
+ }
+
+ fn make_field_declarations(
+ metadata: Option>>,
+ token: mdTypeDef,
+ ) -> Vec {
+ let mut result = Vec::new();
+
+ if let Some(metadata) = Option::as_ref(&metadata) {
+ let meta = Arc::clone(metadata);
+ if let Ok(metadata) = metadata.try_read() {
+ let mut enumerator = std::ptr::null_mut();
+ let mut count = 0;
+ let mut tokens = [0; 1024];
+ let mut enumerator_ptr = &mut enumerator;
+ let result_inner = metadata.enum_fields(
+ enumerator_ptr,
+ token,
+ &mut tokens,
+ tokens.len() as u32,
+ &mut count,
+ );
+ debug_assert!(result_inner.is_ok());
+
+ debug_assert!(count < (tokens.len() - 1) as u32);
+
+ metadata.close_enum(enumerator);
+
+ for i in 0..count {
+ result.push(StructFieldDeclaration::new(
+ Some(Arc::clone(&meta)),
+ tokens[i],
+ ))
+ }
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/core/src/metadata/declarations/struct_field_declaration.rs b/core/src/metadata/declarations/struct_field_declaration.rs
new file mode 100644
index 0000000..ae41109
--- /dev/null
+++ b/core/src/metadata/declarations/struct_field_declaration.rs
@@ -0,0 +1,70 @@
+use crate::bindings::helpers;
+use crate::metadata::declarations::declaration::{Declaration, DeclarationKind};
+use crate::metadata::declarations::field_declaration::FieldDeclaration;
+use crate::prelude::*;
+use std::borrow::Cow;
+use std::sync::{Arc, RwLock};
+
+#[derive(Clone, Debug)]
+pub struct StructFieldDeclaration {
+ base: FieldDeclaration,
+}
+
+impl Declaration for StructFieldDeclaration {
+ fn name<'b>(&self) -> Cow<'b, str> {
+ self.base.name()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ self.base.full_name()
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.base.kind()
+ }
+}
+
+impl StructFieldDeclaration {
+ pub fn base(&self) -> &FieldDeclaration {
+ &self.base
+ }
+ pub fn new(metadata: Option>>, token: mdFieldDef) -> Self {
+ Self {
+ base: FieldDeclaration::new(DeclarationKind::StructField, metadata, token),
+ }
+ }
+
+ pub fn type_<'b>(&self) -> Cow<'b, [u8]> {
+ let mut signature = [0_u8; MAX_IDENTIFIER_LENGTH];
+ let mut signature_size = 0;
+ match self.base.metadata() {
+ None => Cow::default(),
+ Some(metadata) => {
+ let result = metadata.get_field_props(
+ self.base.token(),
+ None,
+ None,
+ None,
+ None,
+ None,
+ Some(signature.as_mut_ptr() as *mut *const u8),
+ Some(&mut signature_size),
+ None,
+ None,
+ None,
+ );
+
+ debug_assert!(result.is_ok());
+
+ let header = helpers::cor_sig_uncompress_data(signature.as_mut_ptr());
+ debug_assert!(
+ CorCallingConvention::from(header)
+ == CorCallingConvention::ImageCeeCsCallconvField
+ );
+
+ let result = &signature[..signature_size as usize];
+ result.into()
+ }
+ }
+ }
+}
diff --git a/core/src/metadata/declarations/type_declaration.rs b/core/src/metadata/declarations/type_declaration.rs
new file mode 100644
index 0000000..7f8accb
--- /dev/null
+++ b/core/src/metadata/declarations/type_declaration.rs
@@ -0,0 +1,121 @@
+pub use super::declaration::{Declaration, DeclarationKind};
+use crate::bindings::{enums, helpers};
+
+use crate::prelude::IMetaDataImport2;
+use crate::prelude::*;
+use std::borrow::Cow;
+use std::ffi::OsString;
+use std::sync::{Arc, RwLock, RwLockReadGuard, TryLockError};
+
+#[derive(Clone, Debug)]
+pub struct TypeDeclaration {
+ kind: DeclarationKind,
+ metadata: Option>>,
+ token: mdTypeDef,
+}
+
+impl Declaration for TypeDeclaration {
+ fn is_exported(&self) -> bool {
+ let mut flags: DWORD = 0;
+ match self.metadata() {
+ None => false,
+ Some(metadata) => {
+ let result = metadata.get_type_def_props(
+ self.token,
+ None,
+ None,
+ None,
+ Some(&mut flags),
+ None,
+ );
+
+ debug_assert!(result.is_ok());
+
+ if !helpers::is_td_public(flags) || helpers::is_td_special_name(flags) {
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+
+ fn name<'b>(&self) -> Cow<'b, str> {
+ let mut name = self.full_name().to_string();
+ let back_tick_index = name.find('`');
+ if let Some(index) = back_tick_index {
+ name = name
+ .chars()
+ .take(0)
+ .chain(name.chars().skip(index))
+ .collect()
+ }
+
+ let dot_index = name.find('.');
+ if let Some(index) = dot_index {
+ name = name
+ .chars()
+ .take(0)
+ .chain(name.chars().skip(index + 1))
+ .collect()
+ }
+
+ name.into()
+ }
+
+ fn full_name<'b>(&self) -> Cow<'b, str> {
+ let mut full_name_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ match self.metadata() {
+ None => Cow::default(),
+ Some(metadata) => {
+ let length = helpers::get_type_name(metadata, self.token, &mut full_name_data);
+ OsString::from_wide(&full_name_data[..length as usize]).to_string_lossy()
+ }
+ }
+ }
+
+ fn kind(&self) -> DeclarationKind {
+ self.kind
+ }
+}
+
+impl TypeDeclaration {
+ pub fn kind(&self) -> DeclarationKind {
+ self.kind
+ }
+
+ pub fn token(&self) -> mdTypeDef {
+ self.token
+ }
+
+ pub fn new(
+ kind: DeclarationKind,
+ metadata: Option>>,
+ token: mdTypeDef,
+ ) -> Self {
+ debug_assert!(metadata.is_none());
+ debug_assert!(
+ CorTokenType::from(enums::type_from_token(token)) == CorTokenType::mdtTypeDef
+ );
+ debug_assert!(token != mdTypeDefNil);
+ Self {
+ kind,
+ metadata,
+ token,
+ }
+ }
+
+ pub fn metadata(&self) -> Option<&IMetaDataImport2> {
+ match Option::as_ref(&self.metadata) {
+ None => None,
+ Some(metadata) => match metadata.try_read() {
+ Ok(value) => &value,
+ Err(_) => None,
+ },
+ }
+ }
+
+ pub fn metadata_shared(&self) -> Option>> {
+ Option::as_ref(&self.metadata).map(|v| Arc::clone(&v))
+ }
+}
diff --git a/core/src/metadata/declaring_interface_for_method.rs b/core/src/metadata/declaring_interface_for_method.rs
new file mode 100644
index 0000000..f1948d7
--- /dev/null
+++ b/core/src/metadata/declaring_interface_for_method.rs
@@ -0,0 +1,620 @@
+use crate::prelude::*;
+use crate::bindings::{enums, imeta_data_import2, helpers};
+use std::borrow::Cow;
+use crate::metadata::com_helpers::{get_string_value_from_blob, get_type_name, SYSTEM_TYPE, COMPOSABLE_ATTRIBUTE, ACTIVATABLE_ATTRIBUTE, STATIC_ATTRIBUTE, resolve_type_ref};
+use crate::metadata::declarations::interface_declaration::InterfaceDeclaration;
+use crate::metadata::declarations::interface_declaration::generic_interface_instance_declaration::GenericInterfaceInstanceDeclaration;
+use crate::metadata::declarations::base_class_declaration::BaseClassDeclarationImpl;
+use std::sync::{Arc, Mutex};
+use crate::metadata::declarations::method_declaration::MethodDeclaration;
+
+#[derive(Debug)]
+pub struct Metadata {}
+
+impl Metadata {
+ pub fn get_method_containing_class_token(metadata: *mut IMetaDataImport2, method_token: mdMethodDef) -> u32 {
+ let mut class_token = mdTokenNil;
+
+ match CorTokenType::from(enums::type_from_token(method_token)) {
+ CorTokenType::mdtMethodDef => {
+ debug_assert!(
+ imeta_data_import2::get_method_props(
+ metadata, method_token, Some(&mut class_token), None,
+ None, None, None, None,
+ None, None, None,
+ ).is_ok()
+ );
+ }
+ CorTokenType::mdtMemberRef => {
+ debug_assert!(
+ imeta_data_import2::get_member_ref_props(
+ metadata, method_token, Some(&mut class_token), None, None,
+ None, None, None,
+ ).is_ok()
+ );
+ }
+ _ => {
+ std::unreachable!()
+ }
+ }
+
+ return class_token;
+ }
+
+ pub fn get_custom_attribute_constructor_token(metadata: *mut IMetaDataImport2, custom_attribute: mdCustomAttribute) -> u32 {
+ let mut constructor_token = mdTokenNil;
+ debug_assert!(
+ imeta_data_import2::get_custom_attribute_props(
+ metadata, custom_attribute, None, Some(&mut constructor_token),
+ None, None,
+ ).is_ok()
+ );
+ constructor_token
+ }
+
+ pub fn get_custom_attribute_class_token(metadata: *mut IMetaDataImport2, custom_attribute: mdCustomAttribute) -> u32 {
+ Metadata::get_method_containing_class_token(metadata, Metadata::get_custom_attribute_constructor_token(metadata, custom_attribute))
+ }
+
+ pub fn get_method_signature<'a>(metadata: *mut IMetaDataImport2, token: mdMethodDef) -> Cow<'a, [u8]> {
+ let mut signature = [0_u8; MAX_IDENTIFIER_LENGTH];
+ let signature_ptr = &mut signature.as_mut_ptr();
+ let mut signature_size = 0;
+ match CorTokenType::from(enums::type_from_token(token)) {
+ CorTokenType::mdtMethodDef => {
+ imeta_data_import2::get_method_props(
+ metadata, token,
+ None, None, None, None,
+ None, Some(signature_ptr as *mut *const u8),
+ Some(&mut signature_size), None, None,
+ ).is_ok()
+ }
+ CorTokenType::mdtMemberRef => {
+ imeta_data_import2::get_member_ref_props(
+ metadata, token, None,
+ None, None, None, Some(signature_ptr as *mut *const u8),
+ Some(&mut signature_size),
+ ).is_ok()
+ }
+ _ => {
+ std::unreachable!()
+ }
+ }
+ // todo clean up
+ let mut new_signature: [u8] = signature[..signature_size];
+ let os = unsafe { new_signature.as_ptr().offset(1) };
+ unsafe { std::slice::from_raw_parts(os, new_signature.len() - 1).into() }
+ }
+
+ pub fn get_signature_argument_count(metadata: *mut IMetaDataImport2, signature: Cow<[u8]>) -> u32 {
+ helpers::cor_sig_uncompress_data(signature.as_ptr())
+ }
+
+ pub fn get_method_argument_count(metadata: *mut IMetaDataImport2, token: mdToken) -> u32 {
+ let signature = Metadata::get_method_signature(metadata, token);
+ Metadata::get_signature_argument_count(metadata, signature)
+ }
+
+
+ pub fn get_custom_attributes_with_name(metadata: *mut IMetaDataImport2, token: mdTypeDef, attribute_name: &str) -> Vec {
+ // mdCustomAttribute
+ let mut attributes = [0; 512];
+ let mut attributes_count = 0;
+ let mut attributes_enumerator = std::ptr::null_mut();
+ let attributes_enumerator_ptr = &mut attributes_enumerator;
+
+ debug_assert!(
+ imeta_data_import2::enum_custom_attributes(
+ metadata, Some(attributes_enumerator_ptr), Some(token), None,
+ Some(attributes.as_mut_ptr()), Some(attributes.len() as u32),
+ Some(&mut attributes_count),
+ ).is_ok()
+ );
+ debug_assert!(
+ attributes_count < (attributes.len() - 1) as u32
+ );
+ imeta_data_import2::close_enum(
+ metadata, attributes_enumerator,
+ );
+
+
+ let mut filtered_attributes: Vec = Vec::new();
+ let new_attributes: [u32] = attributes[..attributes_count];
+ for attribute in new_attributes.iter() {
+ let class_attribute_class_token = Metadata::get_custom_attribute_class_token(metadata, attribute);
+ let mut name = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let length = helpers::get_type_name(metadata, class_attribute_class_token, name.as_mut_ptr(), name.len() as u32);
+ let mut class_attribute_class_name = windows::HSTRING::from_wide(name[..length]);
+ // TODO
+ if class_attribute_class_name != attribute_name {
+ continue;
+ }
+
+ filtered_attributes.push(
+ attribute
+ );
+
+ filtered_attributes.push_back(attribute);
+ }
+ filtered_attributes
+ }
+
+ pub fn get_custom_attribute_type_argument(metadata: *mut IMetaDataImport2, token: mdCustomAttribute) -> u32 {
+ let mut attribute_value = std::mem::MaybeUninit::uninit();
+ let attribute_value_ptr = &mut attribute_value;
+ let mut attribute_value_size = 0;
+ debug_assert!(imeta_data_import2::get_custom_attribute_props(
+ metadata, token,
+ None, None, Some(attribute_value_ptr as *mut *const u8), Some(&mut attribute_value_size),
+ ).is_ok());
+
+ let type_name = get_string_value_from_blob(
+ metadata, unsafe { attribute_value.as_ptr().offset(2) },
+ );
+
+ let type_name_data = windows::HSTRING::from(type_name);
+ let type_name_data = type_name_data.as_wide();
+
+ let mut type_token = mdTokenNil;
+ debug_assert!(imeta_data_import2::find_type_def_by_name(
+ metadata, Some(type_name_data.as_ptr()), None, Some(&mut type_token),
+ ).is_ok());
+ return type_token;
+ }
+
+
+ pub fn get_class_methods<'a>(metadata: *mut IMetaDataImport2, token: mdTypeDef) -> Cow<'a, [u32]> {
+ let mut methods = [0; 1024];
+ let mut methods_count = 0;
+ let mut methods_enumerator = std::ptr::null_mut();
+ let methods_enumerator_ptr = &mut methods_enumerator;
+ debug_assert!(
+ imeta_data_import2::enum_methods(
+ metadata, methods_enumerator_ptr, token, methods.as_mut_ptr(),
+ methods.len() as u32, &mut methods_count,
+ ).is_ok()
+ );
+ debug_assert!(
+ methods_count < (methods.len() - 1) as u32
+ );
+ imeta_data_import2::close_enum(
+ metadata, methods_enumerator,
+ );
+
+ methods[..methods_count]
+ }
+
+
+ pub fn has_method_first_type_argument(metadata: *mut IMetaDataImport2, token: mdToken) -> bool {
+ let mut signature = Metadata::get_method_signature(
+ metadata, token,
+ );
+ let argument_count = helpers::cor_sig_uncompress_data(signature.as_ptr());
+
+ if argument_count == 0 {
+ return false;
+ }
+
+ let return_type = helpers::cor_sig_uncompress_element_type(signature.as_ptr());
+
+ debug_assert!(
+ return_type == crate::enums::CorElementType::ElementTypeVoid
+ );
+
+ let first_argument = helpers::cor_sig_uncompress_element_type(signature.as_ptr());
+
+
+ if first_argument == crate::enums::CorElementType::ElementTypeClass {
+ return false;
+ }
+
+ let first_argument_token = helpers::cor_sig_uncompress_token(signature.as_ptr());
+ let first_argument_type_name = get_type_name(
+ metadata, first_argument_token,
+ );
+
+ if first_argument_type_name != SYSTEM_TYPE {
+ return false;
+ }
+
+ return true;
+ }
+
+
+ pub fn declaring_interface_for_initializer<'a>(metadata: *mut IMetaDataImport2, method_token: mdMethodDef, out_index: &mut usize) -> Option>> {
+ // InterfaceDeclaration
+ let method_argument_count = Metadata::get_method_argument_count(metadata, method_token);
+
+ let class_token = Metadata::get_method_containing_class_token(metadata, method_token);
+
+ debug_assert!(
+ CorTokenType::from(enums::type_from_token(class_token)) == crate::enums::CorTokenType::mdtTypeDef
+ );
+
+ let composable_attributes = Metadata::get_custom_attributes_with_name(
+ metadata, class_token, COMPOSABLE_ATTRIBUTE,
+ );
+
+ for attributeToken in composable_attributes.iter() {
+ let factory_token = Metadata::get_custom_attribute_type_argument(
+ metadata, attributeToken,
+ );
+
+ let factory_methods = Metadata::get_class_methods(
+ metadata, attributeToken,
+ );
+
+ for (i, factoryMethod) in factory_methods.iter().enumerate() {
+ let factory_method_arguments_count = Metadata::get_method_argument_count(metadata, factoryMethod);
+ if factory_method_arguments_count - 2 != method_argument_count {
+ continue;
+ }
+
+ *out_index = i;
+ return Some(
+ Arc::new(
+ Mutex::new(
+ InterfaceDeclaration::new(metadata, factory_token)
+ )
+ )
+ );
+ }
+ }
+
+ if method_argument_count == 0 {
+ *out_index = usize::MAX;
+ return None;
+ }
+
+
+ let mut activatable_attributes = Metadata::get_custom_attributes_with_name(
+ metadata, class_token, ACTIVATABLE_ATTRIBUTE,
+ );
+ for attributeToken in activatable_attributes.iter() {
+ let attribute_constructor_token = Metadata::get_custom_attribute_constructor_token(
+ metadata, attributeToken,
+ );
+
+ if !Metadata::has_method_first_type_argument(metadata, attribute_constructor_token) {
+ continue;
+ }
+
+ let factory_token = Metadata::get_custom_attribute_type_argument(metadata, attributeToken);
+
+
+ let factory_methods = Metadata::get_class_methods(
+ metadata, factory_token,
+ );
+
+ for (i, factory_method) in factory_methods.iter().enumerate() {
+ let factory_method_arguments_count = Metadata::get_method_argument_count(
+ metadata, factory_method,
+ );
+
+ if factory_method_arguments_count != method_argument_count {
+ continue;
+ }
+
+ *out_index = i;
+ return Some(
+ Arc::new(
+ Mutex::new(
+ InterfaceDeclaration::new(metadata, factory_token)
+ )
+ )
+ );
+ }
+ }
+
+ // return Option ?
+ std::unreachable!();
+ }
+
+
+ pub fn declaring_interface_for_static_method<'a>(metadata: *mut IMetaDataImport2, method_token: mdMethodDef, out_index: &mut usize) -> Option>> {
+ let method_signature = Metadata::get_method_signature(
+ metadata, method_token,
+ );
+ let class_token = Metadata::get_method_containing_class_token(
+ metadata, method_token,
+ );
+ debug_assert!(
+ CorTokenType::from(enums::type_from_token(class_token)) == CorTokenType::mdtTypeDef
+ );
+
+ let static_attributes = Metadata::get_custom_attributes_with_name(
+ metadata, class_token, STATIC_ATTRIBUTE,
+ );
+
+ for attributeToken in static_attributes.iter() {
+ let statics_token = Metadata::get_custom_attribute_type_argument(
+ metadata, attributeToken,
+ );
+
+ let static_methods = Metadata::get_class_methods(
+ metadata, statics_token,
+ );
+
+ for (i, staticMethod) in static_methods.iter().enumerate() {
+ let mut static_signature = [0_u8; MAX_IDENTIFIER_LENGTH];
+ let static_signature_ptr = &mut static_signature.as_mut_ptr();
+ let mut static_signature_size = 0;
+ debug_assert!(imeta_data_import2::get_method_props(
+ metadata, staticMethod,
+ None, None, None, None, None,
+ Some(static_signature_ptr as *mut *const u8), Some(&mut static_signature_size),
+ None, None,
+ ));
+ let static_signature: &[u8] = &static_signature[..static_signature_size as usize];
+
+ unsafe {
+ if libc::memcmp(
+ static_signature.as_ptr().offset(1) as _,
+ method_signature.as_ptr() as _,
+ static_signature_size as usize,
+ ) != 0 {
+ continue;
+ }
+ }
+ *out_index = i;
+ return Some(Arc::new(Mutex::new(InterfaceDeclaration::new(metadata, statics_token))));
+ }
+ }
+
+ std::unreachable!();
+ }
+
+
+ pub fn find_method_index(metadata: *mut IMetaDataImport2, class_token: mdTypeDef, method_token: mdMethodDef) -> usize {
+ let mut first_method = 0;
+
+ let mut methods_enumerator = std::ptr::null_mut();
+ let methods_enumerator_ptr = &mut methods_enumerator;
+ debug_assert!(
+ imeta_data_import2::enum_methods(
+ metadata, methods_enumerator_ptr, class_token, &mut first_method, 1, 0 as _,
+ ).is_ok()
+ );
+
+ imeta_data_import2::close_enum(metadata, methods_enumerator);
+
+
+ return (method_token - first_method) as usize;
+ }
+
+
+ pub fn declaring_interface_for_instance_method(metadata: *mut IMetaDataImport2, method_token: mdMethodDef, out_index: &mut usize) -> Option>> {
+ let class_token = Metadata::get_method_containing_class_token(
+ metadata, method_token,
+ );
+ debug_assert!(
+ CorTokenType::from(enums::type_from_token(class_token)) == CorTokenType::mdtTypeDef
+ );
+ let mut method_body_tokens = [0; 1024];
+ let mut method_decl_tokens = [0; 1024];
+ let mut method_impls_count = 0;
+ let mut method_impls_enumerator = std::ptr::null_mut();
+ let method_impls_enumerator_ptr = &mut method_impls_enumerator;
+ debug_assert!(
+ imeta_data_import2::enum_method_impls(
+ metadata, method_impls_enumerator_ptr, Some(class_token),
+ Some(&mut method_body_tokens),
+ Some(&mut method_decl_tokens),
+ Some(method_body_tokens.len() as u32),
+ Some(&mut method_impls_count),
+ ).is_ok()
+ );
+
+ debug_assert!(
+ method_impls_count < (method_body_tokens.len() - 1) as u32
+ );
+
+ imeta_data_import2::close_enum(metadata, method_impls_enumerator);
+
+ let mut result: Option>> = None;
+ for i in 0..method_impls_count {
+ let method_body_token = method_body_tokens[i];
+ debug_assert!(
+ CorTokenType::from(enums::type_from_token(method_body_token)) == CorTokenType::mdtMethodDef
+ );
+
+ if method_token != method_body_token {
+ continue;
+ }
+
+ let method_decl_token = method_decl_tokens[i];
+ match CorTokenType::from(enums::type_from_token(method_decl_token)) {
+ CorTokenType::mdtMethodDef => {
+ let mut declaring_interface_token = mdTokenNil;
+ debug_assert!(
+ imeta_data_import2::get_method_props(
+ metadata, method_decl_token,
+ Some(&mut declaring_interface_token), None,
+ None, None, None, None,
+ None, None, None,
+ ).is_ok()
+ );
+ *out_index = Metadata::find_method_index(
+ metadata, declaring_interface_token, method_decl_token,
+ );
+ result = Some(
+ Arc::new(
+ Mutex::new(
+ InterfaceDeclaration::new(metadata, declaring_interface_token)
+ )
+ )
+ );
+ }
+ CorTokenType::mdtMemberRef => {
+ let mut parent_token = 0;
+ debug_assert!(
+ imeta_data_import2::get_member_ref_props(
+ metadata, method_decl_token, Some(&mut parent_token), None,
+ None, None, None, None,
+ ).is_ok()
+ );
+
+ match CorTokenType::from(enums::type_from_token(parent_token)) {
+ CorTokenType::mdtTypeRef => {
+ let mut external_metadata = std::ptr::null_mut();
+ let external_metadata_ptr = &mut external_metadata;
+ let mut declaring_interface_token = 0;
+ let is_resolved = resolve_type_ref(
+ metadata, parent_token, external_metadata_ptr, &mut declaring_interface_token,
+ );
+ debug_assert!(
+ is_resolved
+ );
+
+ let mut declaring_method_name = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let mut signature = [0_u8; MAX_IDENTIFIER_LENGTH];
+ let signature_ptr = &mut signature.as_mut_ptr();
+ let mut signature_size = 0;
+ debug_assert!(
+ imeta_data_import2::get_member_ref_props(
+ metadata, method_decl_token, None,
+ Some(declaring_method_name.as_mut_ptr()),
+ Some(declaring_method_name.len() as u32),
+ None, Some(signature_ptr as *mut *const u8), Some(&mut signature_size),
+ )
+ );
+ let mut declaring_method = 0;
+ debug_assert!(
+ imeta_data_import2::find_method(
+ external_metadata as _, declaring_interface_token, declaring_method_name.as_mut_ptr(), Some(signature.as_ptr()), Some(signature_size), Some(&mut declaring_method),
+ ).is_ok()
+ );
+ *out_index = Metadata::find_method_index(
+ external_metadata as _, declaring_interface_token, declaring_method,
+ );
+ result = Some(
+ Arc::new(
+ Mutex::new(
+ InterfaceDeclaration::new(external_metadata as _, declaring_interface_token)
+ )
+ )
+ );
+ }
+ CorTokenType::mdtTypeSpec => {
+ let mut type_spec_signature = std::ptr::null_mut();
+ let type_spec_signature_ptr = &mut type_spec_signature;
+ let mut type_spec_signature_size = 0;
+ debug_assert!(
+ imeta_data_import2::get_type_spec_from_token(
+ metadata, parent_token, type_spec_signature_ptr as *mut *const u8, &mut type_spec_signature_size,
+ ).is_ok()
+ );
+
+
+ let mut declaring_method_name = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let mut signature = std::ptr::null_mut();
+ let signature_ptr = &mut signature;
+ let mut signature_size = 0;
+ debug_assert!(
+ imeta_data_import2::get_member_ref_props(
+ metadata, method_decl_token, None, Some(
+ declaring_method_name.as_mut_ptr()
+ ),
+ Some(declaring_method_name.len() as u32),
+ None, Some(signature_ptr as *mut *const u8), Some(&mut signature_size),
+ ).is_ok()
+ );
+ let type1 = helpers::cor_sig_uncompress_element_type(type_spec_signature.as_ptr());
+ debug_assert!(
+ type1 == crate::enums::CorElementType::ElementTypeGenericinst
+ );
+
+ let type2 = helpers::cor_sig_uncompress_element_type(type_spec_signature.as_ptr());
+ debug_assert!(
+ type2 == crate::enums::CorElementType::ElementTypeClass
+ );
+
+ // TODO: Use signature in matching
+ let open_generic_class_token = helpers::cor_sig_uncompress_token(type_spec_signature.as_ptr());
+ match CorTokenType::from(enums::type_from_token(open_generic_class_token)) {
+ CorTokenType::mdtTypeDef => {
+ let mut declaring_method = 0;
+ debug_assert!(imeta_data_import2::find_method(
+ metadata, open_generic_class_token, declaring_method_name.as_ptr(), None, None, Some(&mut declaring_method),
+ ).is_ok());
+ *out_index = Metadata::find_method_index(metadata, open_generic_class_token, 0);
+
+ result = Some(
+ Arc::new(
+ Mutex::new(
+ GenericInterfaceInstanceDeclaration::new(
+ metadata as _, open_generic_class_token, metadata as _, parent_token,
+ )
+ )
+ )
+ );
+ }
+ CorTokenType::mdtTypeRef => {
+ let mut external_metadata = std::ptr::null_mut();
+ let mut external_metadata_ptr = &mut external_metadata;
+ let mut external_class_token = mdTokenNil;
+
+ let is_resolved = resolve_type_ref(
+ metadata, open_generic_class_token, external_metadata_ptr, &mut external_class_token,
+ );
+ debug_assert!(
+ is_resolved
+ );
+
+ let mut declaring_method = 0;
+ debug_assert!(
+ imeta_data_import2::find_method(
+ external_metadata as _, external_class_token, declaring_method_name.as_ptr(), None, None, Some(&mut declaring_method),
+ ).is_ok()
+ );
+
+ *out_index = Metadata::find_method_index(external_metadata as _, external_class_token, declaring_method);
+ result = Some(
+ Arc::new(
+ Mutex::new(
+ GenericInterfaceInstanceDeclaration::new(external_metadata, external_class_token, metadata as _, parent_token)
+ )
+ )
+ );
+ }
+ _ => {
+ std::unreachable!()
+ }
+ }
+ }
+ _ => {
+ std::unreachable!()
+ }
+ }
+ }
+ _ => {
+ std::unreachable!();
+ }
+ }
+ };
+ result
+ }
+
+ pub fn find_declaring_interface_for_method(method: &MethodDeclaration, out_index: &mut usize) -> Option>> {
+ debug_assert!(
+ out_index
+ );
+
+ let metadata = method.base().metadata;
+ let method_token = method.base().token;
+
+ if method.is_static() {
+ Metadata::declaring_interface_for_static_method(
+ metadata, method_token, out_index,
+ )
+ } else if method.is_initializer() {
+ Metadata::declaring_interface_for_initializer(
+ metadata, method_token, out_index,
+ )
+ } else {
+ Metadata::declaring_interface_for_instance_method(
+ metadata, method_token, out_index,
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/src/metadata/generic_instance_id_builder.rs b/core/src/metadata/generic_instance_id_builder.rs
new file mode 100644
index 0000000..65de705
--- /dev/null
+++ b/core/src/metadata/generic_instance_id_builder.rs
@@ -0,0 +1,180 @@
+use core_bindings::{IRoSimpleMetaDataBuilder, GUID, PCWSTR};
+
+use crate::bindings::helpers;
+pub use crate::bindings::{iro_simple_meta_data_builder, rometadataresolution};
+use crate::metadata::declarations::class_declaration::ClassDeclaration;
+use crate::metadata::declarations::declaration::{Declaration, DeclarationKind};
+use crate::metadata::declarations::delegate_declaration::generic_delegate_declaration::GenericDelegateDeclaration;
+use crate::metadata::declarations::delegate_declaration::{
+ DelegateDeclaration, DelegateDeclarationImpl,
+};
+use crate::metadata::declarations::enum_declaration::EnumDeclaration;
+use crate::metadata::declarations::interface_declaration::generic_interface_declaration::GenericInterfaceDeclaration;
+use crate::metadata::declarations::struct_declaration::StructDeclaration;
+use crate::metadata::meta_data_reader::MetadataReader;
+use crate::metadata::signature::Signature;
+
+use crate::metadata::declarations::interface_declaration::InterfaceDeclaration;
+
+use crate::prelude::core_unreachable;
+
+#[derive(Debug)]
+pub struct GenericInstanceIdBuilder {}
+
+impl GenericInstanceIdBuilder {
+ extern "C" fn locator_impl(name: PCWSTR, builder: *mut IRoSimpleMetaDataBuilder) -> i32 {
+ let declaration = MetadataReader::find_by_name_w(name);
+ debug_assert!(declaration.is_some());
+
+ match Option::as_ref(&declaration) {
+ None => {}
+ Some(declaration) => match declaration.try_read() {
+ Ok(declaration) => match declaration.kind() {
+ DeclarationKind::Class => {
+ let mut class_declaration = declaration
+ .as_any()
+ .downcast_ref::()
+ .unwrap();
+
+ let default_interface = class_declaration.default_interface();
+ let default_interface_id = default_interface.id();
+ let full_name = windows::HSTRING::from(default_interface.full_name());
+ let full_name_w = full_name.as_wide();
+ let result = iro_simple_meta_data_builder::set_runtime_class_simple_default(
+ builder,
+ name,
+ full_name_w.as_ptr(),
+ &default_interface_id,
+ );
+ debug_assert!(result.is_ok());
+ return 0;
+ }
+ DeclarationKind::Interface => {
+ let mut interface_declaration = declaration
+ .as_any()
+ .downcast_ref::()
+ .unwrap();
+ let interface_declaration_id = interface_declaration.id();
+ iro_simple_meta_data_builder::set_win_rt_interface(
+ builder,
+ interface_declaration_id,
+ );
+ return 0;
+ }
+ DeclarationKind::GenericInterface => {
+ let mut generic_interface_declaration = declaration
+ .as_any()
+ .downcast_ref::()
+ .unwrap();
+ let result = iro_simple_meta_data_builder::set_parameterized_interface(
+ builder,
+ generic_interface_declaration.id(),
+ generic_interface_declaration.number_of_generic_parameters() as u32,
+ );
+ debug_assert!(result.is_ok());
+ return 0;
+ }
+ DeclarationKind::Enum => {
+ let mut enum_declaration = declaration
+ .as_any()
+ .downcast_ref::()
+ .unwrap();
+ let type_ = enum_declaration.type_().into_owned();
+ let full_name = windows::HSTRING::from(
+ enum_declaration.full_name().to_owned().as_ref(),
+ );
+ let full_name_w = full_name.as_wide();
+ let signature = Signature::to_string(std::ptr::null() as _, type_.as_ptr());
+ let signature = windows::HSTRING::from(signature.to_owned().as_ref());
+ let signature_w = signature.as_wide();
+ let result = iro_simple_meta_data_builder::set_enum(
+ builder,
+ full_name_w.as_ptr(),
+ signature_w.as_ptr(),
+ );
+ debug_assert!(result.is_ok());
+ return 0;
+ }
+ DeclarationKind::Struct => {
+ let mut struct_declaration =
+ declaration.downcast_ref::().unwrap();
+
+ let mut field_names = Vec::new();
+ for field in struct_declaration.fields().iter() {
+ let field_type = field.type_().to_owned();
+ let signature =
+ Signature::to_string(field.base().metadata, field_type.as_ptr());
+ let signature = windows::HSTRING::from(signature.as_ref());
+
+ field_names.push(signature);
+ }
+
+ let full_name =
+ windows::HSTRING::from(struct_declaration.full_name().as_ref());
+ let full_name_w = full_name.as_wide();
+ let field_names = field_names
+ .into_iter()
+ .map(|field| field.as_wide().as_ptr())
+ .collect();
+ let result = iro_simple_meta_data_builder::set_struct(
+ builder,
+ full_name_w.as_ptr(),
+ struct_declaration.size() as u32,
+ field_names.as_ptr(),
+ );
+ debug_assert!(result.is_ok());
+
+ return 0;
+ }
+ DeclarationKind::Delegate => {
+ let mut delegate_declaration = declaration
+ .as_any()
+ .downcast_ref::()
+ .unwrap();
+ let result = iro_simple_meta_data_builder::set_delegate(
+ builder,
+ delegate_declaration.id(),
+ );
+ debug_assert!(result.is_ok());
+ return 0;
+ }
+ DeclarationKind::GenericDelegate => {
+ let mut generic_delegate_declaration = declaration
+ .as_any()
+ .downcast_ref::()
+ .unwrap();
+ debug_assert!(iro_simple_meta_data_builder::set_parameterized_delegate(
+ builder,
+ generic_delegate_declaration.id(),
+ generic_delegate_declaration.number_of_generic_parameters() as u32,
+ )
+ .is_ok());
+ return 0;
+ }
+ _ => {}
+ },
+ Err(_) => {}
+ },
+ }
+ core_unreachable();
+ 1
+ }
+
+ pub fn generate_id(declaration: &dyn Declaration) -> GUID {
+ let mut declaration_full_name = declaration.full_name();
+
+ let mut result = helpers::generate_id_name(declaration_full_name.as_ref());
+
+ let mut guid = GUID::default();
+ let result = rometadataresolution::ro_get_parameterized_type_instance_iid(
+ result.1,
+ result.0.as_mut_ptr(),
+ Some(GenericInstanceIdBuilder::locator_impl),
+ &mut guid,
+ None,
+ );
+ debug_assert!(result.is_ok());
+
+ return guid;
+ }
+}
diff --git a/core/src/metadata/meta_data_reader.rs b/core/src/metadata/meta_data_reader.rs
new file mode 100644
index 0000000..c003a6c
--- /dev/null
+++ b/core/src/metadata/meta_data_reader.rs
@@ -0,0 +1,170 @@
+use std::sync::{Arc, RwLock};
+
+use windows::HSTRING;
+
+use crate::bindings::{enums, helpers, imeta_data_import2, rometadataresolution};
+use crate::metadata::declarations::class_declaration::ClassDeclaration;
+use crate::metadata::declarations::declaration::Declaration;
+use crate::metadata::declarations::delegate_declaration::DelegateDeclaration;
+use crate::metadata::declarations::delegate_declaration::generic_delegate_declaration::GenericDelegateDeclaration;
+use crate::metadata::declarations::enum_declaration::EnumDeclaration;
+use crate::metadata::declarations::interface_declaration::generic_interface_declaration::GenericInterfaceDeclaration;
+use crate::metadata::declarations::namespace_declaration::NamespaceDeclaration;
+use crate::metadata::declarations::struct_declaration::StructDeclaration;
+use crate::prelude::*;
+use crate::metadata::declarations::interface_declaration::InterfaceDeclaration;
+
+const WINDOWS: &str = "Windows";
+const SYSTEM_ENUM: &str = "System.Enum";
+const SYSTEM_VALUETYPE: &str = "System.ValueType";
+const SYSTEM_MULTICASTDELEGATE: &str = "System.MulticastDelegate";
+
+#[derive(Debug)]
+pub struct MetadataReader {}
+
+impl MetadataReader {
+ pub fn find_by_name_w(full_name: PCWSTR) -> Option>> {
+ let mut count = 0;
+ helpers::to_string_length(full_name, &mut count);
+ let slice = unsafe { std::slice::from_raw_parts(full_name, count) };
+ let name = OsString::from_wide(slice).to_string_lossy();
+ MetadataReader::find_by_name(name.as_ref())
+ }
+ pub fn find_by_name(full_name: &str) -> Option>> {
+ if full_name.is_empty() {
+ return Some(
+ Arc::new(
+ RwLock::new(NamespaceDeclaration::new(""))
+ )
+ );
+ }
+ let mut metadata = unsafe { std::mem::MaybeUninit::uninit() };
+ let meta = &mut metadata.as_mut_ptr() as *mut *mut c_void;
+ let mut token = mdTokenNil;
+ let mut full_name_hstring = HSTRING::from(full_name);
+ let get_metadata_file_result = rometadataresolution::ro_get_meta_data_file(
+ &mut full_name_hstring, None, None, Some(meta), Some(&mut token),
+ );
+
+ if get_metadata_file_result.is_err() {
+ if get_metadata_file_result == windows::HRESULT::from_win32(RO_E_METADATA_NAME_IS_NAMESPACE as u32) {
+ return Some(
+ Arc::new(
+ RwLock::new(NamespaceDeclaration::new(full_name))
+ )
+ );
+ }
+ return None;
+ }
+
+ let mut metadata = unsafe { metadata.assume_init() };
+
+ let mut flags = 0;
+ let mut parent_token = mdTokenNil;
+ {
+ let result = imeta_data_import2::get_type_def_props(
+ &mut metadata, token, None, None, None, Some(&mut flags), Some(&mut parent_token),
+ );
+ debug_assert!(result.is_ok());
+ }
+
+
+ if helpers::is_td_class(flags) {
+ let mut parent_name = [0_u16; MAX_IDENTIFIER_LENGTH];
+
+ match CorTokenType::from(enums::type_from_token(parent_token)) {
+ CorTokenType::mdtTypeDef => {
+ let result = imeta_data_import2::get_type_def_props(
+ &mut metadata, parent_token, Some(&mut parent_name), Some(parent_name.len() as u32),
+ None, None, None,
+ );
+ debug_assert!(
+ result.is_ok()
+ );
+ }
+ CorTokenType::mdtTypeRef => {
+ let result = imeta_data_import2::get_type_ref_props(
+ &mut metadata, parent_token, None, Some(&mut parent_name), Some(parent_name.len() as u32), None,
+ );
+ debug_assert!(
+ result.is_ok()
+ );
+ }
+ _ => {
+ core_unreachable()
+ }
+ }
+
+ let mut parent_name_string = OsString::from_wide(&parent_name).to_string_lossy().as_ref();
+ let metadata = unsafe {
+ Arc::new(
+ RwLock::new(
+ metadata
+ )
+ )
+ };
+ if parent_name_string == SYSTEM_ENUM {
+ return Some(
+ Arc::new(
+ RwLock::new(EnumDeclaration::new(Some(metadata), token))
+ )
+ );
+ }
+
+ if parent_name_string == SYSTEM_VALUETYPE {
+ return Some(
+ Arc::new(
+ RwLock::new(StructDeclaration::new(Some(metadata), token))
+ )
+ );
+ }
+
+ if parent_name_string == SYSTEM_MULTICASTDELEGATE {
+ return if full_name.contains("`") {
+ Some(
+ Arc::new(
+ RwLock::new(GenericDelegateDeclaration::new(Some(metadata), token))
+ )
+ )
+ } else {
+ Some(
+ Arc::new(
+ RwLock::new(DelegateDeclaration::new(Some(metadata), token))
+ )
+ )
+ }
+ }
+
+ return Some(
+ Arc::new(
+ RwLock::new(ClassDeclaration::new(Some(metadata), token))
+ )
+ );
+ }
+
+ if helpers::is_td_interface(flags) {
+ let metadata = unsafe {
+ Arc::new(
+ RwLock::new(
+ metadata
+ )
+ )
+ };
+ return if full_name.contains("`") {
+ Some(
+ Arc::new(
+ RwLock::new(GenericInterfaceDeclaration::new(metadata, token))
+ )
+ )
+ } else {
+ Some(
+ Arc::new(
+ Mutex::new(InterfaceDeclaration::new(metadata, token))
+ )
+ )
+ };
+ }
+
+ std::unreachable!();
+ }
+}
\ No newline at end of file
diff --git a/core/src/metadata/mod.rs b/core/src/metadata/mod.rs
new file mode 100755
index 0000000..21c064e
--- /dev/null
+++ b/core/src/metadata/mod.rs
@@ -0,0 +1,7 @@
+pub mod com_helpers;
+pub mod declarations;
+pub mod signature;
+pub mod declaration_factory;
+pub mod generic_instance_id_builder;
+pub mod meta_data_reader;
+pub mod declaring_interface_for_method;
diff --git a/core/src/metadata/signature.rs b/core/src/metadata/signature.rs
new file mode 100644
index 0000000..10b2c37
--- /dev/null
+++ b/core/src/metadata/signature.rs
@@ -0,0 +1,160 @@
+#![allow(non_upper_case_globals)]
+
+use crate::bindings::helpers;
+use crate::prelude::*;
+use std::borrow::Cow;
+
+const Guid: &str = "Guid";
+
+#[derive(Debug)]
+pub struct Signature {}
+
+impl Signature {
+ pub fn consume_type(signature: PCCOR_SIGNATURE) -> PCCOR_SIGNATURE {
+ let start = signature;
+ let element_type = helpers::cor_sig_uncompress_element_type(signature);
+ use crate::enums::CorElementType;
+ match element_type {
+ CorElementType::ElementTypeVoid
+ | CorElementType::ElementTypeBoolean
+ | CorElementType::ElementTypeChar
+ | CorElementType::ElementTypeI1
+ | CorElementType::ElementTypeU1
+ | CorElementType::ElementTypeI2
+ | CorElementType::ElementTypeU2
+ | CorElementType::ElementTypeI4
+ | CorElementType::ElementTypeU4
+ | CorElementType::ElementTypeI8
+ | CorElementType::ElementTypeU8
+ | CorElementType::ElementTypeR4
+ | CorElementType::ElementTypeR8
+ | CorElementType::ElementTypeString => start,
+ CorElementType::ElementTypeValuetype => {
+ helpers::cor_sig_uncompress_token(signature);
+ start
+ }
+ CorElementType::ElementTypeClass => {
+ helpers::cor_sig_uncompress_token(signature);
+ start
+ }
+ CorElementType::ElementTypeObject => start,
+ CorElementType::ElementTypeSzarray => {
+ Signature::consume_type(signature);
+ start
+ }
+ CorElementType::ElementTypeVar => {
+ helpers::cor_sig_uncompress_data(signature);
+ start
+ }
+ CorElementType::ElementTypeGenericinst => {
+ helpers::cor_sig_uncompress_element_type(signature);
+ helpers::cor_sig_uncompress_token(signature);
+
+ let generic_arguments_count = helpers::cor_sig_uncompress_data(signature);
+ for i in 0..generic_arguments_count {
+ Signature::consume_type(signature);
+ }
+ start
+ }
+ CorElementType::ElementTypeByref => {
+ Signature::consume_type(signature);
+ start
+ }
+ _ => {
+ std::unreachable!()
+ }
+ }
+ }
+
+ pub fn to_string<'a>(metadata: &IMetaDataImport2, signature: PCCOR_SIGNATURE) -> Cow<'a, str> {
+ let element_type = helpers::cor_sig_uncompress_element_type(signature);
+ return match element_type {
+ CorElementType::ElementTypeVoid => "Void".into(),
+ CorElementType::ElementTypeBoolean => "Boolean".into(),
+ CorElementType::ElementTypeChar => "Char16".into(),
+ CorElementType::ElementTypeI1 => "Int8".into(),
+ CorElementType::ElementTypeU1 => "UInt8".into(),
+ CorElementType::ElementTypeI2 => "Int16".into(),
+ CorElementType::ElementTypeU2 => "UInt16".into(),
+ CorElementType::ElementTypeI4 => "Int32".into(),
+ CorElementType::ElementTypeU4 => "UInt32".into(),
+ CorElementType::ElementTypeI8 => "Int64".into(),
+ CorElementType::ElementTypeU8 => "UInt64".into(),
+ CorElementType::ElementTypeR4 => "Single".into(),
+ CorElementType::ElementTypeR8 => "Double".into(),
+ CorElementType::ElementTypeString => "String".into(),
+ CorElementType::ElementTypeValuetype => {
+ let token = helpers::cor_sig_uncompress_token(signature);
+ let mut class_name_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let length = helpers::get_type_name(metadata, token, &mut class_name_data);
+
+ let class_name = OsString::from_wide(&class_name_data[..length as usize])
+ .to_string_lossy()
+ .as_ref();
+ if class_name.eq("System.Guid") {
+ Guid.into()
+ } else {
+ class_name.into()
+ }
+ }
+ CorElementType::ElementTypeClass => {
+ let token = helpers::cor_sig_uncompress_token(signature);
+ let mut class_name_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let length = helpers::get_type_name(metadata, token, &mut class_name_data);
+ OsString::from_wide(&class_name_data[..length as usize]).to_string_lossy()
+ }
+ CorElementType::ElementTypeObject => "Object".into(),
+ CorElementType::ElementTypeSzarray => {
+ let result = Signature::to_string(metadata, signature);
+ (result.to_owned() + "[]").into()
+ }
+ CorElementType::ElementTypeVar => {
+ let index = helpers::cor_sig_uncompress_data(signature);
+ let mut result_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let length = helpers::to_wstring(index, &mut result_data);
+ ("Var!".to_owned()
+ + OsString::from_wide(&result_data[..length as usize])
+ .to_string_lossy()
+ .as_ref())
+ .into()
+ }
+ CorElementType::ElementTypeGenericinst => {
+ let generic_type = helpers::cor_sig_uncompress_element_type(signature);
+ debug_assert!(generic_type == CorElementType::ElementTypeClass);
+
+ let token = helpers::cor_sig_uncompress_token(signature);
+
+ let mut class_name_data = [0_u16; MAX_IDENTIFIER_LENGTH];
+ let length = helpers::get_type_name(metadata, token, &mut class_name_data);
+
+ let mut result =
+ OsString::from_wide(&class_name_data[..length as usize]).to_string_lossy();
+
+ result += "<";
+
+ let generic_arguments_count = helpers::cor_sig_uncompress_data(signature);
+ for i in 0..generic_arguments_count {
+ let sig_type = Signature::consume_type(signature);
+ let data = Signature::to_string(metadata, sig_type);
+ result += data.as_ref();
+ if i == generic_arguments_count - 1 {
+ result += ", ";
+ }
+ }
+
+ result += ">";
+
+ result.into()
+ }
+ CorElementType::ElementTypeByref => {
+ let mut result = "ByRef ".to_owned();
+ result += Signature::to_string(metadata, signature).as_ref();
+ result.into()
+ }
+ _ => {
+ core_unreachable();
+ Cow::default()
+ }
+ };
+ }
+}
diff --git a/core/src/prelude.rs b/core/src/prelude.rs
new file mode 100644
index 0000000..01bbe35
--- /dev/null
+++ b/core/src/prelude.rs
@@ -0,0 +1,97 @@
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+pub use libc::wchar_t;
+pub use std::ffi::OsString;
+pub use std::os::raw::{c_long, c_uint, c_void};
+pub use std::os::windows::ffi::*;
+
+pub use super::enums::*;
+pub use core_bindings::{
+ mdCustomAttribute, mdEvent, mdFieldDef, mdGenericParam, mdInterfaceImpl, mdMemberRef,
+ mdMethodDef, mdParamDef, mdProperty, mdToken, mdTypeDef, mdTypeRef, mdTypeSpec,
+ IMetaDataImport2 as IMetaDataImport2_, BYTE, DWORD, HCORENUM, LPCWSTR, LPWSTR, PCCOR_SIGNATURE,
+ ULONG, ULONG32, UVCP_CONSTANT,
+};
+use core_bindings::{
+ Helpers_RO_E_METADATA_NAME_IS_NAMESPACE, Helpers_mdAssemblyNil, Helpers_mdAssemblyRefNil,
+ Helpers_mdCustomAttributeNil, Helpers_mdEventNil, Helpers_mdExportedTypeNil,
+ Helpers_mdFieldDefNil, Helpers_mdFileNil, Helpers_mdGenericParamConstraintNil,
+ Helpers_mdGenericParamNil, Helpers_mdInterfaceImplNil, Helpers_mdManifestResourceNil,
+ Helpers_mdMemberRefNil, Helpers_mdMethodDefNil, Helpers_mdMethodSpecNil, Helpers_mdModuleNil,
+ Helpers_mdModuleRefNil, Helpers_mdParamDefNil, Helpers_mdPermissionNil, Helpers_mdPropertyNil,
+ Helpers_mdSignatureNil, Helpers_mdStringNil, Helpers_mdTokenNil, Helpers_mdTypeDefNil,
+ Helpers_mdTypeRefNil, Helpers_mdTypeSpecNil, GUID, HRESULT,
+};
+
+use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard, TryLockError};
+
+pub const mdTokenNil: mdToken = Helpers_mdTokenNil;
+pub const mdModuleNil: mdToken = Helpers_mdModuleNil;
+pub const mdTypeRefNil: mdToken = Helpers_mdTypeRefNil;
+pub const mdTypeDefNil: mdToken = Helpers_mdTypeDefNil;
+pub const mdFieldDefNil: mdToken = Helpers_mdFieldDefNil;
+pub const mdMethodDefNil: mdToken = Helpers_mdMethodDefNil;
+pub const mdParamDefNil: mdToken = Helpers_mdParamDefNil;
+pub const mdInterfaceImplNil: mdToken = Helpers_mdInterfaceImplNil;
+pub const mdMemberRefNil: mdToken = Helpers_mdMemberRefNil;
+pub const mdCustomAttributeNil: mdToken = Helpers_mdCustomAttributeNil;
+pub const mdPermissionNil: mdToken = Helpers_mdPermissionNil;
+pub const mdSignatureNil: mdToken = Helpers_mdSignatureNil;
+pub const mdEventNil: mdToken = Helpers_mdEventNil;
+pub const mdPropertyNil: mdToken = Helpers_mdPropertyNil;
+pub const mdModuleRefNil: mdToken = Helpers_mdModuleRefNil;
+pub const mdTypeSpecNil: mdToken = Helpers_mdTypeSpecNil;
+pub const mdAssemblyNil: mdToken = Helpers_mdAssemblyNil;
+pub const mdAssemblyRefNil: mdToken = Helpers_mdAssemblyRefNil;
+pub const mdFileNil: mdToken = Helpers_mdFileNil;
+pub const mdExportedTypeNil: mdToken = Helpers_mdExportedTypeNil;
+pub const mdManifestResourceNil: mdToken = Helpers_mdManifestResourceNil;
+pub const mdGenericParamNil: mdToken = Helpers_mdGenericParamNil;
+pub const mdGenericParamConstraintNil: mdToken = Helpers_mdGenericParamConstraintNil;
+pub const mdMethodSpecNil: mdToken = Helpers_mdMethodSpecNil;
+pub const mdStringNil: mdToken = Helpers_mdStringNil;
+
+pub type CLSID = GUID;
+
+pub const RO_E_METADATA_NAME_IS_NAMESPACE: HRESULT = Helpers_RO_E_METADATA_NAME_IS_NAMESPACE;
+
+pub const MAX_IDENTIFIER_LENGTH: usize = 511;
+
+pub const COR_CTOR_METHOD_NAME: &str = ".ctor";
+pub const COR_CCTOR_METHOD_NAME: &str = ".cctor";
+pub const COR_ENUM_FIELD_NAME: &str = "value__";
+
+pub fn get_lock_value<'a, T>(value: &Option>>) -> Option<&T> {
+ match Option::as_ref(&value) {
+ None => None,
+ Some(value) => match value.try_read() {
+ Ok(value) => Some(&*value),
+ Err(_) => None,
+ },
+ }
+}
+
+pub fn get_mutex_value_mut<'a, T>(value: &Option>>) -> Option<&mut T> {
+ match Option::as_ref(&value) {
+ None => None,
+ Some(value) => match value.try_write() {
+ Ok(value) => Some(&mut *value),
+ Err(_) => None,
+ },
+ }
+}
+
+#[cfg(debug_assertions)]
+pub fn core_unreachable() {
+ std::unreachable!()
+}
+
+
+#[cfg(debug_assertions)]
+pub fn core_unimplemented() {
+ std::unimplemented!()
+}
+
+pub use crate::bindings::imeta_data_import2::*;
diff --git a/core/src/runtime/com/com_constructor.rs b/core/src/runtime/com/com_constructor.rs
new file mode 100644
index 0000000..3fb7142
--- /dev/null
+++ b/core/src/runtime/com/com_constructor.rs
@@ -0,0 +1,17 @@
+use crate::prelude::*;
+use crate::metadata::declaring_interface_for_method::Metadata;
+
+
+#[derive(Debug)]
+pub struct COMConstructor {}
+
+#[derive(Debug)]
+pub struct COMConstructorCall {
+ initialization: Initialization,
+}
+
+impl COMConstructorCall {
+ pub fn new() -> Self {
+ Metadata::find_declaring_interface_for_method()
+ }
+}
\ No newline at end of file
diff --git a/core/src/runtime/com/com_interop.rs b/core/src/runtime/com/com_interop.rs
new file mode 100644
index 0000000..f51f7d8
--- /dev/null
+++ b/core/src/runtime/com/com_interop.rs
@@ -0,0 +1,24 @@
+use crate::metadata::meta_data_reader::MetadataReader;
+use crate::prelude::{ get_lock_value};
+
+#[derive(Debug)]
+pub struct COMInterop {}
+
+impl COMInterop {
+ pub fn new() -> Self {
+ Self {}
+ }
+ pub fn resolve_type(type_name: &str) {
+ let decl = MetadataReader::find_by_name(type_name);
+ println!("{:?}",decl);
+ /*if let Some(decl) = decl {
+ if let Some(decl) = decl.try_read() {
+
+ }
+ decl.try_read().unwrap()
+ let val = get_lock_value(decl);
+ val.kind()
+ }
+ */
+ }
+}
\ No newline at end of file
diff --git a/core/src/runtime/com/com_method_call.rs b/core/src/runtime/com/com_method_call.rs
new file mode 100644
index 0000000..9a80a62
--- /dev/null
+++ b/core/src/runtime/com/com_method_call.rs
@@ -0,0 +1,2 @@
+#[derive(Debug)]
+pub struct COMMethodCall {}
\ No newline at end of file
diff --git a/core/src/runtime/com/com_object_wrapper.rs b/core/src/runtime/com/com_object_wrapper.rs
new file mode 100644
index 0000000..44d390e
--- /dev/null
+++ b/core/src/runtime/com/com_object_wrapper.rs
@@ -0,0 +1,2 @@
+#[derive(Debug)]
+pub struct COMObjectWrapper {}
\ No newline at end of file
diff --git a/core/src/runtime/com/com_unknown_type.rs b/core/src/runtime/com/com_unknown_type.rs
new file mode 100644
index 0000000..d7ec009
--- /dev/null
+++ b/core/src/runtime/com/com_unknown_type.rs
@@ -0,0 +1,2 @@
+#[derive(Debug)]
+pub struct COMUnknownType {}
\ No newline at end of file
diff --git a/core/src/runtime/com/mod.rs b/core/src/runtime/com/mod.rs
new file mode 100644
index 0000000..2b084b4
--- /dev/null
+++ b/core/src/runtime/com/mod.rs
@@ -0,0 +1,5 @@
+pub mod com_interop;
+pub mod com_constructor;
+pub mod com_unknown_type;
+pub mod com_method_call;
+pub mod com_object_wrapper;
\ No newline at end of file
diff --git a/core/src/runtime/console.rs b/core/src/runtime/console.rs
new file mode 100755
index 0000000..4d44ffc
--- /dev/null
+++ b/core/src/runtime/console.rs
@@ -0,0 +1,48 @@
+use rusty_v8 as v8;
+use core_bindings::{Windows::Win32::System::Console, Windows::Win32::System::WindowsProgramming};
+use std::ffi::{CString, c_void};
+
+pub(crate) fn handle_console_log(scope: &mut v8::HandleScope, args: v8::FunctionCallbackArguments, _retval: v8::ReturnValue) {
+ let mut value = String::new();
+ for i in 0..args.length() {
+ let item = args.get(i).to_rust_string_lossy(scope);
+ if i == args.length() - 1 {
+ value.push_str(&item)
+ } else {
+ value.push_str(&item);
+ value.push_str(",")
+ }
+ if i == args.length() - 1 {
+ value.push_str("\n");
+ }
+ }
+
+ let length = value.chars().count() as u32;
+ let handle = unsafe { WindowsProgramming::GetStdHandle(WindowsProgramming::STD_OUTPUT_HANDLE) };
+ let string = CString::new(value).unwrap();
+ let mut written = 0_u32;
+ unsafe {
+ Console::WriteConsoleA(handle, string.as_ptr() as *const c_void, length, &mut written, std::ptr::null() as _);
+ }
+}
+
+pub(crate) fn handle_console_dir(scope: &mut v8::HandleScope, args: v8::FunctionCallbackArguments, _retval: v8::ReturnValue) {
+ let mut value = String::new();
+ for i in 0..args.length() {
+ let item = args.get(i).to_rust_string_lossy(scope);
+ if i == args.length() - 1 {
+ value.push_str(&item)
+ } else {
+ value.push_str(&item);
+ value.push_str(",")
+ }
+ }
+ let length = value.chars().count() as u32;
+ let handle = unsafe { WindowsProgramming::GetStdHandle(WindowsProgramming::STD_OUTPUT_HANDLE) };
+
+ let string = CString::new(value).unwrap();
+ let mut written = 0_u32;
+ unsafe {
+ Console::WriteConsoleA(handle, string.as_ptr() as *const c_void, length, &mut written, std::ptr::null());
+ }
+}
\ No newline at end of file
diff --git a/core/src/runtime/ffi/ff_boolean_type.rs b/core/src/runtime/ffi/ff_boolean_type.rs
new file mode 100644
index 0000000..aa3e47d
--- /dev/null
+++ b/core/src/runtime/ffi/ff_boolean_type.rs
@@ -0,0 +1,2 @@
+#[derive(Debug)]
+pub struct FFIBooleanType {}
\ No newline at end of file
diff --git a/core/src/runtime/ffi/ffi_interop.rs b/core/src/runtime/ffi/ffi_interop.rs
new file mode 100644
index 0000000..1d0bbc7
--- /dev/null
+++ b/core/src/runtime/ffi/ffi_interop.rs
@@ -0,0 +1,2 @@
+#[derive(Debug)]
+pub struct FFIInterop {}
\ No newline at end of file
diff --git a/core/src/runtime/ffi/ffi_number_type.rs b/core/src/runtime/ffi/ffi_number_type.rs
new file mode 100644
index 0000000..10a87a4
--- /dev/null
+++ b/core/src/runtime/ffi/ffi_number_type.rs
@@ -0,0 +1,2 @@
+#[derive(Debug)]
+pub struct FFINumberType {}
\ No newline at end of file
diff --git a/core/src/runtime/ffi/ffi_void_type.rs b/core/src/runtime/ffi/ffi_void_type.rs
new file mode 100644
index 0000000..fc4d3ae
--- /dev/null
+++ b/core/src/runtime/ffi/ffi_void_type.rs
@@ -0,0 +1,2 @@
+#[derive(Debug)]
+pub struct FFIVoidType {}
\ No newline at end of file
diff --git a/core/src/runtime/ffi/mod.rs b/core/src/runtime/ffi/mod.rs
new file mode 100755
index 0000000..202dfc0
--- /dev/null
+++ b/core/src/runtime/ffi/mod.rs
@@ -0,0 +1,4 @@
+pub mod ffi_interop;
+pub mod ff_boolean_type;
+pub mod ffi_number_type;
+pub mod ffi_void_type;
\ No newline at end of file
diff --git a/core/src/runtime/global.rs b/core/src/runtime/global.rs
new file mode 100755
index 0000000..e69de29
diff --git a/core/src/runtime/mod.rs b/core/src/runtime/mod.rs
new file mode 100755
index 0000000..5151836
--- /dev/null
+++ b/core/src/runtime/mod.rs
@@ -0,0 +1,232 @@
+mod global;
+mod ffi;
+mod console;
+mod com;
+
+use rusty_v8 as v8;
+use std::ffi::{CString, CStr, c_void, OsStr, OsString};
+use std::os::raw::{c_char, c_uint, c_long};
+use std::io::Read;
+use std::os::windows::prelude::*;
+use std::path::{Path, PathBuf};
+use windows::HSTRING;
+use crate::runtime::com::com_interop::COMInterop;
+use rusty_v8::{Value, Local, Handle};
+use std::convert::TryInto;
+
+pub struct Runtime {
+ isolate: v8::OwnedIsolate,
+ global_context: v8::Global,
+ app_root: String,
+}
+
+
+const MAX_IDENTIFIER_LENGTH: usize = 511;
+
+
+impl Runtime {
+ pub fn new(app_root: &str) -> Self {
+ let platform = v8::new_default_platform().unwrap();
+ v8::V8::initialize_platform(platform);
+ v8::V8::initialize();
+ let mut isolate = v8::Isolate::new(Default::default());
+
+ isolate.set_capture_stack_trace_for_uncaught_exceptions(true, 100);
+
+ let global_context;
+ {
+ let mut scope = &mut v8::HandleScope::new(&mut isolate);
+ let mut global = v8::FunctionTemplate::new(scope, Runtime::handle_global);
+
+ {
+ let class_name = v8::String::new(scope, "NativeScriptGlobalObject").unwrap();
+ global.set_class_name(class_name);
+ }
+
+ let mut global_template = v8::ObjectTemplate::new_from_template(scope, global);
+
+ global_template.set_internal_field_count(0);
+
+ {
+ {
+ Runtime::init_performance(scope, &mut global_template);
+ }
+
+ {
+ Runtime::init_time(scope, &mut global_template);
+ }
+
+
+ let mut context = v8::Context::new_from_template(scope, global_template);
+
+ let mut local_scope = v8::ContextScope::new(scope, context);
+
+ {
+ Runtime::init_global(&mut local_scope, context);
+ }
+
+ {
+ Runtime::init_console(&mut local_scope, context);
+ }
+
+ {
+ Runtime::init_meta(&mut local_scope, context);
+ }
+
+ {
+ global_context = v8::Global::new(&mut local_scope, context);
+ }
+ }
+ }
+
+ Self {
+ isolate,
+ global_context,
+ app_root: app_root.to_string(),
+ }
+ }
+
+ fn run_script(&mut self, script: &str) {
+ /*
+ let path = PathBuf::from(script);
+ println!("??? {:?}", path.to_string_lossy());
+ let mut file = std::fs::File::open(std::fs::canonicalize(&path).unwrap()).unwrap();
+ let mut data = Vec::new();
+ file.read_to_end(&mut data);
+ let script = String::from_utf8_lossy(data.as_slice());
+ */
+
+ let mut isolate = &mut self.isolate;
+ let mut scope = &mut v8::HandleScope::new(isolate);
+ let mut local = v8::Local::new(scope, &self.global_context);
+ let mut scope = &mut v8::ContextScope::new(scope, local);
+ let code = v8::String::new(scope, script).unwrap();
+ let script = v8::Script::compile(&mut scope, code, None).unwrap();
+ let result = script.run(&mut scope).unwrap();
+ let result = result.to_string(&mut scope).unwrap();
+ }
+
+ fn handle_global(_scope: &mut v8::HandleScope, _args: v8::FunctionCallbackArguments, _retval: v8::ReturnValue) {}
+
+ fn init_global(scope: &mut v8::ContextScope>, context: v8::Local) {
+ let mut global = context.global(scope);
+ let value = v8::String::new(
+ scope, "global",
+ ).unwrap().into();
+ global.define_own_property(scope, value, global.into(), v8::READ_ONLY);
+ let interop = Box::new(COMInterop::new());
+ let interop = Box::into_raw(interop);
+ let value = v8::External::new(scope, interop as *mut c_void);
+ global.set_internal_field(0, value.into());
+ }
+
+ fn init_console(scope: &mut v8::ContextScope>, context: v8::Local) {
+ let console = v8::Object::new(scope);
+ let log = v8::Function::new(scope, console::handle_console_log).unwrap();
+ let dir = v8::Function::new(scope, console::handle_console_dir).unwrap();
+
+ {
+ let name = v8::String::new(scope, "log").unwrap().into();
+ console.set(
+ scope,
+ name,
+ log.into(),
+ );
+ }
+
+ {
+ let name = v8::String::new(scope, "dir").unwrap().into();
+ console.set(
+ scope,
+ name,
+ dir.into(),
+ );
+ }
+
+ let mut global = context.global(scope);
+ let value = v8::String::new(
+ scope, "console",
+ ).unwrap().into();
+ global.define_own_property(scope, value, console.into(), v8::READ_ONLY);
+ }
+
+ fn handle_time(scope: &mut v8::HandleScope,
+ _args: v8::FunctionCallbackArguments,
+ mut retval: v8::ReturnValue) {
+ let now = chrono::Utc::now();
+ retval.set(
+ v8::Number::new(scope, (now.timestamp_millis() / 1000000) as f64).into()
+ )
+ }
+
+ fn init_time(scope: &mut v8::HandleScope<()>, global: &mut v8::Local) {
+ let time = v8::FunctionTemplate::new(scope, Runtime::handle_time);
+ global.set(
+ v8::String::new(scope, "time").unwrap().into(), time.into(),
+ );
+ }
+
+ fn init_performance(scope: &mut v8::HandleScope<()>, global: &mut v8::Local) {
+ let performance = v8::ObjectTemplate::new(scope);
+ let now = v8::FunctionTemplate::new(scope, Runtime::handle_now);
+ performance.set(
+ v8::String::new(scope, "now").unwrap().into(),
+ now.into(),
+ );
+ global.set(
+ v8::String::new(scope, "performance").unwrap().into(),
+ performance.into(),
+ );
+ }
+
+ fn handle_now(scope: &mut v8::HandleScope,
+ _args: v8::FunctionCallbackArguments,
+ mut retval: v8::ReturnValue) {
+ let now = chrono::Utc::now();
+ retval.set(
+ v8::Number::new(scope, now.timestamp_nanos() as f64).into()
+ )
+ }
+
+ fn init_meta(scope: &mut v8::ContextScope>, context: v8::Local) {
+ let meta = v8::Function::new(scope, Runtime::handle_meta).unwrap();
+ let mut global = context.global(scope);
+ let value = v8::String::new(
+ scope, "$",
+ ).unwrap().into();
+ global.define_own_property(scope, value, meta.into(), v8::READ_ONLY);
+ }
+
+ fn handle_meta(scope: &mut v8::HandleScope,
+ args: v8::FunctionCallbackArguments,
+ mut retval: v8::ReturnValue) {
+ println!("handle meta {:?}", args.get(0).to_rust_string_lossy(scope));
+ let isolate = scope.get_isolate_mut();
+ let class_name = args.get(0).to_rust_string_lossy(scope);
+ let global = scope.get_current_context().global(scope);
+ match global.get_internal_field(scope, 0) {
+ None => {}
+ Some(value) => {
+ let interop: v8::External = value.try_into().unwrap();
+ let interop = interop.value() as *mut COMInterop;
+ }
+ }
+ }
+}
+
+
+#[no_mangle]
+pub extern fn runtime_init(main_entry: *const c_char) -> i64 {
+ let string = unsafe { CStr::from_ptr(main_entry) }.to_string_lossy();
+ Box::into_raw(Box::new(Runtime::new(string.as_ref()))) as i64
+}
+
+#[no_mangle]
+pub extern fn runtime_runscript(runtime: i64, script: *const c_char) {
+ if runtime != 0 {
+ let mut runtime: *mut Runtime = runtime as _;
+ let mut runtime = unsafe { &mut *runtime };
+ let script = unsafe { CStr::from_ptr(script) }.to_string_lossy();
+ runtime.run_script(script.as_ref());
+ }
+}
\ No newline at end of file