diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj b/Dalamud.Boot/Dalamud.Boot.vcxproj index 298edbcbc..2a0c6db83 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj @@ -58,8 +58,8 @@ Windows true false - Version.lib;Shlwapi.lib;%(AdditionalDependencies) - ..\lib\CoreCLR;%(AdditionalLibraryDirectories) + Version.lib;Shlwapi.lib;nethost.lib;%(AdditionalDependencies) + ..\lib\CoreCLR\nethost;%(AdditionalLibraryDirectories) diff --git a/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj b/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj index c293e258c..933e468c7 100644 --- a/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj +++ b/Dalamud.Injector.Boot/Dalamud.Injector.Boot.vcxproj @@ -48,7 +48,7 @@ Console true false - ..\lib\CoreCLR;%(AdditionalLibraryDirectories) + ..\lib\CoreCLR\nethost;%(AdditionalLibraryDirectories) $(OutDir)$(TargetName).Boot.pdb @@ -61,6 +61,7 @@ false false + nethost.lib;%(AdditionalDependencies) @@ -107,4 +108,4 @@ - \ No newline at end of file + diff --git a/lib/CoreCLR/.ver b/lib/CoreCLR/.ver new file mode 100644 index 000000000..60b9d82f5 --- /dev/null +++ b/lib/CoreCLR/.ver @@ -0,0 +1 @@ +Microsoft.NETCore.App.Host.win-x64\8.0.7 \ No newline at end of file diff --git a/lib/CoreCLR/CoreCLR.cpp b/lib/CoreCLR/CoreCLR.cpp index e4a62eeba..72f3d0f91 100644 --- a/lib/CoreCLR/CoreCLR.cpp +++ b/lib/CoreCLR/CoreCLR.cpp @@ -20,6 +20,7 @@ int CoreCLR::load_hostfxr() int CoreCLR::load_hostfxr(const struct get_hostfxr_parameters* parameters) { + /* // Get the path to CoreCLR's hostfxr std::wstring calling_module_path(MAX_PATH, L'\0'); @@ -41,6 +42,7 @@ int CoreCLR::load_hostfxr(const struct get_hostfxr_parameters* parameters) get_export(lib_nethost, "get_hostfxr_path")); if (!get_hostfxr_path) return -1; + */ wchar_t buffer[MAX_PATH]{}; size_t buffer_size = sizeof buffer / sizeof(wchar_t); diff --git a/lib/CoreCLR/core/coreclr_delegates.h b/lib/CoreCLR/core/coreclr_delegates.h index 20c1221bd..550badf13 100644 --- a/lib/CoreCLR/core/coreclr_delegates.h +++ b/lib/CoreCLR/core/coreclr_delegates.h @@ -21,27 +21,40 @@ #define UNMANAGEDCALLERSONLY_METHOD ((const char_t*)-1) // Signature of delegate returned by coreclr_delegate_type::load_assembly_and_get_function_pointer -typedef int (CORECLR_DELEGATE_CALLTYPE* load_assembly_and_get_function_pointer_fn)( - const char_t* assembly_path /* Fully qualified path to assembly */, - const char_t* type_name /* Assembly qualified type name */, - const char_t* method_name /* Public static method name compatible with delegateType */, - const char_t* delegate_type_name /* Assembly qualified delegate type name or null +typedef int (CORECLR_DELEGATE_CALLTYPE *load_assembly_and_get_function_pointer_fn)( + const char_t *assembly_path /* Fully qualified path to assembly */, + const char_t *type_name /* Assembly qualified type name */, + const char_t *method_name /* Public static method name compatible with delegateType */, + const char_t *delegate_type_name /* Assembly qualified delegate type name or null or UNMANAGEDCALLERSONLY_METHOD if the method is marked with the UnmanagedCallersOnlyAttribute. */, - void* reserved /* Extensibility parameter (currently unused and must be 0) */, - /*out*/ void** delegate /* Pointer where to store the function pointer result */); + void *reserved /* Extensibility parameter (currently unused and must be 0) */, + /*out*/ void **delegate /* Pointer where to store the function pointer result */); // Signature of delegate returned by load_assembly_and_get_function_pointer_fn when delegate_type_name == null (default) -typedef int (CORECLR_DELEGATE_CALLTYPE* component_entry_point_fn)(void* arg, int32_t arg_size_in_bytes); +typedef int (CORECLR_DELEGATE_CALLTYPE *component_entry_point_fn)(void *arg, int32_t arg_size_in_bytes); -typedef int (CORECLR_DELEGATE_CALLTYPE* get_function_pointer_fn)( - const char_t* type_name /* Assembly qualified type name */, - const char_t* method_name /* Public static method name compatible with delegateType */, - const char_t* delegate_type_name /* Assembly qualified delegate type name or null, +typedef int (CORECLR_DELEGATE_CALLTYPE *get_function_pointer_fn)( + const char_t *type_name /* Assembly qualified type name */, + const char_t *method_name /* Public static method name compatible with delegateType */, + const char_t *delegate_type_name /* Assembly qualified delegate type name or null, or UNMANAGEDCALLERSONLY_METHOD if the method is marked with the UnmanagedCallersOnlyAttribute. */, - void* load_context /* Extensibility parameter (currently unused and must be 0) */, - void* reserved /* Extensibility parameter (currently unused and must be 0) */, - /*out*/ void** delegate /* Pointer where to store the function pointer result */); + void *load_context /* Extensibility parameter (currently unused and must be 0) */, + void *reserved /* Extensibility parameter (currently unused and must be 0) */, + /*out*/ void **delegate /* Pointer where to store the function pointer result */); + +typedef int (CORECLR_DELEGATE_CALLTYPE *load_assembly_fn)( + const char_t *assembly_path /* Fully qualified path to assembly */, + void *load_context /* Extensibility parameter (currently unused and must be 0) */, + void *reserved /* Extensibility parameter (currently unused and must be 0) */); + +typedef int (CORECLR_DELEGATE_CALLTYPE *load_assembly_bytes_fn)( + const void *assembly_bytes /* Bytes of the assembly to load */, + size_t assembly_bytes_len /* Byte length of the assembly to load */, + const void *symbols_bytes /* Optional. Bytes of the symbols for the assembly */, + size_t symbols_bytes_len /* Optional. Byte length of the symbols for the assembly */, + void *load_context /* Extensibility parameter (currently unused and must be 0) */, + void *reserved /* Extensibility parameter (currently unused and must be 0) */); #endif // __CORECLR_DELEGATES_H__ diff --git a/lib/CoreCLR/core/hostfxr.h b/lib/CoreCLR/core/hostfxr.h index a0a526d90..a19636b9e 100644 --- a/lib/CoreCLR/core/hostfxr.h +++ b/lib/CoreCLR/core/hostfxr.h @@ -28,15 +28,17 @@ enum hostfxr_delegate_type hdt_com_unregister, hdt_load_assembly_and_get_function_pointer, hdt_get_function_pointer, + hdt_load_assembly, + hdt_load_assembly_bytes, }; -typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_main_fn)(const int argc, const char_t** argv); -typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_main_startupinfo_fn)( +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_main_fn)(const int argc, const char_t **argv); +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_main_startupinfo_fn)( const int argc, - const char_t** argv, - const char_t* host_path, - const char_t* dotnet_root, - const char_t* app_path); + const char_t **argv, + const char_t *host_path, + const char_t *dotnet_root, + const char_t *app_path); typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_main_bundle_startupinfo_fn)( const int argc, const char_t** argv, @@ -45,7 +47,7 @@ typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_main_bundle_startupinfo_fn)( const char_t* app_path, int64_t bundle_header_offset); -typedef void(HOSTFXR_CALLTYPE* hostfxr_error_writer_fn)(const char_t* message); +typedef void(HOSTFXR_CALLTYPE *hostfxr_error_writer_fn)(const char_t *message); // // Sets a callback which is to be used to write errors to. @@ -64,20 +66,20 @@ typedef void(HOSTFXR_CALLTYPE* hostfxr_error_writer_fn)(const char_t* message); // By default no callback is registered in which case the errors are written to stderr. // // Each call to the error writer is sort of like writing a single line (the EOL character is omitted). -// Multiple calls to the error writer may occure for one failure. +// Multiple calls to the error writer may occur for one failure. // // If the hostfxr invokes functions in hostpolicy as part of its operation, the error writer // will be propagated to hostpolicy for the duration of the call. This means that errors from // both hostfxr and hostpolicy will be reporter through the same error writer. // -typedef hostfxr_error_writer_fn(HOSTFXR_CALLTYPE* hostfxr_set_error_writer_fn)(hostfxr_error_writer_fn error_writer); +typedef hostfxr_error_writer_fn(HOSTFXR_CALLTYPE *hostfxr_set_error_writer_fn)(hostfxr_error_writer_fn error_writer); typedef void* hostfxr_handle; struct hostfxr_initialize_parameters { size_t size; - const char_t* host_path; - const char_t* dotnet_root; + const char_t *host_path; + const char_t *dotnet_root; }; // @@ -88,6 +90,8 @@ struct hostfxr_initialize_parameters // Number of argv arguments // argv // Command-line arguments for running an application (as if through the dotnet executable). +// Only command-line arguments which are accepted by runtime installation are supported, SDK/CLI commands are not supported. +// For example 'app.dll app_argument_1 app_argument_2`. // parameters // Optional. Additional parameters for initialization // host_context_handle @@ -105,11 +109,11 @@ struct hostfxr_initialize_parameters // // This function does not load the runtime. // -typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_initialize_for_dotnet_command_line_fn)( +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_initialize_for_dotnet_command_line_fn)( int argc, - const char_t** argv, - const struct hostfxr_initialize_parameters* parameters, - /*out*/ hostfxr_handle* host_context_handle); + const char_t **argv, + const struct hostfxr_initialize_parameters *parameters, + /*out*/ hostfxr_handle *host_context_handle); // // Initializes the hosting components using a .runtimeconfig.json file @@ -141,10 +145,10 @@ typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_initialize_for_dotnet_command_line_fn) // initializations. In the case of Success_DifferentRuntimeProperties, it is left to the consumer to verify that // the difference in properties is acceptable. // -typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_initialize_for_runtime_config_fn)( - const char_t* runtime_config_path, - const struct hostfxr_initialize_parameters* parameters, - /*out*/ hostfxr_handle* host_context_handle); +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_initialize_for_runtime_config_fn)( + const char_t *runtime_config_path, + const struct hostfxr_initialize_parameters *parameters, + /*out*/ hostfxr_handle *host_context_handle); // // Gets the runtime property value for an initialized host context @@ -169,10 +173,10 @@ typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_initialize_for_runtime_config_fn)( // If host_context_handle is nullptr and an active host context exists, this function will get the // property value for the active host context. // -typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_get_runtime_property_value_fn)( +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_get_runtime_property_value_fn)( const hostfxr_handle host_context_handle, - const char_t* name, - /*out*/ const char_t** value); + const char_t *name, + /*out*/ const char_t **value); // // Sets the value of a runtime property for an initialized host context @@ -193,10 +197,10 @@ typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_get_runtime_property_value_fn)( // If the property already exists in the host context, it will be overwritten. If value is nullptr, the // property will be removed. // -typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_set_runtime_property_value_fn)( +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_set_runtime_property_value_fn)( const hostfxr_handle host_context_handle, - const char_t* name, - const char_t* value); + const char_t *name, + const char_t *value); // // Gets all the runtime properties for an initialized host context @@ -225,11 +229,11 @@ typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_set_runtime_property_value_fn)( // If host_context_handle is nullptr and an active host context exists, this function will get the // properties for the active host context. // -typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_get_runtime_properties_fn)( +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_get_runtime_properties_fn)( const hostfxr_handle host_context_handle, - /*inout*/ size_t* count, - /*out*/ const char_t** keys, - /*out*/ const char_t** values); + /*inout*/ size_t * count, + /*out*/ const char_t **keys, + /*out*/ const char_t **values); // // Load CoreCLR and run the application for an initialized host context @@ -245,7 +249,7 @@ typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_get_runtime_properties_fn)( // // This function will not return until the managed application exits. // -typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_run_app_fn)(const hostfxr_handle host_context_handle); +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_run_app_fn)(const hostfxr_handle host_context_handle); // // Gets a typed delegate from the currently loaded CoreCLR or from a newly created one. @@ -268,10 +272,10 @@ typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_run_app_fn)(const hostfxr_handle host_ // hdt_load_assembly_and_get_function_pointer // hdt_get_function_pointer // -typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_get_runtime_delegate_fn)( +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_get_runtime_delegate_fn)( const hostfxr_handle host_context_handle, enum hostfxr_delegate_type type, - /*out*/ void** delegate); + /*out*/ void **delegate); // // Closes an initialized host context @@ -283,6 +287,80 @@ typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_get_runtime_delegate_fn)( // Return value: // The error code result. // -typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_close_fn)(const hostfxr_handle host_context_handle); +typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_close_fn)(const hostfxr_handle host_context_handle); + +struct hostfxr_dotnet_environment_sdk_info +{ + size_t size; + const char_t* version; + const char_t* path; +}; + +typedef void(HOSTFXR_CALLTYPE* hostfxr_get_dotnet_environment_info_result_fn)( + const struct hostfxr_dotnet_environment_info* info, + void* result_context); + +struct hostfxr_dotnet_environment_framework_info +{ + size_t size; + const char_t* name; + const char_t* version; + const char_t* path; +}; + +struct hostfxr_dotnet_environment_info +{ + size_t size; + + const char_t* hostfxr_version; + const char_t* hostfxr_commit_hash; + + size_t sdk_count; + const struct hostfxr_dotnet_environment_sdk_info* sdks; + + size_t framework_count; + const struct hostfxr_dotnet_environment_framework_info* frameworks; +}; + +// +// Returns available SDKs and frameworks. +// +// Resolves the existing SDKs and frameworks from a dotnet root directory (if +// any), or the global default location. If multi-level lookup is enabled and +// the dotnet root location is different than the global location, the SDKs and +// frameworks will be enumerated from both locations. +// +// The SDKs are sorted in ascending order by version, multi-level lookup +// locations are put before private ones. +// +// The frameworks are sorted in ascending order by name followed by version, +// multi-level lookup locations are put before private ones. +// +// Parameters: +// dotnet_root +// The path to a directory containing a dotnet executable. +// +// reserved +// Reserved for future parameters. +// +// result +// Callback invoke to return the list of SDKs and frameworks. +// Structs and their elements are valid for the duration of the call. +// +// result_context +// Additional context passed to the result callback. +// +// Return value: +// 0 on success, otherwise failure. +// +// String encoding: +// Windows - UTF-16 (pal::char_t is 2 byte wchar_t) +// Unix - UTF-8 (pal::char_t is 1 byte char) +// +typedef int32_t(HOSTFXR_CALLTYPE* hostfxr_get_dotnet_environment_info_fn)( + const char_t* dotnet_root, + void* reserved, + hostfxr_get_dotnet_environment_info_result_fn result, + void* result_context); #endif //__HOSTFXR_H__ diff --git a/lib/CoreCLR/nethost/nethost.dll b/lib/CoreCLR/nethost/nethost.dll index 6673b3079..9386f0793 100644 Binary files a/lib/CoreCLR/nethost/nethost.dll and b/lib/CoreCLR/nethost/nethost.dll differ diff --git a/lib/CoreCLR/nethost/nethost.h b/lib/CoreCLR/nethost/nethost.h index aff09b286..eaca17535 100644 --- a/lib/CoreCLR/nethost/nethost.h +++ b/lib/CoreCLR/nethost/nethost.h @@ -6,6 +6,36 @@ #include +#ifdef _WIN32 + #ifdef NETHOST_EXPORT + #define NETHOST_API __declspec(dllexport) + #else + // Consuming the nethost as a static library + // Shouldn't export attempt to dllimport. + #ifdef NETHOST_USE_AS_STATIC + #define NETHOST_API + #else + #define NETHOST_API __declspec(dllimport) + #endif + #endif + + #define NETHOST_CALLTYPE __stdcall + #ifdef _WCHAR_T_DEFINED + typedef wchar_t char_t; + #else + typedef unsigned short char_t; + #endif +#else + #ifdef NETHOST_EXPORT + #define NETHOST_API __attribute__((__visibility__("default"))) + #else + #define NETHOST_API + #endif + + #define NETHOST_CALLTYPE + typedef char char_t; +#endif + #ifdef __cplusplus extern "C" { #endif @@ -17,7 +47,7 @@ extern "C" { // Size of the struct. This is used for versioning. // // assembly_path -// Path to the compenent's assembly. +// Path to the component's assembly. // If specified, hostfxr is located as if the assembly_path is the apphost // // dotnet_root @@ -47,7 +77,7 @@ struct get_hostfxr_parameters { // // get_hostfxr_parameters // Optional. Parameters that modify the behaviour for locating the hostfxr library. -// If nullptr, hostfxr is located using the enviroment variable or global registration +// If nullptr, hostfxr is located using the environment variable or global registration // // Return value: // 0 on success, otherwise failure @@ -57,10 +87,10 @@ struct get_hostfxr_parameters { // The full search for the hostfxr library is done on every call. To minimize the need // to call this function multiple times, pass a large buffer (e.g. PATH_MAX). // -using get_hostfxr_path_type = int(__stdcall *)( - char_t* buffer, - size_t* buffer_size, - const struct get_hostfxr_parameters* parameters); +NETHOST_API int NETHOST_CALLTYPE get_hostfxr_path( + char_t * buffer, + size_t * buffer_size, + const struct get_hostfxr_parameters *parameters); #ifdef __cplusplus } // extern "C" diff --git a/lib/CoreCLR/nethost/nethost.lib b/lib/CoreCLR/nethost/nethost.lib new file mode 100644 index 000000000..8c483c141 Binary files /dev/null and b/lib/CoreCLR/nethost/nethost.lib differ