diff --git a/build/nuke_build/Build.cs b/build/nuke_build/Build.cs index db99a211..7c2bf806 100644 --- a/build/nuke_build/Build.cs +++ b/build/nuke_build/Build.cs @@ -263,7 +263,7 @@ class Build : NukeBuild // This transport gets compiled to Arm64X and x64. The Arm64X output is in the Arm64EC folder stagingFiles.Add(ApiSolutionFolder / "vsfiles" / platform / Configuration.Release / $"Midi2.MidiSrvTransport.dll"); - + stagingFiles.Add(ApiSolutionFolder / "vsfiles" / platform / Configuration.Release / $"wdmaud2.drv"); // only in-proc files, like the MidiSrvTransport, are Arm64EC. For all the others // any reference to Arm64EC is just Arm64. We don't use any of the Arm64X output @@ -283,8 +283,6 @@ class Build : NukeBuild stagingFiles.Add(ApiSolutionFolder / "vsfiles" / servicePlatform / Configuration.Release / $"Midi2.SchedulerTransform.dll"); - stagingFiles.Add(ApiSolutionFolder / "vsfiles" / servicePlatform / Configuration.Release / $"wdmaud2.drv"); - foreach (var file in stagingFiles) { FileSystemTasks.CopyFileToDirectory(file, ApiStagingFolder / servicePlatform, FileExistsPolicy.Overwrite, true); diff --git a/build/staging/version/BundleInfo.wxi b/build/staging/version/BundleInfo.wxi index 83f545da..be34c082 100644 --- a/build/staging/version/BundleInfo.wxi +++ b/build/staging/version/BundleInfo.wxi @@ -1,4 +1,4 @@ - + diff --git a/build/staging/version/WindowsMidiServicesVersion.cs b/build/staging/version/WindowsMidiServicesVersion.cs index 36ad2acb..c670b978 100644 --- a/build/staging/version/WindowsMidiServicesVersion.cs +++ b/build/staging/version/WindowsMidiServicesVersion.cs @@ -6,12 +6,12 @@ public static class MidiBuildInformation { public const string Source = "GitHub Preview"; public const string Name = "Developer Preview 8"; - public const string BuildFullVersion = "1.0.2-preview-8.241218-1759"; + public const string BuildFullVersion = "1.0.2-preview-8.241219-1336"; public const string VersionMajor = "1"; public const string VersionMinor = "0"; public const string VersionRevision = "2"; - public const string VersionDateNumber = "241218"; - public const string VersionTimeNumber = "1759"; + public const string VersionDateNumber = "241219"; + public const string VersionTimeNumber = "1336"; } } diff --git a/build/staging/version/WindowsMidiServicesVersion.h b/build/staging/version/WindowsMidiServicesVersion.h index f0ba035a..49750b1d 100644 --- a/build/staging/version/WindowsMidiServicesVersion.h +++ b/build/staging/version/WindowsMidiServicesVersion.h @@ -5,12 +5,12 @@ #define WINDOWS_MIDI_SERVICES_BUILD_SOURCE L"GitHub Preview" #define WINDOWS_MIDI_SERVICES_BUILD_VERSION_NAME L"Developer Preview 8" -#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_FULL L"1.0.2-preview-8.241218-1759" +#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_FULL L"1.0.2-preview-8.241219-1336" #define WINDOWS_MIDI_SERVICES_BUILD_VERSION_MAJOR L"1" #define WINDOWS_MIDI_SERVICES_BUILD_VERSION_MINOR L"0" #define WINDOWS_MIDI_SERVICES_BUILD_VERSION_REVISION L"2" -#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_DATE_NUMBER L"241218" -#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_TIME_NUMBER L"1759" +#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_DATE_NUMBER L"241219" +#define WINDOWS_MIDI_SERVICES_BUILD_VERSION_TIME_NUMBER L"1336" #endif diff --git a/samples/cpp-winrt/basics/client-basics-cpp.vcxproj b/samples/cpp-winrt/basics/client-basics-cpp.vcxproj index 9357a1d1..79b675cc 100644 --- a/samples/cpp-winrt/basics/client-basics-cpp.vcxproj +++ b/samples/cpp-winrt/basics/client-basics-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241218-1759 + Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241219-1336 true true false diff --git a/samples/cpp-winrt/basics/packages.config b/samples/cpp-winrt/basics/packages.config index 37d82809..2346b67e 100644 --- a/samples/cpp-winrt/basics/packages.config +++ b/samples/cpp-winrt/basics/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj b/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj index 478c7e36..7dfd7c2f 100644 --- a/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj +++ b/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241218-1759 + Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241219-1336 true true true diff --git a/samples/cpp-winrt/loopback-endpoints/packages.config b/samples/cpp-winrt/loopback-endpoints/packages.config index 37d82809..2346b67e 100644 --- a/samples/cpp-winrt/loopback-endpoints/packages.config +++ b/samples/cpp-winrt/loopback-endpoints/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/send-speed/packages.config b/samples/cpp-winrt/send-speed/packages.config index 37d82809..2346b67e 100644 --- a/samples/cpp-winrt/send-speed/packages.config +++ b/samples/cpp-winrt/send-speed/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj b/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj index 0814ecfb..504d9e4f 100644 --- a/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj +++ b/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241218-1759 + Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241219-1336 true true true diff --git a/samples/cpp-winrt/simple-app-to-app-midi/packages.config b/samples/cpp-winrt/simple-app-to-app-midi/packages.config index 37d82809..2346b67e 100644 --- a/samples/cpp-winrt/simple-app-to-app-midi/packages.config +++ b/samples/cpp-winrt/simple-app-to-app-midi/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj b/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj index 3cce86ce..b8ec1bfd 100644 --- a/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj +++ b/samples/cpp-winrt/simple-app-to-app-midi/simple-app-to-app-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241218-1759 + Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241219-1336 true true true diff --git a/samples/cpp-winrt/static-enum-endpoints/packages.config b/samples/cpp-winrt/static-enum-endpoints/packages.config index 37d82809..2346b67e 100644 --- a/samples/cpp-winrt/static-enum-endpoints/packages.config +++ b/samples/cpp-winrt/static-enum-endpoints/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj b/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj index ede76052..1aa71ae3 100644 --- a/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj +++ b/samples/cpp-winrt/static-enum-endpoints/static-enum-endpoints-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241218-1759 + Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241219-1336 true true true diff --git a/samples/cpp-winrt/watch-endpoints/packages.config b/samples/cpp-winrt/watch-endpoints/packages.config index 37d82809..2346b67e 100644 --- a/samples/cpp-winrt/watch-endpoints/packages.config +++ b/samples/cpp-winrt/watch-endpoints/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj b/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj index 3a6c7cf6..c772072e 100644 --- a/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj +++ b/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241218-1759 + Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241219-1336 true true true diff --git a/src/api/Client/WinMM/wdmaud2.vcxproj b/src/api/Client/WinMM/wdmaud2.vcxproj index 722ec18c..5483de67 100644 --- a/src/api/Client/WinMM/wdmaud2.vcxproj +++ b/src/api/Client/WinMM/wdmaud2.vcxproj @@ -5,6 +5,10 @@ Debug ARM64 + + Debug + ARM64EC + Debug Win32 @@ -17,6 +21,10 @@ Debug x64 + + Release + ARM64EC + Release Win32 @@ -39,6 +47,12 @@ v143 Unicode + + DynamicLibrary + true + v143 + Unicode + DynamicLibrary true @@ -57,6 +71,12 @@ v143 Unicode + + DynamicLibrary + false + v143 + Unicode + DynamicLibrary false @@ -77,6 +97,9 @@ + + + @@ -86,6 +109,9 @@ + + + @@ -99,6 +125,13 @@ $(SolutionDir)VSFiles\intermediate\wdmaud2\$(Platform)\$(Configuration)\ .drv + + true + $(SolutionDir)VSFiles\$(Platform)\$(Configuration)\ + $(SolutionDir)VSFiles\intermediate\wdmaud2\$(Platform)\$(Configuration)\ + .drv + true + true $(SolutionDir)VSFiles\$(Platform)\$(Configuration)\ @@ -117,6 +150,13 @@ $(SolutionDir)VSFiles\intermediate\wdmaud2\$(Platform)\$(Configuration)\ .drv + + true + $(SolutionDir)VSFiles\$(Platform)\$(Configuration)\ + $(SolutionDir)VSFiles\intermediate\wdmaud2\$(Platform)\$(Configuration)\ + .drv + true + true $(SolutionDir)VSFiles\$(Platform)\$(Configuration)\ @@ -146,6 +186,23 @@ false + + + _DEBUG;_WINDOWS;_USRDLL;WDMAUD2_EXPORTS;%(PreprocessorDefinitions) + Level3 + Create + pch.h + stdcpp20 + %(AdditionalIncludeDirectories);$(SolutionDir)VSFiles\intermediate\idl\$(Platform)\$(Configuration);$(ProjectDir)\..\Inc;$(SolutionDir)inc;$(SolutionDir)VSFiles\intermediate\MidiSrv\$(Platform)\$(Configuration);$(SolutionDir)VSFiles\intermediate\midi2.midisrvtransport\$(Platform)\$(Configuration) + + + true + Windows + winmmdrv.def + $(CoreLibraryDependencies);%(AdditionalDependencies);winmm.lib;onecoreuap.lib;avrt.lib;$(SolutionDir)VSFiles\$(Platform)\$(Configuration)\midixproc.lib;$(SolutionDir)VSFiles\$(Platform)\$(Configuration)\midisrvtransportlib.lib + false + + _DEBUG;_WINDOWS;_USRDLL;WDMAUD2_EXPORTS;%(PreprocessorDefinitions) @@ -199,6 +256,25 @@ false + + + NDEBUG;_WINDOWS;_USRDLL;WDMAUD2_EXPORTS;%(PreprocessorDefinitions) + Level3 + Create + pch.h + stdcpp20 + %(AdditionalIncludeDirectories);$(SolutionDir)VSFiles\intermediate\idl\$(Platform)\$(Configuration);$(ProjectDir)\..\Inc;$(SolutionDir)inc;$(SolutionDir)VSFiles\intermediate\MidiSrv\$(Platform)\$(Configuration);$(SolutionDir)VSFiles\intermediate\midi2.midisrvtransport\$(Platform)\$(Configuration) + + + true + Windows + true + true + winmmdrv.def + $(CoreLibraryDependencies);%(AdditionalDependencies);winmm.lib;onecoreuap.lib;avrt.lib;$(SolutionDir)VSFiles\$(Platform)\$(Configuration)\midixproc.lib;$(SolutionDir)VSFiles\$(Platform)\$(Configuration)\midisrvtransportlib.lib + false + + NDEBUG;_WINDOWS;_USRDLL;WDMAUD2_EXPORTS;%(PreprocessorDefinitions) diff --git a/src/api/Inc/MidiSrvTransport.h b/src/api/Inc/MidiSrvTransport.h index 24e7a93c..8eebd05a 100644 --- a/src/api/Inc/MidiSrvTransport.h +++ b/src/api/Inc/MidiSrvTransport.h @@ -17,7 +17,7 @@ class MidiSrvTransportTelemetryProvider : public wil::TraceLoggingProvider (0xc22d26fd,0x947b,0x5df1,0xa0,0xf8,0xbc,0x62,0xd2,0x6d,0x18,0x8d)) }; -HRESULT GetMidiSrvBindingHandle(_In_ handle_t* BindingHandle); +HRESULT GetMidiSrvBindingHandle(_In_ handle_t* BindingHandle); class CMidi2MidiSrv { @@ -28,21 +28,21 @@ class CMidi2MidiSrv HRESULT Shutdown(); // session tracker - HRESULT AddClientSession(_In_ GUID sessionId, _In_ LPCWSTR sessionName); - HRESULT UpdateClientSessionName(_In_ GUID sessionId, _In_ LPCWSTR sessionName); - HRESULT RemoveClientSession(_In_ GUID sessionId); - HRESULT GetSessionList(_Out_ LPWSTR* sessionList); - HRESULT GetSessionList(_Out_ LPSAFEARRAY* SessionDetailsList); - BOOL VerifyConnectivity(); + HRESULT AddClientSession(_In_ GUID sessionId, _In_ LPCWSTR sessionName); + HRESULT UpdateClientSessionName(_In_ GUID sessionId, _In_ LPCWSTR sessionName); + HRESULT RemoveClientSession(_In_ GUID sessionId); + HRESULT GetSessionList(_Out_ LPWSTR* sessionList); + // HRESULT GetSessionList(_Out_ LPSAFEARRAY* SessionDetailsList); + BOOL VerifyConnectivity(); // configuration manager - HRESULT UpdateConfiguration(_In_ LPCWSTR configurationJson, _Out_ LPWSTR* responseJson); - HRESULT GetTransportList(_Out_ LPWSTR* transportListJson); - HRESULT GetTransformList(_Out_ LPWSTR* transformListJson); + HRESULT UpdateConfiguration(_In_ LPCWSTR configurationJson, _Out_ LPWSTR* responseJson); + HRESULT GetTransportList(_Out_ LPWSTR* transportListJson); + HRESULT GetTransformList(_Out_ LPWSTR* transformListJson); private: - PVOID m_ContextHandle{ nullptr }; + PVOID m_ContextHandle{ nullptr }; MidiClientHandle m_ClientHandle{ 0 }; std::unique_ptr m_MidiPump; diff --git a/src/api/Libs/MidiSrvTransportLib/MidiSrvTransport.cpp b/src/api/Libs/MidiSrvTransportLib/MidiSrvTransport.cpp index 5184ada3..deb3819c 100644 --- a/src/api/Libs/MidiSrvTransportLib/MidiSrvTransport.cpp +++ b/src/api/Libs/MidiSrvTransportLib/MidiSrvTransport.cpp @@ -23,39 +23,39 @@ void __RPC_USER midl_user_free(void __RPC_FAR* pointer delete[](BYTE*)pointer; } -// using the protocol and endpoint, retrieve the midisrv -// rpc binding handle -_Use_decl_annotations_ -HRESULT -GetMidiSrvBindingHandle(handle_t* bindingHandle -) -{ - RETURN_HR_IF(E_INVALIDARG, nullptr == bindingHandle); - *bindingHandle = NULL; - - RPC_WSTR stringBinding = nullptr; - auto cleanupOnExit = wil::scope_exit([&]() - { - if (stringBinding) - { - RpcStringFree(&stringBinding); - } - }); - - RETURN_IF_WIN32_ERROR(RpcStringBindingCompose( - nullptr, - (RPC_WSTR) MIDISRV_LRPC_PROTOCOL, - nullptr, - nullptr, - nullptr, - &stringBinding)); - - RETURN_IF_WIN32_ERROR(RpcBindingFromStringBinding( - stringBinding, - bindingHandle)); - - return S_OK; -} +// using the protocol and endpoint, retrieve the midisrv +// rpc binding handle +_Use_decl_annotations_ +HRESULT +GetMidiSrvBindingHandle(handle_t* bindingHandle +) +{ + RETURN_HR_IF(E_INVALIDARG, nullptr == bindingHandle); + *bindingHandle = NULL; + + RPC_WSTR stringBinding = nullptr; + auto cleanupOnExit = wil::scope_exit([&]() + { + if (stringBinding) + { + RpcStringFree(&stringBinding); + } + }); + + RETURN_IF_WIN32_ERROR(RpcStringBindingCompose( + nullptr, + (RPC_WSTR) MIDISRV_LRPC_PROTOCOL, + nullptr, + nullptr, + nullptr, + &stringBinding)); + + RETURN_IF_WIN32_ERROR(RpcBindingFromStringBinding( + stringBinding, + bindingHandle)); + + return S_OK; +} HRESULT CMidi2MidiSrv::Initialize( @@ -261,299 +261,299 @@ CMidi2MidiSrv::SendMidiMessage( return E_ABORT; } -_Use_decl_annotations_ -HRESULT +_Use_decl_annotations_ +HRESULT CMidi2MidiSrv::AddClientSession( - GUID sessionId, - LPCWSTR sessionName -) -{ - TraceLoggingWrite( - MidiSrvTransportTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") - ); - - wil::unique_rpc_binding bindingHandle; - - RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); - RETURN_HR_IF_NULL(E_INVALIDARG, sessionName); - - RETURN_IF_FAILED([&]() - { - // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks - // with structured exception handling. - RpcTryExcept RETURN_IF_FAILED(MidiSrvRegisterSession(bindingHandle.get(), sessionId, sessionName, &m_ContextHandle)); - RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); - RpcEndExcept - - return S_OK; - }()); - - return S_OK; -} - -_Use_decl_annotations_ -HRESULT + GUID sessionId, + LPCWSTR sessionName +) +{ + TraceLoggingWrite( + MidiSrvTransportTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this") + ); + + wil::unique_rpc_binding bindingHandle; + + RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); + RETURN_HR_IF_NULL(E_INVALIDARG, sessionName); + + RETURN_IF_FAILED([&]() + { + // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks + // with structured exception handling. + RpcTryExcept RETURN_IF_FAILED(MidiSrvRegisterSession(bindingHandle.get(), sessionId, sessionName, &m_ContextHandle)); + RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); + RpcEndExcept + + return S_OK; + }()); + + return S_OK; +} + +_Use_decl_annotations_ +HRESULT CMidi2MidiSrv::UpdateClientSessionName( - GUID sessionId, - LPCWSTR sessionName -) -{ - TraceLoggingWrite( - MidiSrvTransportTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") - ); - - wil::unique_rpc_binding bindingHandle; - - RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); - RETURN_HR_IF_NULL(E_INVALIDARG, sessionName); - - RETURN_IF_FAILED([&]() - { - // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks - // with structured exception handling. - RpcTryExcept RETURN_IF_FAILED(MidiSrvUpdateSessionName(bindingHandle.get(), m_ContextHandle, sessionId, sessionName)); - RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); - RpcEndExcept - - return S_OK; - }()); - - return S_OK; -} - - -_Use_decl_annotations_ -HRESULT + GUID sessionId, + LPCWSTR sessionName +) +{ + TraceLoggingWrite( + MidiSrvTransportTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this") + ); + + wil::unique_rpc_binding bindingHandle; + + RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); + RETURN_HR_IF_NULL(E_INVALIDARG, sessionName); + + RETURN_IF_FAILED([&]() + { + // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks + // with structured exception handling. + RpcTryExcept RETURN_IF_FAILED(MidiSrvUpdateSessionName(bindingHandle.get(), m_ContextHandle, sessionId, sessionName)); + RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); + RpcEndExcept + + return S_OK; + }()); + + return S_OK; +} + + +_Use_decl_annotations_ +HRESULT CMidi2MidiSrv::RemoveClientSession( - GUID sessionId -) -{ - TraceLoggingWrite( - MidiSrvTransportTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") - ); - - wil::unique_rpc_binding bindingHandle; - - RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); - - RETURN_IF_FAILED([&]() - { - // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks - // with structured exception handling. - RpcTryExcept RETURN_IF_FAILED(MidiSrvDeregisterSession(bindingHandle.get(), m_ContextHandle, sessionId)); - RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); - RpcEndExcept - - return S_OK; - }()); - - return S_OK; -} - - - -_Use_decl_annotations_ -HRESULT + GUID sessionId +) +{ + TraceLoggingWrite( + MidiSrvTransportTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this") + ); + + wil::unique_rpc_binding bindingHandle; + + RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); + + RETURN_IF_FAILED([&]() + { + // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks + // with structured exception handling. + RpcTryExcept RETURN_IF_FAILED(MidiSrvDeregisterSession(bindingHandle.get(), m_ContextHandle, sessionId)); + RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); + RpcEndExcept + + return S_OK; + }()); + + return S_OK; +} + + + +_Use_decl_annotations_ +HRESULT CMidi2MidiSrv::GetSessionList( - LPWSTR* sessionList -) -{ - TraceLoggingWrite( - MidiSrvTransportTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") - ); - - wil::unique_rpc_binding bindingHandle; - - RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); - RETURN_HR_IF_NULL(E_INVALIDARG, sessionList); - - RETURN_IF_FAILED([&]() - { - // RPC requirement - *sessionList = nullptr; - - // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks - // with structured exception handling. - RpcTryExcept RETURN_IF_FAILED(MidiSrvGetSessionList(bindingHandle.get(), sessionList)); - RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); - RpcEndExcept - return S_OK; - }()); - - return S_OK; -} - -BOOL + LPWSTR* sessionList +) +{ + TraceLoggingWrite( + MidiSrvTransportTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this") + ); + + wil::unique_rpc_binding bindingHandle; + + RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); + RETURN_HR_IF_NULL(E_INVALIDARG, sessionList); + + RETURN_IF_FAILED([&]() + { + // RPC requirement + *sessionList = nullptr; + + // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks + // with structured exception handling. + RpcTryExcept RETURN_IF_FAILED(MidiSrvGetSessionList(bindingHandle.get(), sessionList)); + RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); + RpcEndExcept + return S_OK; + }()); + + return S_OK; +} + +BOOL CMidi2MidiSrv::VerifyConnectivity() -{ - TraceLoggingWrite( - MidiSrvTransportTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") - ); - - wil::unique_rpc_binding bindingHandle; - - LOG_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); - - auto verifyConnectivity = ([&]() - { - // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks - // with structured exception handling. - RpcTryExcept MidiSrvVerifyConnectivity(bindingHandle.get()); - RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); - RpcEndExcept - - return S_OK; - }); - - auto hr = verifyConnectivity(); - - if (FAILED(hr)) - { - return FALSE; - } - else - { - return TRUE; - } - -} - -_Use_decl_annotations_ -HRESULT +{ + TraceLoggingWrite( + MidiSrvTransportTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this") + ); + + wil::unique_rpc_binding bindingHandle; + + LOG_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); + + auto verifyConnectivity = ([&]() + { + // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks + // with structured exception handling. + RpcTryExcept MidiSrvVerifyConnectivity(bindingHandle.get()); + RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); + RpcEndExcept + + return S_OK; + }); + + auto hr = verifyConnectivity(); + + if (FAILED(hr)) + { + return FALSE; + } + else + { + return TRUE; + } + +} + +_Use_decl_annotations_ +HRESULT CMidi2MidiSrv::UpdateConfiguration(LPCWSTR configurationJson, LPWSTR* responseJson) -{ - TraceLoggingWrite( - MidiSrvTransportTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Entering UpdateConfiguration", MIDI_TRACE_EVENT_MESSAGE_FIELD), - TraceLoggingWideString(configurationJson, "config json"), - TraceLoggingPointer(responseJson, "Response pointer") - ); - - RETURN_HR_IF_NULL(E_INVALIDARG, responseJson); - - // requirement for RPC and also in case of failure - *responseJson = NULL; - - RETURN_HR_IF_NULL(E_INVALIDARG, configurationJson); - - wil::unique_rpc_binding bindingHandle; - RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); - - RETURN_IF_FAILED([&]() - { - // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks - // with structured exception handling. - RpcTryExcept RETURN_IF_FAILED(MidiSrvUpdateConfiguration(bindingHandle.get(), configurationJson, responseJson)); - RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); - RpcEndExcept - - TraceLoggingWrite( - MidiSrvTransportTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this"), - TraceLoggingWideString(L"Completed RPC call", MIDI_TRACE_EVENT_MESSAGE_FIELD), - TraceLoggingWideString(configurationJson, "config json"), - TraceLoggingPointer(responseJson, "Response pointer") - ); - - return S_OK; - }()); - - return S_OK; -} - -_Use_decl_annotations_ -HRESULT +{ + TraceLoggingWrite( + MidiSrvTransportTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Entering UpdateConfiguration", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(configurationJson, "config json"), + TraceLoggingPointer(responseJson, "Response pointer") + ); + + RETURN_HR_IF_NULL(E_INVALIDARG, responseJson); + + // requirement for RPC and also in case of failure + *responseJson = NULL; + + RETURN_HR_IF_NULL(E_INVALIDARG, configurationJson); + + wil::unique_rpc_binding bindingHandle; + RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); + + RETURN_IF_FAILED([&]() + { + // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks + // with structured exception handling. + RpcTryExcept RETURN_IF_FAILED(MidiSrvUpdateConfiguration(bindingHandle.get(), configurationJson, responseJson)); + RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); + RpcEndExcept + + TraceLoggingWrite( + MidiSrvTransportTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this"), + TraceLoggingWideString(L"Completed RPC call", MIDI_TRACE_EVENT_MESSAGE_FIELD), + TraceLoggingWideString(configurationJson, "config json"), + TraceLoggingPointer(responseJson, "Response pointer") + ); + + return S_OK; + }()); + + return S_OK; +} + +_Use_decl_annotations_ +HRESULT CMidi2MidiSrv::GetTransportList(LPWSTR* transportListJson) -{ - TraceLoggingWrite( - MidiSrvTransportTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") - ); - - RETURN_HR_IF_NULL(E_INVALIDARG, transportListJson); - - // requirement for RPC and also in case of failure - *transportListJson = NULL; - - wil::unique_rpc_binding bindingHandle; - RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); - - - RETURN_IF_FAILED([&]() - { - // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks - // with structured exception handling. - RpcTryExcept RETURN_IF_FAILED(MidiSrvGetTransportList(bindingHandle.get(), transportListJson)); - RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); - RpcEndExcept - return S_OK; - }()); - - return S_OK; -} - -_Use_decl_annotations_ -HRESULT +{ + TraceLoggingWrite( + MidiSrvTransportTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this") + ); + + RETURN_HR_IF_NULL(E_INVALIDARG, transportListJson); + + // requirement for RPC and also in case of failure + *transportListJson = NULL; + + wil::unique_rpc_binding bindingHandle; + RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); + + + RETURN_IF_FAILED([&]() + { + // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks + // with structured exception handling. + RpcTryExcept RETURN_IF_FAILED(MidiSrvGetTransportList(bindingHandle.get(), transportListJson)); + RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); + RpcEndExcept + return S_OK; + }()); + + return S_OK; +} + +_Use_decl_annotations_ +HRESULT CMidi2MidiSrv::GetTransformList(LPWSTR* transformListJson) -{ - TraceLoggingWrite( - MidiSrvTransportTelemetryProvider::Provider(), - MIDI_TRACE_EVENT_INFO, - TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), - TraceLoggingLevel(WINEVENT_LEVEL_INFO), - TraceLoggingPointer(this, "this") - ); - - RETURN_HR_IF_NULL(E_INVALIDARG, transformListJson); - - // requirement for RPC and also in case of failure - *transformListJson = NULL; - - wil::unique_rpc_binding bindingHandle; - RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); - - - RETURN_IF_FAILED([&]() - { - - // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks - // with structured exception handling. - RpcTryExcept RETURN_IF_FAILED(MidiSrvGetTransformList(bindingHandle.get(), transformListJson)); - RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); - RpcEndExcept - return S_OK; - }()); - - return S_OK; -} +{ + TraceLoggingWrite( + MidiSrvTransportTelemetryProvider::Provider(), + MIDI_TRACE_EVENT_INFO, + TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD), + TraceLoggingLevel(WINEVENT_LEVEL_INFO), + TraceLoggingPointer(this, "this") + ); + + RETURN_HR_IF_NULL(E_INVALIDARG, transformListJson); + + // requirement for RPC and also in case of failure + *transformListJson = NULL; + + wil::unique_rpc_binding bindingHandle; + RETURN_IF_FAILED(GetMidiSrvBindingHandle(&bindingHandle)); + + + RETURN_IF_FAILED([&]() + { + + // RPC calls are placed in a lambda to work around compiler error C2712, limiting use of try/except blocks + // with structured exception handling. + RpcTryExcept RETURN_IF_FAILED(MidiSrvGetTransformList(bindingHandle.get(), transformListJson)); + RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) RETURN_IF_FAILED(HRESULT_FROM_WIN32(RpcExceptionCode())); + RpcEndExcept + return S_OK; + }()); + + return S_OK; +} diff --git a/src/api/Midi2.sln b/src/api/Midi2.sln index bd5beb21..b152d394 100644 --- a/src/api/Midi2.sln +++ b/src/api/Midi2.sln @@ -719,7 +719,8 @@ Global {8D7E847B-AD56-4900-93A1-4F0E2EF7A4F9}.Debug|x86.Build.0 = Debug|Win32 {8D7E847B-AD56-4900-93A1-4F0E2EF7A4F9}.Release|ARM64.ActiveCfg = Release|ARM64 {8D7E847B-AD56-4900-93A1-4F0E2EF7A4F9}.Release|ARM64.Build.0 = Release|ARM64 - {8D7E847B-AD56-4900-93A1-4F0E2EF7A4F9}.Release|ARM64EC.ActiveCfg = Release|ARM64 + {8D7E847B-AD56-4900-93A1-4F0E2EF7A4F9}.Release|ARM64EC.ActiveCfg = Release|ARM64EC + {8D7E847B-AD56-4900-93A1-4F0E2EF7A4F9}.Release|ARM64EC.Build.0 = Release|ARM64EC {8D7E847B-AD56-4900-93A1-4F0E2EF7A4F9}.Release|Win32.ActiveCfg = Release|Win32 {8D7E847B-AD56-4900-93A1-4F0E2EF7A4F9}.Release|Win32.Build.0 = Release|Win32 {8D7E847B-AD56-4900-93A1-4F0E2EF7A4F9}.Release|x64.ActiveCfg = Release|x64 diff --git a/src/app-sdk/client-initialization-redist/Microsoft.Windows.Devices.Midi2.Initialization.hpp b/src/app-sdk/client-initialization-redist/Microsoft.Windows.Devices.Midi2.Initialization.hpp index 04ae56cc..fa433c9e 100644 --- a/src/app-sdk/client-initialization-redist/Microsoft.Windows.Devices.Midi2.Initialization.hpp +++ b/src/app-sdk/client-initialization-redist/Microsoft.Windows.Devices.Midi2.Initialization.hpp @@ -90,6 +90,7 @@ namespace Microsoft::Windows::Devices::Midi2::Initialization // guid for the initializer + // this must be called only *after* initializing the SDK Runtime bool EnsureServiceAvailable() { // initialize the SDK runtime before calling this function diff --git a/src/app-sdk/mididiag/main.cpp b/src/app-sdk/mididiag/main.cpp index 4e4b031b..6e05ac94 100644 --- a/src/app-sdk/mididiag/main.cpp +++ b/src/app-sdk/mididiag/main.cpp @@ -1000,7 +1000,7 @@ void OutputProcessAndNativeMachine() // if not running emulated, IsWow64Process2 returns machine unknown for the process. if ((processMachine == IMAGE_FILE_MACHINE_UNKNOWN || processMachine == IMAGE_FILE_MACHINE_ARM64) && nativeMachine == IMAGE_FILE_MACHINE_ARM64) { - OutputStringField(MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_PROCESSOR_EMULATION, std::wstring{ L"Native Arm64 process on Arm64 PC (Note Emulated)" }); + OutputStringField(MIDIDIAG_FIELD_LABEL_SYSTEM_INFO_PROCESSOR_EMULATION, std::wstring{ L"Native Arm64 process on Arm64 PC (Not Emulated)" }); } else if ((processMachine == IMAGE_FILE_MACHINE_UNKNOWN || processMachine == IMAGE_FILE_MACHINE_AMD64) && nativeMachine == IMAGE_FILE_MACHINE_AMD64) { diff --git a/src/app-sdk/mididiag/mididiag.vcxproj b/src/app-sdk/mididiag/mididiag.vcxproj index 0523dff6..e5208306 100644 --- a/src/app-sdk/mididiag/mididiag.vcxproj +++ b/src/app-sdk/mididiag/mididiag.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241218-1759 + Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241219-1336 true true true diff --git a/src/app-sdk/mididiag/packages.config b/src/app-sdk/mididiag/packages.config index 068148e3..f8387df3 100644 --- a/src/app-sdk/mididiag/packages.config +++ b/src/app-sdk/mididiag/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj b/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj index 723341da..1df14707 100644 --- a/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj +++ b/src/app-sdk/midimdnsinfo/midimdnsinfo.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241218-1759 + Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241219-1336 true true true diff --git a/src/app-sdk/midimdnsinfo/packages.config b/src/app-sdk/midimdnsinfo/packages.config index 068148e3..f8387df3 100644 --- a/src/app-sdk/midimdnsinfo/packages.config +++ b/src/app-sdk/midimdnsinfo/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/app-sdk/midiusbinfo/midiusbinfo.vcxproj b/src/app-sdk/midiusbinfo/midiusbinfo.vcxproj index 30160e06..4c34d837 100644 --- a/src/app-sdk/midiusbinfo/midiusbinfo.vcxproj +++ b/src/app-sdk/midiusbinfo/midiusbinfo.vcxproj @@ -2,7 +2,7 @@ - Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241218-1759 + Microsoft.Windows.Devices.Midi2.1.0.2-preview-8.241219-1336 true true true diff --git a/src/app-sdk/midiusbinfo/packages.config b/src/app-sdk/midiusbinfo/packages.config index 068148e3..f8387df3 100644 --- a/src/app-sdk/midiusbinfo/packages.config +++ b/src/app-sdk/midiusbinfo/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/app-sdk/projections/dotnet-and-cpp/MidiDesktopAppSdkInitializer.cs b/src/app-sdk/projections/dotnet-and-cpp/MidiDesktopAppSdkInitializer.cs index 93697db6..5bf63b6d 100644 --- a/src/app-sdk/projections/dotnet-and-cpp/MidiDesktopAppSdkInitializer.cs +++ b/src/app-sdk/projections/dotnet-and-cpp/MidiDesktopAppSdkInitializer.cs @@ -68,6 +68,7 @@ public class MidiDesktopAppSdkInitializer : IDisposable private MidiDesktopAppSdkInitializer(IMidiClientInitializer initializer) { _initializer = initializer; + } public static MidiDesktopAppSdkInitializer? Create() @@ -82,11 +83,24 @@ private MidiDesktopAppSdkInitializer(IMidiClientInitializer initializer) if (hr == 0 && obj != null) { - return new MidiDesktopAppSdkInitializer((IMidiClientInitializer)obj); + var cominit = (IMidiClientInitializer)obj; + + try + { + cominit.Initialize(); + + var initializer = new MidiDesktopAppSdkInitializer(cominit); + + return initializer; + } + catch (Exception) + { + return null; + } } else { - // TODO: failed to create the initializer + // failed to create the initializer return null; } } @@ -99,7 +113,7 @@ public bool EnsureServiceAvailable() return true; } - catch (Exception ex) + catch (Exception) { // todo: Log return false; @@ -114,7 +128,7 @@ public bool InitializeSdkRuntime() return true; } - catch (Exception ex) + catch (Exception) { // todo: Log return false; diff --git a/src/app-sdk/winrt/Initialization/MidiClientInitializer.cpp b/src/app-sdk/winrt/Initialization/MidiClientInitializer.cpp index 4d5357a7..46721d23 100644 --- a/src/app-sdk/winrt/Initialization/MidiClientInitializer.cpp +++ b/src/app-sdk/winrt/Initialization/MidiClientInitializer.cpp @@ -34,6 +34,18 @@ MidiClientInitializer::Initialize( return S_OK; } + // midisrv client initialization. Doesn't actually connect to service here + + RETURN_IF_FAILED(CoCreateInstance(__uuidof(Midi2MidiSrvTransport), nullptr, CLSCTX_ALL, IID_PPV_ARGS(&m_serviceTransport))); + RETURN_IF_FAILED(m_serviceTransport->Activate(__uuidof(IMidiSessionTracker), (void**)&m_sessionTracker)); + + RETURN_HR_IF_NULL(E_POINTER, m_sessionTracker); + + RETURN_IF_FAILED(m_sessionTracker->Initialize()); + + + // SDK initialization + g_runtimeComponentCatalog = std::make_shared(); if (g_runtimeComponentCatalog == nullptr) @@ -100,6 +112,7 @@ MidiClientInitializer::Initialize( RETURN_IF_FAILED(E_FAIL); } + m_initialized = true; return S_OK; @@ -268,17 +281,10 @@ MidiClientInitializer::EnsureServiceAvailable() noexcept TraceLoggingWideString(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD) ); - wil::com_ptr_nothrow serviceTransport; - wil::com_ptr_nothrow sessionTracker; - RETURN_IF_FAILED(CoCreateInstance(__uuidof(Midi2MidiSrvTransport), nullptr, CLSCTX_ALL, IID_PPV_ARGS(&serviceTransport))); - RETURN_IF_FAILED(serviceTransport->Activate(__uuidof(IMidiSessionTracker), (void**)&sessionTracker)); + RETURN_HR_IF_NULL(E_POINTER, m_sessionTracker); - RETURN_HR_IF_NULL(E_POINTER, sessionTracker); - - RETURN_IF_FAILED(sessionTracker->Initialize()); - - if (sessionTracker->VerifyConnectivity()) + if (m_sessionTracker->VerifyConnectivity()) { return S_OK; } @@ -303,6 +309,16 @@ MidiClientInitializer::Shutdown() noexcept // Remove activation hooks RemoveWinRTActivationHooks(); + if (m_serviceTransport) + { + m_serviceTransport = nullptr; + } + + if (m_sessionTracker) + { + m_sessionTracker->Shutdown(); + m_serviceTransport = nullptr; + } if (g_runtimeComponentCatalog != nullptr) { diff --git a/src/app-sdk/winrt/Initialization/MidiClientInitializer.h b/src/app-sdk/winrt/Initialization/MidiClientInitializer.h index 5fd67d52..0be14eca 100644 --- a/src/app-sdk/winrt/Initialization/MidiClientInitializer.h +++ b/src/app-sdk/winrt/Initialization/MidiClientInitializer.h @@ -77,6 +77,9 @@ struct __declspec(uuid("c3263827-c3b0-bdbd-2500-ce63a3f3f2c3")) MidiClientInitia private: bool m_initialized{ false }; + + wil::com_ptr_nothrow m_serviceTransport{ nullptr }; + wil::com_ptr_nothrow m_sessionTracker{ nullptr }; }; extern winrt::com_ptr g_clientInitializer; diff --git a/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointPlayNotesCommand.cs b/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointPlayNotesCommand.cs index d1dd27a3..876ea414 100644 --- a/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointPlayNotesCommand.cs +++ b/src/user-tools/midi-console/Midi/Commands/Endpoint/EndpointPlayNotesCommand.cs @@ -28,20 +28,20 @@ public sealed class Settings : EndpointCommandSettings [DefaultValue(250)] public int Rest { get; set; } - [LocalizedDescription("ParameterPlayNotesGroupIndex")] - [CommandOption("-g|--group|--group-index")] - [DefaultValue(0)] - public int GroupIndex { get; set; } + [LocalizedDescription("ParameterPlayNotesGroupNumber")] + [CommandOption("-g|--group|--group-number")] + [DefaultValue(1)] + public int GroupNumber { get; set; } - [LocalizedDescription("ParameterPlayNotesChannelIndex")] - [CommandOption("-c|--channel|--channel-index")] - [DefaultValue(0)] - public int ChannelIndex { get; set; } + [LocalizedDescription("ParameterPlayNotesChannelNumber")] + [CommandOption("-c|--channel|--channel-number")] + [DefaultValue(1)] + public int ChannelNumber { get; set; } [LocalizedDescription("ParameterPlayNotesVelocity")] - [CommandOption("-v|--velocity")] - [DefaultValue(127)] - public UInt32 Velocity { get; set; } + [CommandOption("-v|--velocity|--velocity-percent")] + [DefaultValue(75.0)] + public double Velocity { get; set; } [LocalizedDescription("ParameterPlayNotesForever")] [CommandOption("-f|--forever|--repeat-forever")] @@ -57,22 +57,19 @@ public sealed class Settings : EndpointCommandSettings public override Spectre.Console.ValidationResult Validate(CommandContext context, Settings settings) { - if (!MidiGroup.IsValidIndex((byte)settings.GroupIndex)) + if (!MidiGroup.IsValidIndex((byte)(settings.GroupNumber-1))) { - return ValidationResult.Error("Group index must be between 0 and 15 inclusive."); + return ValidationResult.Error("Group number must be between 1 and 16 inclusive."); } - if (!MidiChannel.IsValidIndex((byte)settings.ChannelIndex)) + if (!MidiChannel.IsValidIndex((byte)(settings.ChannelNumber-1))) { - return ValidationResult.Error("Channel index must be between 0 and 15 inclusive."); + return ValidationResult.Error("Channel index must be between 1 and 16 inclusive."); } - if (!settings.Midi2) + if (settings.Velocity > 100.0 || settings.Velocity < 1.0) { - if (settings.Velocity > 127 || settings.Velocity < 0) - { - return ValidationResult.Error("Velocity must be between 0 and 127 inclusive for MIDI 1.0 messages."); - } + return ValidationResult.Error("Velocity percentage must be between 1.0 and 100.0 inclusive."); } // todo: validate notes @@ -86,18 +83,18 @@ public override Spectre.Console.ValidationResult Validate(CommandContext context { if (index > 127 || index < 0) { - return ValidationResult.Error("All note indexes must be between 0 and 127"); + return ValidationResult.Error("All note indexes must be between 0 and 127."); } } if (settings.Length < 30 ) { - return ValidationResult.Error("Please provide a note duration of at least 30 milliseconds"); + return ValidationResult.Error("Please provide a note duration of at least 30 milliseconds."); } if (settings.Rest < 0) { - return ValidationResult.Error("Please provide a rest duration of zero or more milliseconds"); + return ValidationResult.Error("Please provide a rest duration of zero or more milliseconds."); } return base.Validate(context, settings); @@ -168,9 +165,8 @@ public override int Execute(CommandContext context, Settings settings) bool stillSending = true; - MidiGroup group = new MidiGroup((byte)settings.GroupIndex); - MidiChannel channel = new MidiChannel((byte)settings.ChannelIndex); - byte velocity = (byte)settings.Velocity; + MidiGroup group = new MidiGroup((byte)(settings.GroupNumber-1)); + MidiChannel channel = new MidiChannel((byte)(settings.ChannelNumber-1)); var messageSenderThread = new Thread(() => { @@ -191,6 +187,8 @@ public override int Execute(CommandContext context, Settings settings) if (settings.Midi2) { + UInt32 velocity = (UInt32)(settings.Velocity / 100.0) * UInt32.MaxValue; + var noteOnMessage = MidiMessageBuilder.BuildMidi2ChannelVoiceMessage( MidiClock.TimestampConstantSendImmediately, group, @@ -203,6 +201,8 @@ public override int Execute(CommandContext context, Settings settings) } else { + byte velocity = (byte)settings.Velocity; + var noteOnMessage = MidiMessageBuilder.BuildMidi1ChannelVoiceMessage( MidiClock.TimestampConstantSendImmediately, group, @@ -231,6 +231,8 @@ public override int Execute(CommandContext context, Settings settings) if (settings.Midi2) { + UInt32 velocity = (UInt32)(settings.Velocity / 100.0) * UInt32.MaxValue; + var noteOffMessage = MidiMessageBuilder.BuildMidi2ChannelVoiceMessage( MidiClock.TimestampConstantSendImmediately, group, @@ -243,6 +245,8 @@ public override int Execute(CommandContext context, Settings settings) } else { + byte velocity = (byte)settings.Velocity; + var noteOffMessage = MidiMessageBuilder.BuildMidi1ChannelVoiceMessage( MidiClock.TimestampConstantSendImmediately, group, diff --git a/src/user-tools/midi-console/Midi/Program.cs b/src/user-tools/midi-console/Midi/Program.cs index bfbbad6e..04d1c5c2 100644 --- a/src/user-tools/midi-console/Midi/Program.cs +++ b/src/user-tools/midi-console/Midi/Program.cs @@ -136,7 +136,7 @@ endpoint.AddCommand("play-notes") .WithAlias("play") .WithExample("endpoint", "\\\\?\\SWD#MIDISRV...}", "play-notes", "127 32 56 98", "--length", "500", "--velocity", "50", "--forever", "--midi2") - .WithDescription(Strings.CommandPlayMidi1NotesDescription) + .WithDescription(Strings.CommandPlayNotesDescription) ; diff --git a/src/user-tools/midi-console/Midi/Resources/Strings.Designer.cs b/src/user-tools/midi-console/Midi/Resources/Strings.Designer.cs index bba26ba1..4a743c87 100644 --- a/src/user-tools/midi-console/Midi/Resources/Strings.Designer.cs +++ b/src/user-tools/midi-console/Midi/Resources/Strings.Designer.cs @@ -214,11 +214,11 @@ internal static string CommandMonitorEndpointDescription { } /// - /// Looks up a localized string similar to Send MIDI 1.0 note on and off messages to the endpoint. + /// Looks up a localized string similar to Send MIDI 1.0 or 2.0 note on and off messages to the endpoint. /// - internal static string CommandPlayMidi1NotesDescription { + internal static string CommandPlayNotesDescription { get { - return ResourceManager.GetString("CommandPlayMidi1NotesDescription", resourceCulture); + return ResourceManager.GetString("CommandPlayNotesDescription", resourceCulture); } } @@ -1051,16 +1051,16 @@ internal static string ParameterMonitorEndpointVerbose { } /// - /// Looks up a localized string similar to Index (0-15 decimal) of the channel to send the messages to. + /// Looks up a localized string similar to Number (1-16 decimal) of the channel to send the messages to. /// - internal static string ParameterPlayNotesChannelIndex { + internal static string ParameterPlayNotesChannelNumber { get { - return ResourceManager.GetString("ParameterPlayNotesChannelIndex", resourceCulture); + return ResourceManager.GetString("ParameterPlayNotesChannelNumber", resourceCulture); } } /// - /// Looks up a localized string similar to Set to true to play the notes until you press the escape key. + /// Looks up a localized string similar to Set to true to continue to loop through the notes until you press the escape key. /// internal static string ParameterPlayNotesForever { get { @@ -1069,11 +1069,11 @@ internal static string ParameterPlayNotesForever { } /// - /// Looks up a localized string similar to Index (0-15 decimal) for the group to send the messages to. + /// Looks up a localized string similar to Number (1-16 decimal) for the group to send the messages to. /// - internal static string ParameterPlayNotesGroupIndex { + internal static string ParameterPlayNotesGroupNumber { get { - return ResourceManager.GetString("ParameterPlayNotesGroupIndex", resourceCulture); + return ResourceManager.GetString("ParameterPlayNotesGroupNumber", resourceCulture); } } @@ -1096,7 +1096,25 @@ internal static string ParameterPlayNotesLengthMilliseconds { } /// - /// Looks up a localized string similar to Note velocity (0-127 decimal). A velocity of 0 becomes a note-off message.. + /// Looks up a localized string similar to Set to true to use MIDI 2.0 protocol messages (type 4) instead of MIDI 1.0 protocol (type 2). + /// + internal static string ParameterPlayNotesMidi2 { + get { + return ResourceManager.GetString("ParameterPlayNotesMidi2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duration of wait time between notes, in whole decimal milliseconds. + /// + internal static string ParameterPlayNotesRestMilliseconds { + get { + return ResourceManager.GetString("ParameterPlayNotesRestMilliseconds", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Note velocity (1.0 - 100.0) as a fractional decimal percentage of the maximum value for the protocol.. /// internal static string ParameterPlayNotesVelocity { get { diff --git a/src/user-tools/midi-console/Midi/Resources/Strings.resx b/src/user-tools/midi-console/Midi/Resources/Strings.resx index 317d0d9b..d682049d 100644 --- a/src/user-tools/midi-console/Midi/Resources/Strings.resx +++ b/src/user-tools/midi-console/Midi/Resources/Strings.resx @@ -884,20 +884,20 @@ Timestamp Length / duration of the note in whole decimal milliseconds. - - Index (0-15 decimal) for the group to send the messages to + + Number (1-16 decimal) for the group to send the messages to - - Index (0-15 decimal) of the channel to send the messages to + + Number (1-16 decimal) of the channel to send the messages to - Note velocity (0-127 decimal). A velocity of 0 becomes a note-off message. + Note velocity (1.0 - 100.0) as a fractional decimal percentage of the maximum value for the protocol. - Set to true to play the notes until you press the escape key + Set to true to continue to loop through the notes until you press the escape key - - Send MIDI 1.0 note on and off messages to the endpoint + + Send MIDI 1.0 or 2.0 note on and off messages to the endpoint Unique identifiers updated @@ -905,4 +905,10 @@ Timestamp List the Windows MIDI Services-specific property keys + + Duration of wait time between notes, in whole decimal milliseconds + + + Set to true to use MIDI 2.0 protocol messages (type 4) instead of MIDI 1.0 protocol (type 2) + \ No newline at end of file