diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json
index e1272134..413b7e71 100644
--- a/.nuke/build.schema.json
+++ b/.nuke/build.schema.json
@@ -70,6 +70,7 @@
"BuildAppSdkRuntimeAndToolsInstaller",
"BuildConsoleApp",
"BuildCppSamples",
+ "BuildCSharpSamples",
"BuildServiceAndPlugins",
"BuildServiceAndPluginsInstaller",
"BuildSettingsApp",
@@ -90,6 +91,7 @@
"BuildAppSdkRuntimeAndToolsInstaller",
"BuildConsoleApp",
"BuildCppSamples",
+ "BuildCSharpSamples",
"BuildServiceAndPlugins",
"BuildServiceAndPluginsInstaller",
"BuildSettingsApp",
diff --git a/build/nuke_build/Build.cs b/build/nuke_build/Build.cs
index e4976347..003b080a 100644
--- a/build/nuke_build/Build.cs
+++ b/build/nuke_build/Build.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Xml;
using Microsoft.ApplicationInsights.Extensibility;
using Nuke.Common;
using Nuke.Common.CI;
@@ -37,13 +38,18 @@ class Build : NukeBuild
string NuGetVersionName => "preview.7";
// we set these here, especially the time, so it's the same for all platforms in the single build
- string SetupBuildMajorMinor = "1.0";
+ string SetupBuildMajorMinor = "1.0.1";
string SetupBuildDateNumber = DateTime.Now.ToString("yy") + DateTime.Now.DayOfYear.ToString("000"); // YYddd where ddd is the day number for the year
string SetupBuildTimeNumber = UInt32.Parse(DateTime.Now.ToString("HHmm")).ToString(); // HHmm
- string NugetFullVersionString => SetupBuildMajorMinor + "." + SetupBuildDateNumber + "." + SetupBuildTimeNumber + "-" + NuGetVersionName;
- string NugetFullPackageId => "Microsoft.Windows.Devices.Midi2";
+ string NugetVersionString => SetupBuildMajorMinor + "-" + NuGetVersionName + "." + SetupBuildDateNumber + "." + SetupBuildTimeNumber ;
+ string NugetPackageId => "Microsoft.Windows.Devices.Midi2";
+
+ string NugetFullPackageIdWithVersion => NugetPackageId + "." + NugetVersionString;
+
+
+ string SetupBundleFullVersionString => SetupBuildMajorMinor + "-" + NuGetVersionName + "." + SetupBuildDateNumber + "." + SetupBuildTimeNumber;
AbsolutePath _thisReleaseFolder;
@@ -236,6 +242,16 @@ class Build : NukeBuild
.DependsOn(BuildServiceAndPlugins)
.Executes(() =>
{
+ //// for cswinrt
+ //NuGetTasks.NuGetInstall(_ => _
+ // .SetProcessWorkingDirectory(AppSdkSolutionFolder)
+ // .SetSource("https://api.nuget.org/v3/index.json")
+ // .SetPackageID("Microsoft.Windows.CsWinRT")
+ // .SetDependencyVersion(DependencyVersion.Highest)
+ //);
+
+
+
foreach (var platform in SdkPlatforms)
{
string solutionDir = AppSdkSolutionFolder.ToString() + @"\";
@@ -282,12 +298,12 @@ class Build : NukeBuild
// todo: it would be better to see if any of the generated winmds have changed and only
// do this step if those have changed. Maybe do a before/after date/time check?
- Console.Out.WriteLine($"NuGet Version: {NugetFullVersionString}");
+ Console.Out.WriteLine($"NuGet Version: {NugetVersionString}");
NuGetTasks.NuGetPack(_ => _
.SetTargetPath(AppSdkSolutionFolder / "projections" / "dotnet-and-cpp" / "nuget" / "Microsoft.Windows.Devices.Midi2.nuspec")
- .AddProperty("version", NugetFullVersionString)
- .AddProperty("id", NugetFullPackageId)
+ .AddProperty("version", NugetVersionString)
+ .AddProperty("id", NugetPackageId)
.SetOutputDirectory(AppSdkNugetOutputFolder)
);
@@ -303,7 +319,7 @@ class Build : NukeBuild
// copy the NuGet package over to this release
FileSystemTasks.CopyFileToDirectory(
- AppSdkNugetOutputFolder / $"{NugetFullPackageId}.{NugetFullVersionString}.nupkg",
+ AppSdkNugetOutputFolder / $"{NugetFullPackageIdWithVersion}.nupkg",
ThisReleaseFolder,
FileExistsPolicy.Overwrite,
true);
@@ -350,7 +366,7 @@ class Build : NukeBuild
{
UpdateSetupBundleInfoIncludeFile(platform);
- string fullSetupVersionString = $"{SetupVersionName} {SetupBuildMajorMinor}.{SetupBuildDateNumber}.{SetupBuildTimeNumber}";
+ //string fullSetupVersionString = $"{SetupVersionName} {SetupBuildMajorMinor}.{SetupBuildDateNumber}.{SetupBuildTimeNumber}";
string solutionDir = AppSdkSolutionFolder.ToString() + @"\";
@@ -380,7 +396,7 @@ class Build : NukeBuild
FileSystemTasks.CopyFile(
AppSdkSetupSolutionFolder / "main-bundle" / "bin" / platform / Configuration.Release / "WindowsMidiServicesSdkRuntimeSetup.exe",
- ThisReleaseFolder / $"Windows MIDI Services (Tools and SDKs) {fullSetupVersionString}-{platform.ToLower()}.exe");
+ ThisReleaseFolder / $"Windows MIDI Services (Tools and SDKs) {SetupBundleFullVersionString}-{platform.ToLower()}.exe");
}
@@ -388,13 +404,13 @@ class Build : NukeBuild
void UpdateSetupBundleInfoIncludeFile(string platform)
{
- string versionString = $"{SetupBuildMajorMinor}.{SetupBuildDateNumber}.{SetupBuildTimeNumber}";
+ //string versionString = $"{SetupBuildMajorMinor}.{SetupBuildDateNumber}.{SetupBuildTimeNumber}";
using (StreamWriter writer = System.IO.File.CreateText(SetupBundleInfoIncludeFile))
{
writer.WriteLine("");
writer.WriteLine($" ");
- writer.WriteLine($" ");
+ writer.WriteLine($" ");
writer.WriteLine("");
}
}
@@ -409,7 +425,7 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
{
UpdateSetupBundleInfoIncludeFile(platform);
- string fullSetupVersionString = $"{SetupVersionName} {SetupBuildMajorMinor}.{SetupBuildDateNumber}.{SetupBuildTimeNumber}";
+ //string fullSetupVersionString = $"{SetupVersionName} {SetupBuildMajorMinor}.{SetupBuildDateNumber}.{SetupBuildTimeNumber}";
string solutionDir = InBoxComponentsSetupSolutionFolder.ToString() + @"\";
@@ -437,7 +453,7 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
// do this copy if a new setup file was created. Maybe do a before/after date/time check?
FileSystemTasks.CopyFile(
InBoxComponentsSetupSolutionFolder / "main-bundle" / "bin" / platform / Configuration.Release / "WindowsMidiServicesInBoxComponentsSetup.exe",
- ThisReleaseFolder / $"Windows MIDI Services (In-Box Service) - {fullSetupVersionString}-{platform.ToLower()}.exe");
+ ThisReleaseFolder / $"Windows MIDI Services (In-Box Service) - {SetupBundleFullVersionString}-{platform.ToLower()}.exe");
}
});
@@ -463,7 +479,8 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
.SetProcessWorkingDirectory(MidiSettingsSolutionFolder)
.SetPreRelease(true)
.SetSource(AppSdkNugetOutputFolder)
- .SetPackageID(NugetFullPackageId)
+ .SetPackageID(NugetPackageId)
+ .SetDependencyVersion(DependencyVersion.Highest)
);
NuGetTasks.NuGetRestore(_ => _
@@ -673,7 +690,8 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
.SetProcessWorkingDirectory(MidiConsoleSolutionFolder)
.SetPreRelease(true)
.SetSource(AppSdkNugetOutputFolder)
- .SetPackageID(NugetFullPackageId)
+ .SetPackageID(NugetPackageId)
+ .SetDependencyVersion(DependencyVersion.Highest)
);
NuGetTasks.NuGetRestore(_ => _
@@ -754,49 +772,99 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
});
- //Target BuildConsoleAppInstaller => _ => _
- // .DependsOn(BuildConsoleApp)
- // .DependsOn(BuildServiceAndPluginsInstaller)
- // .Executes(() =>
- // {
- // // we build for Arm64 and x64. No EC required here
- // foreach (var platform in OutOfProcPlatforms)
- // {
- // //UpdateSetupBundleInfoIncludeFile(platform); // happens as part of service installer
- // string fullSetupVersionString = $"{SetupVersionName} {SetupBuildMajorMinor}.{SetupBuildDateNumber}.{SetupBuildTimeNumber}";
+ void RestoreNuGetPackagesForCPPProject(string vcxprojFilePath, string solutionDir, string packagesConfigFullPath)
+ {
+ var projectDir = Path.GetDirectoryName(vcxprojFilePath);
+
+ NuGetTasks.NuGetInstall(_ => _
+ .SetProcessWorkingDirectory(projectDir)
+ .SetPreRelease(true)
+ .SetSource(AppSdkNugetOutputFolder)
+ .SetPackageID(NugetPackageId)
+ .SetDependencyVersion(DependencyVersion.Highest)
+ );
+
+ NuGetTasks.NuGetRestore(_ => _
+ .SetProcessWorkingDirectory(projectDir)
+ .SetSource(AppSdkNugetOutputFolder)
+ .SetSolutionDirectory(solutionDir)
+ //.SetConfigFile(packagesConfigFullPath)
+ );
+ }
+
+ void UpdateWindowsMidiServicesSdkPackagePropertyForCppProject(string vcxprojFilePath)
+ {
+ if (File.Exists(vcxprojFilePath))
+ {
+ // this is ugly and annoying to have to do.
+ // XmlTasks.XmlPoke(configFilePath, @"/packages/package/id", NugetFullPackageId)
+
+ var doc = new XmlDocument();
+ doc.Load(vcxprojFilePath);
+
+ var manager = new XmlNamespaceManager(doc.NameTable);
+ manager.AddNamespace("msb", "http://schemas.microsoft.com/developer/msbuild/2003");
+
+ XmlElement element = doc.SelectSingleNode($"/msb:Project/msb:PropertyGroup/msb:WindowsMidiServicesSdkPackage", manager) as XmlElement;
+
+ // change the version attribute
+ if (element != null)
+ {
+ element.InnerText = NugetFullPackageIdWithVersion;
+
+ doc.Save(vcxprojFilePath);
+
+ Console.WriteLine($"Updated {vcxprojFilePath}");
+ }
+ else
+ {
+ throw new ArgumentException($"Failed to update SDK Package Value for '{vcxprojFilePath}'.");
+ }
+
+ }
+ else
+ {
+ throw new ArgumentException($"vcxproj file does not exist '{vcxprojFilePath}'.");
+ }
+
+ }
- // string solutionDir = ConsoleSetupSolutionFolder.ToString() + @"\";
+ void UpdatePackagesConfigForCPPProject(string configFilePath)
+ {
+ if (File.Exists(configFilePath))
+ {
+ // this is ugly and annoying to have to do.
+ // XmlTasks.XmlPoke(configFilePath, @"/packages/package/id", NugetFullPackageId)
- // var msbuildProperties = new Dictionary();
- // msbuildProperties.Add("Platform", platform);
- // msbuildProperties.Add("SolutionDir", solutionDir); // to include trailing slash
+ var doc = new XmlDocument();
+ doc.Load(configFilePath);
- // Console.Out.WriteLine($"----------------------------------------------------------------------");
- // Console.Out.WriteLine($"SolutionDir: {solutionDir}");
- // Console.Out.WriteLine($"Platform: {platform.ToLower()}");
+ XmlElement element = doc.SelectSingleNode($"/packages/package[@id = \"{NugetPackageId}\"]") as XmlElement;
- // var output = MSBuildTasks.MSBuild(_ => _
- // .SetTargetPath(ConsoleSetupSolutionFolder / "midi-console-setup.sln")
- // .SetMaxCpuCount(14)
- // /*.SetOutDir(outputFolder) */
- // /*.SetProcessWorkingDirectory(ApiSolutionFolder)*/
- // /*.SetTargets("Build") */
- // .SetProperties(msbuildProperties)
- // .SetConfiguration(Configuration.Release)
- // .EnableNodeReuse()
- // );
+ // change the version attribute
+ if (element != null)
+ {
+ Console.WriteLine($"Updating {element}");
+ element.SetAttribute("version", NugetVersionString);
- // // todo: it would be better to see if any of the sdk files have changed and only
- // // do this copy if a new setup file was created. Maybe do a before/after date/time check?
- // FileSystemTasks.CopyFile(
- // ConsoleSetupSolutionFolder / "console-main-bundle" / "bin" / platform / Configuration.Release / "WindowsMidiServicesConsoleSetup.exe",
- // ThisReleaseFolder / $"Windows MIDI Services (Console) - {fullSetupVersionString}-{platform.ToLower()}.exe");
- // }
+ doc.Save(configFilePath);
+ Console.WriteLine($"Updated {configFilePath}");
+ }
+ else
+ {
+ throw new ArgumentException($"Failed to update NuGet Package Value for '{configFilePath}'.");
+ }
+
+ }
+ else
+ {
+ throw new ArgumentException($"Packages.config file does not exist '{configFilePath}'.");
+ }
+ }
- // });
Target BuildCppSamples => _ => _
.DependsOn(BuildAndPackAllAppSDKs)
@@ -804,22 +872,45 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
{
var solution = SamplesCppWinRTSolutionFolder / "cpp-winrt-samples.sln";
- // update nuget packages
+ // update nuget packages for each project
+ foreach (var projectFolder in Directory.GetDirectories(SamplesCppWinRTSolutionFolder))
+ {
+ // only send paths that have a packages config in them
+
+ var configFilePath = Path.Combine(projectFolder, "packages.config");
+
+ if (File.Exists(configFilePath))
+ {
+ Console.WriteLine($"Updating {configFilePath}");
+ UpdatePackagesConfigForCPPProject(configFilePath);
+
+ var vcxprojFilePaths = Directory.GetFiles(projectFolder, "*.vcxproj");
+
+ foreach (var path in vcxprojFilePaths)
+ {
+ Console.WriteLine($"Updating {path}");
+ UpdateWindowsMidiServicesSdkPackagePropertyForCppProject(path);
+
+ // nuget restore
+ RestoreNuGetPackagesForCPPProject(path, SamplesCppWinRTSolutionFolder, configFilePath);
+
+ }
+ }
+ else
+ {
+ Console.WriteLine($"Not a project folder {projectFolder}");
+ }
+
+ }
+
- // for the MIDI nuget package
- NuGetTasks.NuGetInstall(_ => _
- .SetProcessWorkingDirectory(SamplesCppWinRTSolutionFolder)
- .SetPreRelease(true)
- .SetSource(AppSdkNugetOutputFolder)
- .SetPackageID(NugetFullPackageId)
- );
// for cppwinrt
NuGetTasks.NuGetInstall(_ => _
.SetProcessWorkingDirectory(SamplesCppWinRTSolutionFolder)
- .SetPreRelease(true)
.SetSource("https://api.nuget.org/v3/index.json")
.SetPackageID("Microsoft.Windows.CppWinRT")
+ .SetDependencyVersion(DependencyVersion.Highest)
);
// for WIL
@@ -831,15 +922,24 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
//);
- NuGetTasks.NuGetRestore(_ => _
- .SetProcessWorkingDirectory(SamplesCppWinRTSolutionFolder)
- .SetSolutionDirectory(SamplesCppWinRTSolutionFolder)
- .SetSource(AppSdkNugetOutputFolder)
- /*.SetConfigFile(solution)*/
- );
+ // for the MIDI nuget package
+ // the install and restore should work with the above
+ // manual managing of the packages.config
+ //NuGetTasks.NuGetInstall(_ => _
+ // .SetProcessWorkingDirectory(SamplesCppWinRTSolutionFolder)
+ // .SetPreRelease(true)
+ // .SetSource(AppSdkNugetOutputFolder)
+ // .SetPackageID(NugetFullPackageId)
+ // .SetDependencyVersion(DependencyVersion.Highest)
+ //);
+
+ //NuGetTasks.NuGetRestore(_ => _
+ // .SetProcessWorkingDirectory(SamplesCppWinRTSolutionFolder)
+ // .SetSolutionDirectory(SamplesCppWinRTSolutionFolder)
+ // .SetSource(AppSdkNugetOutputFolder)
+ //);
-
// make sure they compile
foreach (var platform in NativeSamplesPlatforms)
{
@@ -875,6 +975,81 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
});
+ Target BuildCSharpSamples => _ => _
+ .DependsOn(BuildAndPackAllAppSDKs)
+ .Executes(() =>
+ {
+ var solution = SamplesCSWinRTSolutionFolder / "csharp-net-samples.sln";
+
+
+ // for cswinrt
+ NuGetTasks.NuGetInstall(_ => _
+ .SetProcessWorkingDirectory(SamplesCSWinRTSolutionFolder)
+ .SetSource("https://api.nuget.org/v3/index.json")
+ .SetPackageID("Microsoft.Windows.CsWinRT")
+ .SetDependencyVersion(DependencyVersion.Highest)
+ );
+
+
+ // for the MIDI nuget package
+ // the install and restore should work with the above
+ // manual managing of the packages.config
+ NuGetTasks.NuGetInstall(_ => _
+ .SetProcessWorkingDirectory(SamplesCSWinRTSolutionFolder)
+ .SetPreRelease(true)
+ .SetSource(AppSdkNugetOutputFolder)
+ .SetPackageID(NugetPackageId)
+ .SetDependencyVersion(DependencyVersion.Highest)
+ );
+
+ NuGetTasks.NuGetRestore(_ => _
+ .SetProcessWorkingDirectory(SamplesCSWinRTSolutionFolder)
+ .SetSolutionDirectory(SamplesCSWinRTSolutionFolder)
+ .SetSource(AppSdkNugetOutputFolder)
+ );
+
+
+ // make sure they compile
+ foreach (var platform in ManagedSamplesPlatforms)
+ {
+ string rid = platform.ToLower() == "arm64" ? "win-arm64" : "win-x64";
+
+ //DotNetTasks.DotNetBuild(_ => _
+ // .SetProjectFile(SamplesCSWinRTSolutionFolder / "Midi" / "Midi.csproj")
+ // .SetConfiguration(Configuration.Release)
+ // .SetPublishSingleFile(false)
+ // .SetPublishTrimmed(false)
+ // .SetSelfContained(false)
+ // .SetRuntime(rid)
+ //);
+
+
+ var msbuildProperties = new Dictionary();
+ msbuildProperties.Add("Platform", platform);
+ msbuildProperties.Add("SolutionDir", SamplesCSWinRTSolutionFolder); // to include trailing slash
+ //msbuildProperties.Add("NoWarn", "MSB3271"); // winmd and dll platform mismatch with Arm64EC
+
+ Console.Out.WriteLine($"----------------------------------------------------------------------");
+ Console.Out.WriteLine($"Solution: {solution}");
+ Console.Out.WriteLine($"SolutionDir: {SamplesCSWinRTSolutionFolder}");
+ Console.Out.WriteLine($"Platform: {platform}");
+
+
+ MSBuildTasks.MSBuild(_ => _
+ .SetTargetPath(solution)
+ .SetMaxCpuCount(14)
+ /*.SetOutDir(outputFolder) */
+ .SetProcessWorkingDirectory(SamplesCSWinRTSolutionFolder)
+ /*.SetTargets("Build") */
+ .SetProperties(msbuildProperties)
+ .SetConfiguration(Configuration.Release)
+ //.SetVerbosity(MSBuildVerbosity.Minimal)
+ .EnableNodeReuse()
+ );
+ }
+ });
+
+
// hard-coded paths to just get around some runtime limitations. This should
// be re-done to make this build more portable
@@ -1081,13 +1256,13 @@ void UpdateSetupBundleInfoIncludeFile(string platform)
.DependsOn(Prerequisites)
.DependsOn(BuildServiceAndPlugins)
.DependsOn(BuildServiceAndPluginsInstaller)
-
.DependsOn(BuildAndPackAllAppSDKs)
.DependsOn(BuildConsoleApp)
.DependsOn(BuildSettingsApp)
.DependsOn(BuildAppSdkRuntimeAndToolsInstaller)
// .DependsOn(BuildAndPackageElectronProjection)
- // .DependsOn(BuildCppSamples)
+ .DependsOn(BuildCppSamples)
+ .DependsOn(BuildCSharpSamples)
.Executes(() =>
{
});
diff --git a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Initialization.dll b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Initialization.dll
index 0e2fb362..b20c2672 100644
Binary files a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Initialization.dll and b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.Initialization.dll differ
diff --git a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.dll b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.dll
index b08f91fb..ff7d1a4b 100644
Binary files a/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.dll and b/build/staging/app-sdk/Arm64EC/Microsoft.Windows.Devices.Midi2.dll differ
diff --git a/build/staging/version/BundleInfo.wxi b/build/staging/version/BundleInfo.wxi
index 72102839..6df19ba0 100644
--- a/build/staging/version/BundleInfo.wxi
+++ b/build/staging/version/BundleInfo.wxi
@@ -1,4 +1,4 @@
-
+
diff --git a/docs/index.md b/docs/index.md
index 834b9c53..8ac4163d 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -7,6 +7,8 @@ has_children: false
**NOTE: These docs are currently a work-in-progress**
+The best place for questions and to stay up to date is on our Discord server. The best place to report bugs, as a developer, is the GitHub repo.
+
Windows MIDI Services is an open source project, which has been developed with input and feedback from the community.
> [Source repo and developer releases on GitHub](https://aka.ms/midirepo)
@@ -41,11 +43,9 @@ While we're in developer preview, get started by downloading and installing the
## Release Plans
-We currently plan to release Windows MIDI Services in-box in the latest version of Windows by the end of this calendar year. We will then back-port to the supported versions of Windows 11 and the latest supported Window 10 shortly afterwards.
-
-(Plans are always subject to change, especially with quality-driven deliverables, but that's what we're currently working towards)
+We'll soon have Windows MIDI Services in Windows Insider releases. The first few releases will be opt-in for people who request access on our Discord server, as they are not complete and they *will* break some current MIDI applications. After that, we'll open it up more broadly.
-The MIDI console and Settings app are planned to ship and be services through the Microsoft Store on Windows.
+After that, our release plan for the service, plugins, and API is to release when our customers, partners, and internal reviews are all happy with the results, especially backwards compatibility. This is currently expected to happen in the first half of CY 2025.
## Developer Samples
diff --git a/samples/cpp-winrt/basics/client-basics-cpp.vcxproj b/samples/cpp-winrt/basics/client-basics-cpp.vcxproj
index 11af4055..57b52860 100644
--- a/samples/cpp-winrt/basics/client-basics-cpp.vcxproj
+++ b/samples/cpp-winrt/basics/client-basics-cpp.vcxproj
@@ -1,8 +1,8 @@
-
+
-
+ Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24294.2109
true
true
false
@@ -16,6 +16,7 @@
true
client-basics-cpp
+
@@ -167,7 +168,7 @@
-
+
@@ -175,7 +176,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/basics/packages.config b/samples/cpp-winrt/basics/packages.config
index 0eb8ee6d..8f78e13f 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 dea9eb40..eda7aa91 100644
--- a/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj
+++ b/samples/cpp-winrt/loopback-endpoints/loopback-endpoints-cpp.vcxproj
@@ -1,8 +1,8 @@
-
+
-
+ Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24294.2109
true
true
true
@@ -15,6 +15,7 @@
10.0.20348.0
+
Debug
@@ -157,7 +158,7 @@
-
+
@@ -165,7 +166,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/loopback-endpoints/packages.config b/samples/cpp-winrt/loopback-endpoints/packages.config
index 0eb8ee6d..8f78e13f 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 0eb8ee6d..8f78e13f 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 cac0ac92..df6ebbda 100644
--- a/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj
+++ b/samples/cpp-winrt/send-speed/send-speed-cpp.vcxproj
@@ -1,8 +1,8 @@
-
+
-
+ Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24294.2109
true
true
true
@@ -17,6 +17,7 @@
send-speed-cpp
+
Debug
@@ -167,7 +168,7 @@
-
+
@@ -175,7 +176,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/static-enum-endpoints/main.cpp b/samples/cpp-winrt/static-enum-endpoints/main.cpp
index 7685b0d8..8dca2555 100644
--- a/samples/cpp-winrt/static-enum-endpoints/main.cpp
+++ b/samples/cpp-winrt/static-enum-endpoints/main.cpp
@@ -159,7 +159,7 @@ int main()
std::cout << "- Transport-supplied Name: " << winrt::to_string(transportInfo.Name) << std::endl;
std::cout << "- Description: " << winrt::to_string(transportInfo.Description) << std::endl;
std::cout << "- Transport Id: " << winrt::to_string(winrt::to_hstring(transportInfo.TransportId)) << std::endl;
- std::cout << "- Transport Mnemonic: " << winrt::to_string(transportInfo.TransportAbbreviation) << std::endl;
+ std::cout << "- Transport Code: " << winrt::to_string(transportInfo.TransportCode) << std::endl;
if (transportInfo.NativeDataFormat == MidiEndpointNativeDataFormat::Midi1ByteFormat)
{
diff --git a/samples/cpp-winrt/static-enum-endpoints/packages.config b/samples/cpp-winrt/static-enum-endpoints/packages.config
index 0eb8ee6d..8f78e13f 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 40c129c7..36ea0191 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
@@ -1,8 +1,8 @@
-
+
-
+ Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24294.2109
true
true
true
@@ -16,6 +16,7 @@
true
static-enum-endpoints-cpp
+
@@ -167,7 +168,7 @@
-
+
@@ -175,7 +176,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/virtual-device-app-winui/packages.config b/samples/cpp-winrt/virtual-device-app-winui/packages.config
index 0390d5cd..f4115b2c 100644
--- a/samples/cpp-winrt/virtual-device-app-winui/packages.config
+++ b/samples/cpp-winrt/virtual-device-app-winui/packages.config
@@ -1,7 +1,7 @@
-
+
diff --git a/samples/cpp-winrt/virtual-device-app-winui/virtual-device-app-winui.vcxproj b/samples/cpp-winrt/virtual-device-app-winui/virtual-device-app-winui.vcxproj
index 8ff1545f..4f259b9c 100644
--- a/samples/cpp-winrt/virtual-device-app-winui/virtual-device-app-winui.vcxproj
+++ b/samples/cpp-winrt/virtual-device-app-winui/virtual-device-app-winui.vcxproj
@@ -1,10 +1,10 @@
-
+ Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24294.2109
true
true
true
@@ -27,6 +27,7 @@
true
true
+
@@ -215,7 +216,7 @@
-
+
@@ -228,7 +229,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/samples/cpp-winrt/watch-endpoints/packages.config b/samples/cpp-winrt/watch-endpoints/packages.config
index 0eb8ee6d..8f78e13f 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 995afb85..b6a66a2c 100644
--- a/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj
+++ b/samples/cpp-winrt/watch-endpoints/watch-endpoints-cpp.vcxproj
@@ -1,8 +1,8 @@
-
+
-
+ Microsoft.Windows.Devices.Midi2.1.0.1-preview.7.24294.2109
true
true
true
@@ -16,6 +16,7 @@
true
watch-endpoints-cpp
+
@@ -167,7 +168,7 @@
-
+
@@ -175,7 +176,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/src/api/Abstraction/MidiSrvAbstraction/Midi2.MidiSrvConfigurationManager.cpp b/src/api/Abstraction/MidiSrvAbstraction/Midi2.MidiSrvConfigurationManager.cpp
index 2ecc1398..c9f90e36 100644
--- a/src/api/Abstraction/MidiSrvAbstraction/Midi2.MidiSrvConfigurationManager.cpp
+++ b/src/api/Abstraction/MidiSrvAbstraction/Midi2.MidiSrvConfigurationManager.cpp
@@ -75,7 +75,7 @@ CMidi2MidiSrvConfigurationManager::UpdateConfiguration(LPCWSTR configurationJson
_Use_decl_annotations_
HRESULT
CMidi2MidiSrvConfigurationManager::GetTransportList(LPWSTR* transportListJson)
-{
+{
TraceLoggingWrite(
MidiSrvAbstractionTelemetryProvider::Provider(),
MIDI_TRACE_EVENT_INFO,
@@ -91,6 +91,9 @@ CMidi2MidiSrvConfigurationManager::GetTransportList(LPWSTR* transportListJson)
RETURN_IF_FAILED([&]()
{
+ // RPC requirement
+ //*transportListJson = 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(MidiSrvGetTransportList(bindingHandle.get(), transportListJson));
diff --git a/src/api/Abstraction/MidiSrvAbstraction/Midi2.MidiSrvConfigurationManager.h b/src/api/Abstraction/MidiSrvAbstraction/Midi2.MidiSrvConfigurationManager.h
index 03d37b83..0639de5a 100644
--- a/src/api/Abstraction/MidiSrvAbstraction/Midi2.MidiSrvConfigurationManager.h
+++ b/src/api/Abstraction/MidiSrvAbstraction/Midi2.MidiSrvConfigurationManager.h
@@ -25,6 +25,8 @@ class CMidi2MidiSrvConfigurationManager :
STDMETHOD(GetTransportList(_Out_ LPWSTR* transportListJson));
+ //STDMETHOD(GetTransportList(_In_ DWORD transportMetadataStructSize, _In_ PTRANSPORTMETADATA transportList, _Inout_ DWORD* transportCount);
+
STDMETHOD(GetTransformList(_Out_ LPWSTR* transformListJson));
private:
diff --git a/src/api/Client/WinMM/MidiSrvPorts.cpp b/src/api/Client/WinMM/MidiSrvPorts.cpp
index 60d58590..6e4799d3 100644
--- a/src/api/Client/WinMM/MidiSrvPorts.cpp
+++ b/src/api/Client/WinMM/MidiSrvPorts.cpp
@@ -235,10 +235,18 @@ CMidiPorts::GetMidiDeviceCount(MidiFlow flow, UINT32& count)
// all others with a service assigned port number goes into the portInfo structure for processing.
auto prop = device.Properties().Lookup(winrt::to_hstring(STRING_PKEY_MIDI_ServiceAssignedPortNumber));
+
+
if (prop)
{
- servicePortNum = winrt::unbox_value(prop);
- servicePortNumValid = true;
+// servicePortNum = winrt::unbox_value(prop);
+
+ std::optional servicePortNumValue = prop.try_as();
+ if (servicePortNumValue != std::nullopt && servicePortNumValue.has_value())
+ {
+ servicePortNum = servicePortNumValue.value();
+ servicePortNumValid = true;
+ }
}
if (servicePortNumValid)
diff --git a/src/api/Inc/json_helpers.h b/src/api/Inc/json_helpers.h
index ac3d18a0..45198320 100644
--- a/src/api/Inc/json_helpers.h
+++ b/src/api/Inc/json_helpers.h
@@ -102,6 +102,8 @@ namespace WindowsMidiServicesInternal
}
+ // *outParam = (LPWSTR)(obj.Stringify().c_str());
+
return false;
}
diff --git a/src/api/Service/Exe/MidiConfigurationManager.cpp b/src/api/Service/Exe/MidiConfigurationManager.cpp
index fe7b72d4..be4e1a71 100644
--- a/src/api/Service/Exe/MidiConfigurationManager.cpp
+++ b/src/api/Service/Exe/MidiConfigurationManager.cpp
@@ -126,8 +126,25 @@ std::vector CMidiConfigurationManager::GetEnabledTransports() const noexce
if (result == NOERROR)
{
- // Add to the vector
- availableAbstractionLayers.push_back(abstractionLayerGuid);
+ // verify that there are no existing entries for this class id
+
+ if (std::find(availableAbstractionLayers.begin(), availableAbstractionLayers.end(), abstractionLayerGuid) == availableAbstractionLayers.end())
+ {
+ // Doesn't already exist, so add to the vector
+ availableAbstractionLayers.push_back(abstractionLayerGuid);
+ }
+ else
+ {
+ TraceLoggingWrite(
+ MidiSrvTelemetryProvider::Provider(),
+ MIDI_TRACE_EVENT_WARNING,
+ TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
+ TraceLoggingLevel(WINEVENT_LEVEL_WARNING),
+ TraceLoggingWideString(L"Duplicate transport GUID in registry", MIDI_TRACE_EVENT_MESSAGE_FIELD),
+ TraceLoggingGuid(abstractionLayerGuid, "id"),
+ TraceLoggingPointer(this, "this")
+ );
+ }
}
}
@@ -147,12 +164,13 @@ std::vector CMidiConfigurationManager::GetEnabledTransports() const noexce
// TODO: Refactor these two methods and abstract out the registry code. Do this once wil adds the enumeration helpers to the NuGet
std::vector CMidiConfigurationManager::GetEnabledEndpointProcessingTransforms() const noexcept
{
- std::vector availableAbstractionLayers;
+ std::vector availableTransforms;
- // the diagnostics abstraction is always instantiated. We don't want to take the
- // chance someone removes this from the registry, so it's hard-coded here. It's
- // needed for support, tools, diagnostics, etc.
- availableAbstractionLayers.push_back(__uuidof(Midi2DiagnosticsAbstraction));
+ // TODO: We'll want to add the required transforms here, like the translation ones
+ // availableTransforms.push_back(__uuidof(Midi2BS2UMPTransform));
+ // availableTransforms.push_back(__uuidof(Midi2UMP2BSTransform));
+ // availableTransforms.push_back(__uuidof(Midi2ProtocolDownscalerTransform));
+ // availableTransforms.push_back(__uuidof(Midi2SchedulerTransform));
try
{
@@ -214,7 +232,7 @@ std::vector CMidiConfigurationManager::GetEnabledEndpointProcessingTransfo
if (retCode == ERROR_SUCCESS)
{
- DWORD abstractionEnabled = 1;
+ DWORD transformEnabled = 1;
// Check to see if that sub key has an Enabled value.
@@ -226,32 +244,51 @@ std::vector CMidiConfigurationManager::GetEnabledEndpointProcessingTransfo
try
{
- // is the abstraction layer enabled? > 0 or missing Enabled value mean it is
- abstractionEnabled = wil::reg::get_value(pluginKey.get(), MIDI_PLUGIN_ENABLED_REG_VALUE);
+ // is the transform enabled? > 0 or missing Enabled value mean it is
+ transformEnabled = wil::reg::get_value(pluginKey.get(), MIDI_PLUGIN_ENABLED_REG_VALUE);
}
catch (...)
{
// value doesn't exist, so we default to enabled
- abstractionEnabled = (DWORD)1;
+ transformEnabled = (DWORD)1;
}
// we only proceed with this abstraction entry if it's enabled
- if (abstractionEnabled > 0)
+ if (transformEnabled > 0)
{
try
{
- GUID abstractionLayerGuid;
+ GUID transformGuid;
auto clsidString = wil::reg::get_value(pluginKey.get(), MIDI_PLUGIN_CLSID_REG_VALUE);
- auto result = CLSIDFromString((LPCTSTR)clsidString.c_str(), (LPGUID)&abstractionLayerGuid);
+ auto result = CLSIDFromString((LPCTSTR)clsidString.c_str(), (LPGUID)&transformGuid);
LOG_IF_FAILED(result);
if (result == NOERROR)
{
// Add to the vector
- availableAbstractionLayers.push_back(abstractionLayerGuid);
+ availableTransforms.push_back(transformGuid);
+ }
+
+
+ if (std::find(availableTransforms.begin(), availableTransforms.end(), transformGuid) == availableTransforms.end())
+ {
+ // Doesn't already exist, so add to the vector
+ availableTransforms.push_back(transformGuid);
+ }
+ else
+ {
+ TraceLoggingWrite(
+ MidiSrvTelemetryProvider::Provider(),
+ MIDI_TRACE_EVENT_WARNING,
+ TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
+ TraceLoggingLevel(WINEVENT_LEVEL_WARNING),
+ TraceLoggingWideString(L"Duplicate transform GUID in registry", MIDI_TRACE_EVENT_MESSAGE_FIELD),
+ TraceLoggingGuid(transformGuid, "id"),
+ TraceLoggingPointer(this, "this")
+ );
}
}
@@ -265,7 +302,7 @@ std::vector CMidiConfigurationManager::GetEnabledEndpointProcessingTransfo
CATCH_LOG()
// return a copy
- return availableAbstractionLayers;
+ return availableTransforms;
}
@@ -281,18 +318,18 @@ std::vector CMidiConfigurationManager::GetAllEnabledTransport
std::vector results{};
- auto abstractionIdList = GetEnabledTransports();
+ auto transportIdList = GetEnabledTransports();
// for each item in the list, activate the MidiServiceAbstractionPlugin and get the metadata
- for (auto const& abstractionId : abstractionIdList)
+ for (auto const& transportId : transportIdList)
{
- wil::com_ptr_nothrow midiAbstraction;
+ wil::com_ptr_nothrow midiTransport;
wil::com_ptr_nothrow plugin;
- if (SUCCEEDED(CoCreateInstance(abstractionId, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&midiAbstraction))))
+ if (SUCCEEDED(CoCreateInstance(transportId, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&midiTransport))))
{
- if (SUCCEEDED(midiAbstraction->Activate(__uuidof(IMidiServiceTransportPluginMetadataProvider), (void**)&plugin)))
+ if (SUCCEEDED(midiTransport->Activate(__uuidof(IMidiServiceTransportPluginMetadataProvider), (void**)&plugin)))
{
plugin->Initialize();
@@ -314,7 +351,7 @@ std::vector CMidiConfigurationManager::GetAllEnabledTransport
TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
TraceLoggingWideString(L"Unable to activate IMidiServiceAbstractionPlugin", MIDI_TRACE_EVENT_MESSAGE_FIELD),
- TraceLoggingGuid(abstractionId, "abstraction id"),
+ TraceLoggingGuid(transportId, "transport id"),
TraceLoggingPointer(this, "this")
);
}
diff --git a/src/api/Service/Exe/MidiSrvRPC.idl b/src/api/Service/Exe/MidiSrvRPC.idl
index d3f2069c..49b9767d 100644
--- a/src/api/Service/Exe/MidiSrvRPC.idl
+++ b/src/api/Service/Exe/MidiSrvRPC.idl
@@ -131,7 +131,18 @@ interface MidiSrvRPC
HRESULT MidiSrvGetTransportList(
[in] handle_t bindingHandle,
- [out, string] LPWSTR* transportListJson);
+ [out] LPWSTR* transportListJson);
+
+ // call with null transportList pointer to get a count of transports
+ // call again with transportList pointing to an appropriately-sized buffer
+ // and transportCount set to the value from the previous call. If count changes
+ // in between calls, failed hresult is returned.
+ //HRESULT MidiSrvGetTransportList(
+ // [in] handle_t bindingHandle,
+ // [in] DWORD transportMetadataStructSize,
+ // [in, out] DWORD* transportCount,
+ // [out, size_is(transportMetadataStructSize), length_is(transportCount)] PTRANSPORTMETADATA transportList
+ // );
HRESULT MidiSrvGetTransformList(
[in] handle_t bindingHandle,
diff --git a/src/api/Service/Exe/MidiSrvRpc.cpp b/src/api/Service/Exe/MidiSrvRpc.cpp
index 6b85e6bc..32c8836c 100644
--- a/src/api/Service/Exe/MidiSrvRpc.cpp
+++ b/src/api/Service/Exe/MidiSrvRpc.cpp
@@ -443,25 +443,24 @@ MidiSrvGetTransportList(
{
// add to result object
- json::JsonObject abstractionObject;
+ json::JsonObject transportObject;
- if (metadata.Name != NULL) abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_NAME_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.Name));
- if (metadata.TransportCode != NULL) abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_TRANSPORT_CODE_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.TransportCode));
- if (metadata.Description != NULL) abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_DESCRIPTION_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.Description));
- if (metadata.Author != NULL) abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_AUTHOR_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.Author));
- if (metadata.SmallImagePath != NULL) abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_SMALL_IMAGE_PATH_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.SmallImagePath));
- if (metadata.Version != NULL) abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_VERSION_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.Version));
- abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_RT_CREATABLE_APPS_PROPERTY_KEY, json::JsonValue::CreateBooleanValue(metadata.Flags & MetadataFlags_IsRuntimeCreatableByApps));
- abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_RT_CREATABLE_SETTINGS_PROPERTY_KEY, json::JsonValue::CreateBooleanValue(metadata.Flags & MetadataFlags_IsRuntimeCreatableBySettings));
- abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_SYSTEM_MANAGED_PROPERTY_KEY, json::JsonValue::CreateBooleanValue(metadata.Flags & MetadataFlags_IsSystemManaged));
- abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_CLIENT_CONFIGURABLE_PROPERTY_KEY, json::JsonValue::CreateBooleanValue(metadata.Flags & MetadataFlags_IsClientConfigurable));
+ if (metadata.Name != NULL) transportObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_NAME_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.Name));
+ if (metadata.TransportCode != NULL) transportObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_TRANSPORT_CODE_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.TransportCode));
+ if (metadata.Description != NULL) transportObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_DESCRIPTION_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.Description));
+ if (metadata.Author != NULL) transportObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_AUTHOR_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.Author));
+ if (metadata.SmallImagePath != NULL) transportObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_SMALL_IMAGE_PATH_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.SmallImagePath));
+ if (metadata.Version != NULL) transportObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_VERSION_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.Version));
+ transportObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_RT_CREATABLE_APPS_PROPERTY_KEY, json::JsonValue::CreateBooleanValue(metadata.Flags & MetadataFlags_IsRuntimeCreatableByApps));
+ transportObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_RT_CREATABLE_SETTINGS_PROPERTY_KEY, json::JsonValue::CreateBooleanValue(metadata.Flags & MetadataFlags_IsRuntimeCreatableBySettings));
+ transportObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_SYSTEM_MANAGED_PROPERTY_KEY, json::JsonValue::CreateBooleanValue(metadata.Flags & MetadataFlags_IsSystemManaged));
+ transportObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_CLIENT_CONFIGURABLE_PROPERTY_KEY, json::JsonValue::CreateBooleanValue(metadata.Flags & MetadataFlags_IsClientConfigurable));
// if (metadata.ClientConfigurationAssemblyName != NULL) abstractionObject.SetNamedValue(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_CLIENT_CONFIG_ASSEMBLY_PROPERTY_KEY, json::JsonValue::CreateStringValue(metadata.ClientConfigurationAssemblyName));
// add the abstraction metadata to the root, using the abstraction id as the key
- rootObject.SetNamedValue(internal::GuidToString(metadata.TransportId).c_str(), abstractionObject);
+ rootObject.SetNamedValue(internal::GuidToString(metadata.TransportId).c_str(), transportObject);
// We need to free all the strings in the struct. I hate this pattern.
-
SAFE_COTASKMEMFREE(metadata.Name);
SAFE_COTASKMEMFREE(metadata.TransportCode);
SAFE_COTASKMEMFREE(metadata.Description);
@@ -489,6 +488,86 @@ MidiSrvGetTransportList(
return S_OK;
}
+//HRESULT
+//MidiSrvGetTransportList(
+// /*[in]*/ handle_t bindingHandle,
+// /*[in]*/ DWORD transportMetadataStructSize,
+// __RPC__in PTRANSPORTMETADATA transportList,
+// __RPC__inout DWORD* transportCount
+//)
+//{
+// TraceLoggingWrite(
+// MidiSrvTelemetryProvider::Provider(),
+// MIDI_TRACE_EVENT_INFO,
+// TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
+// TraceLoggingLevel(WINEVENT_LEVEL_INFO),
+// TraceLoggingWideString(L"Enter")
+// );
+//
+// UNREFERENCED_PARAMETER(bindingHandle);
+// RETURN_HR_IF_NULL(E_INVALIDARG, transportCount);
+//
+// std::shared_ptr configManager;
+//
+// auto coInit = wil::CoInitializeEx(COINIT_MULTITHREADED);
+//
+// RETURN_IF_FAILED(g_MidiService->GetConfigurationManager(configManager));
+// auto allMetadata = configManager->GetAllEnabledTransportMetadata();
+//
+// DWORD structCount = allMetadata.size();
+//
+// // if null is passed in, we just measure and return the data
+// if (transportList == nullptr)
+// {
+// // return the count
+// if (transportMetadataStructSize == sizeof(TRANSPORTMETADATA))
+// {
+// *transportCount = structCount;
+//
+// return S_OK;
+// }
+// else
+// {
+// // unexpected struct size
+// RETURN_IF_FAILED(E_INVALIDARG);
+// }
+// }
+// else
+// {
+// // transportList is not nullptr
+//
+// if (*transportCount != structCount)
+// {
+// // transport count has changed in between calls
+// RETURN_IF_FAILED(E_INVALIDARG);
+// }
+//
+// // transportList is valid pointer, struct count is expected number, size is as expected
+// // copy the metadata over into the provided buffer
+//
+//
+//
+// }
+//
+//
+//
+//
+// // TODO: This code should probably live in the configuration manager instead of the RPC layer
+//
+//
+// TraceLoggingWrite(
+// MidiSrvTelemetryProvider::Provider(),
+// MIDI_TRACE_EVENT_INFO,
+// TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
+// TraceLoggingLevel(WINEVENT_LEVEL_INFO),
+// TraceLoggingWideString(L"Exit success")
+// );
+//
+// return S_OK;
+//}
+
+
+
HRESULT
MidiSrvGetTransformList(
/*[in]*/ handle_t bindingHandle,
diff --git a/src/app-sdk/mididiag/main.cpp b/src/app-sdk/mididiag/main.cpp
index 0e24d6ca..2a79669f 100644
--- a/src/app-sdk/mididiag/main.cpp
+++ b/src/app-sdk/mididiag/main.cpp
@@ -186,6 +186,99 @@ void OutputError(_In_ std::wstring const& errorMessage)
#define RETURN_FAIL return 1
+void OutputRegStringValue(std::wstring label, HKEY const key, std::wstring value)
+{
+ auto keyValue = wil::reg::try_get_value_string(key, value.c_str());
+ if (keyValue.has_value())
+ {
+ OutputStringField(label, keyValue.value());
+ }
+ else
+ {
+ OutputStringField(label, std::wstring{ L"Not present" });
+ }
+}
+
+// dword value > 0 == true
+void OutputRegDWordBooleanValue(std::wstring label, HKEY const key, std::wstring value)
+{
+ auto keyValue = wil::reg::try_get_value_dword(key, value.c_str());
+ if (keyValue.has_value())
+ {
+ OutputBooleanField(label, keyValue.value() > 0);
+ }
+ else
+ {
+ OutputStringField(label, std::wstring{ L"Not present" });
+ }
+}
+
+bool DoSectionRegistryEntries(_In_ bool const verbose)
+{
+ UNREFERENCED_PARAMETER(verbose);
+
+ OutputSectionHeader(MIDIDIAG_SECTION_LABEL_ENUM_REGISTRY);
+
+ try
+ {
+ // check to see if the root is there
+
+ const auto rootKey = wil::reg::open_unique_key(HKEY_LOCAL_MACHINE, MIDI_ROOT_REG_KEY, wil::reg::key_access::read);
+
+ // list all values in the root
+
+ OutputRegStringValue(MIDIDIAG_FIELD_LABEL_REGISTRY_ROOT_CURRENT_CONFIG, rootKey.get(), MIDI_CONFIG_FILE_REG_VALUE);
+ OutputRegDWordBooleanValue(MIDIDIAG_FIELD_LABEL_REGISTRY_ROOT_DISCOVERY_ENABLED, rootKey.get(), MIDI_DISCOVERY_ENABLED_REG_VALUE);
+ OutputRegDWordBooleanValue(MIDIDIAG_FIELD_LABEL_REGISTRY_ROOT_USE_MMCSS, rootKey.get(), MIDI_USE_MMCSS_REG_VALUE);
+ OutputItemSeparator();
+
+ // TODO: list all values under the desktop app sdk runtime
+
+
+ // TODO: list all values under message processing plugins
+
+
+
+ // list all values under transport plugins
+
+ const auto transportPluginsKey = wil::reg::open_unique_key(HKEY_LOCAL_MACHINE, MIDI_ROOT_TRANSPORT_PLUGINS_REG_KEY);
+
+ for (const auto& keyData : wil::make_range(wil::reg::key_iterator{ transportPluginsKey.get() }, wil::reg::key_iterator{}))
+ {
+ // name of the transport in the registry (this doesn't really mean anything)
+ OutputStringField(MIDIDIAG_FIELD_LABEL_REGISTRY_TRANSPORT_NAME, keyData.name);
+
+ const auto key = wil::reg::open_unique_key(HKEY_LOCAL_MACHINE, std::wstring(std::wstring(MIDI_ROOT_TRANSPORT_PLUGINS_REG_KEY) + L"\\" + keyData.name).c_str());
+
+ OutputRegStringValue(MIDIDIAG_FIELD_LABEL_REGISTRY_TRANSPORT_CLSID, key.get(), MIDI_PLUGIN_CLSID_REG_VALUE);
+ OutputRegDWordBooleanValue(MIDIDIAG_FIELD_LABEL_REGISTRY_TRANSPORT_ENABLED, key.get(), MIDI_PLUGIN_ENABLED_REG_VALUE);
+
+ OutputItemSeparator();
+ }
+ }
+ catch (...)
+ {
+ OutputError(L"Could not open required registry key(s).");
+
+ return false;
+ }
+
+ return true;
+}
+
+bool DoSectionCOMComponents(_In_ bool const verbose)
+{
+ UNREFERENCED_PARAMETER(verbose);
+
+ OutputSectionHeader(MIDIDIAG_SECTION_LABEL_ENUM_COM);
+
+
+ return true;
+
+}
+
+
+
bool DoSectionTransports(_In_ bool const verbose)
{
UNREFERENCED_PARAMETER(verbose);
@@ -709,6 +802,12 @@ int __cdecl main()
if (!DoSectionClock(verbose)) RETURN_FAIL;
}
+
+ DoSectionRegistryEntries(verbose);
+
+ DoSectionCOMComponents(verbose);
+
+
if (!DoSectionServiceStatus(verbose)) RETURN_FAIL;
auto transportsWorked = DoSectionTransports(verbose);
diff --git a/src/app-sdk/mididiag/mididiag.vcxproj b/src/app-sdk/mididiag/mididiag.vcxproj
index 8d2aee83..4bc1d93a 100644
--- a/src/app-sdk/mididiag/mididiag.vcxproj
+++ b/src/app-sdk/mididiag/mididiag.vcxproj
@@ -193,6 +193,7 @@
+
@@ -200,5 +201,6 @@
+
\ No newline at end of file
diff --git a/src/app-sdk/mididiag/mididiag_field_defs.h b/src/app-sdk/mididiag/mididiag_field_defs.h
index 9ff1ffc0..be9f2e8c 100644
--- a/src/app-sdk/mididiag/mididiag_field_defs.h
+++ b/src/app-sdk/mididiag/mididiag_field_defs.h
@@ -22,6 +22,29 @@
#define MIDIDIAG_FIELD_LABEL_ERROR L"ERROR"
+#define MIDIDIAG_SECTION_LABEL_ENUM_REGISTRY L"enum_registry"
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_VALUE L"transport_id"
+
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_ROOT L"reg_root"
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_ROOT_DISCOVERY_ENABLED L"reg_discovery_enabled"
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_ROOT_USE_MMCSS L"reg_use_mmcss"
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_ROOT_CURRENT_CONFIG L"reg_current_config"
+
+
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_SDK_ARM64X L"reg_sdk_arm64x"
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_SDK_X64 L"registry_sdk_x64"
+
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_TRANSPORTS L"reg_transports"
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_TRANSPORT_NAME L"reg_transport_name"
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_TRANSPORT_CLSID L"reg_transport_clsid"
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_TRANSPORT_ENABLED L"reg_transport_enabled"
+
+#define MIDIDIAG_FIELD_LABEL_REGISTRY_TRANSFORMS L"reg_transforms"
+
+
+#define MIDIDIAG_SECTION_LABEL_ENUM_COM L"enum_com"
+
+
#define MIDIDIAG_SECTION_LABEL_ENUM_TRANSPORTS L"enum_transports"
#define MIDIDIAG_FIELD_LABEL_TRANSPORT_ID L"transport_id"
#define MIDIDIAG_FIELD_LABEL_TRANSPORT_NAME L"name"
diff --git a/src/app-sdk/mididiag/packages.config b/src/app-sdk/mididiag/packages.config
index 7a9561b2..2ddc908f 100644
--- a/src/app-sdk/mididiag/packages.config
+++ b/src/app-sdk/mididiag/packages.config
@@ -1,4 +1,5 @@
+
\ No newline at end of file
diff --git a/src/app-sdk/mididiag/pch.h b/src/app-sdk/mididiag/pch.h
index e732230c..855bd952 100644
--- a/src/app-sdk/mididiag/pch.h
+++ b/src/app-sdk/mididiag/pch.h
@@ -54,7 +54,13 @@ namespace svc = winrt::Microsoft::Windows::Devices::Midi2::ServiceConfig;
#include
#include
+#include
+#include
+#include
+
+
#include "wstring_util.h"
+#include "MidiDefs.h"
namespace internal = ::WindowsMidiServicesInternal;
diff --git a/src/app-sdk/projections/dotnet-and-cpp/nuget/Microsoft.Windows.Devices.Midi2.props b/src/app-sdk/projections/dotnet-and-cpp/nuget/Microsoft.Windows.Devices.Midi2.props
index 35209def..6a18f4cb 100644
--- a/src/app-sdk/projections/dotnet-and-cpp/nuget/Microsoft.Windows.Devices.Midi2.props
+++ b/src/app-sdk/projections/dotnet-and-cpp/nuget/Microsoft.Windows.Devices.Midi2.props
@@ -19,7 +19,7 @@
- $(NugetRoot)\ref\native\WMicrosoft.Windows.Devices.Midi2.Initialization.winmd
+ $(NugetRoot)\ref\native\Microsoft.Windows.Devices.Midi2.Initialization.winmd
diff --git a/src/app-sdk/winrt-initialization/MidiServicesInitializer.cpp b/src/app-sdk/winrt-initialization/MidiServicesInitializer.cpp
index c230f3c5..9f8d38f8 100644
--- a/src/app-sdk/winrt-initialization/MidiServicesInitializer.cpp
+++ b/src/app-sdk/winrt-initialization/MidiServicesInitializer.cpp
@@ -118,23 +118,23 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Initialization::implementat
return false;
}
- //auto verifyConnectivityResult = tracker->VerifyConnectivity();
- //if (FAILED(verifyConnectivityResult))
- //{
- // LOG_IF_FAILED(verifyConnectivityResult); // this also generates a fallback error with file and line number info
-
- // TraceLoggingWrite(
- // Midi2SdkTelemetryProvider::Provider(),
- // MIDI_SDK_TRACE_EVENT_ERROR,
- // TraceLoggingString(__FUNCTION__, MIDI_SDK_TRACE_LOCATION_FIELD),
- // TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
- // TraceLoggingWideString(MIDI_SDK_STATIC_THIS_PLACEHOLDER_FIELD_VALUE, MIDI_SDK_TRACE_THIS_FIELD),
- // TraceLoggingWideString(L"Failure hresult received verifying connectivity", MIDI_SDK_TRACE_MESSAGE_FIELD),
- // TraceLoggingHResult(verifyConnectivityResult, MIDI_SDK_TRACE_HRESULT_FIELD)
- // );
-
- // return false;
- //}
+ auto verifyConnectivityResult = tracker->VerifyConnectivity();
+
+ if (!verifyConnectivityResult)
+ {
+ LOG_IF_FAILED(E_FAIL); // this also generates a fallback error with file and line number info
+
+ TraceLoggingWrite(
+ Midi2SdkTelemetryProvider::Provider(),
+ MIDI_SDK_TRACE_EVENT_ERROR,
+ TraceLoggingString(__FUNCTION__, MIDI_SDK_TRACE_LOCATION_FIELD),
+ TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
+ TraceLoggingWideString(MIDI_SDK_STATIC_THIS_PLACEHOLDER_FIELD_VALUE, MIDI_SDK_TRACE_THIS_FIELD),
+ TraceLoggingWideString(L"Failure received verifying connectivity", MIDI_SDK_TRACE_MESSAGE_FIELD)
+ );
+
+ return false;
+ }
return true;
}
diff --git a/src/app-sdk/winrt/MidiReporting.cpp b/src/app-sdk/winrt/MidiReporting.cpp
index 0b73b21b..363b4174 100644
--- a/src/app-sdk/winrt/MidiReporting.cpp
+++ b/src/app-sdk/winrt/MidiReporting.cpp
@@ -11,6 +11,12 @@
#include "MidiReporting.h"
#include "Reporting.MidiReporting.g.cpp"
+#define SAFE_COTASKMEMFREE(p) \
+ if (NULL != p) { \
+ CoTaskMemFree(p); \
+ (p) = NULL; \
+ }
+
namespace winrt::Microsoft::Windows::Devices::Midi2::Reporting::implementation
{
foundation::Collections::IVector MidiReporting::GetInstalledTransportPlugins()
@@ -28,47 +34,53 @@ namespace winrt::Microsoft::Windows::Devices::Midi2::Reporting::implementation
{
if (SUCCEEDED(serviceAbstraction->Activate(__uuidof(IMidiServicePluginMetadataReporterInterface), (void**)&metadataReporter)))
{
- CComBSTR metadataListJson;
- metadataListJson.Empty();
+ LPWSTR rpcCallJson;
+ metadataReporter->GetTransportList(&rpcCallJson);
- metadataReporter->GetTransportList(&metadataListJson);
-
- // parse it into json objects
- if (metadataListJson.m_str != nullptr && metadataListJson.Length() > 0)
+ if (rpcCallJson != nullptr)
{
- winrt::hstring hstr(metadataListJson, metadataListJson.Length());
+ winrt::hstring metadataListJsonString(rpcCallJson);
- // Parse the json, create the objects, throw them into the vector and return
+ //SAFE_COTASKMEMFREE(rpcCallJson);
- json::JsonObject jsonObject = json::JsonObject::Parse(hstr);
+ // parse it into json objects
- if (jsonObject != nullptr)
+ if (metadataListJsonString.size() > 0)
{
- for (auto const& transportKV : jsonObject)
+ // Parse the json, create the objects, throw them into the vector and return
+
+ json::JsonObject jsonObject = json::JsonObject::Parse(metadataListJsonString);
+
+ if (jsonObject != nullptr)
{
- rept::MidiServiceTransportPluginInfo info;
+ for (auto const& transportKV : jsonObject)
+ {
+ rept::MidiServiceTransportPluginInfo info;
- auto transport = transportKV.Value().GetObject();
+ auto transport = transportKV.Value().GetObject();
- info.Id = internal::StringToGuid(transportKV.Key().c_str());
- info.Name = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_NAME_PROPERTY_KEY, L"");
- info.TransportCode = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_TRANSPORT_CODE_PROPERTY_KEY, L"");
- info.Description = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_DESCRIPTION_PROPERTY_KEY, L"");
- info.SmallImagePath = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_SMALL_IMAGE_PATH_PROPERTY_KEY, L"");
- info.Author = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_AUTHOR_PROPERTY_KEY, L"");
- info.Version = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_VERSION_PROPERTY_KEY, L"");
- info.IsSystemManaged = transport.GetNamedBoolean(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_SYSTEM_MANAGED_PROPERTY_KEY, false);
- info.IsRuntimeCreatableByApps = transport.GetNamedBoolean(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_RT_CREATABLE_APPS_PROPERTY_KEY, false);
- info.IsRuntimeCreatableBySettings = transport.GetNamedBoolean(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_RT_CREATABLE_SETTINGS_PROPERTY_KEY, false);
- info.CanConfigure = transport.GetNamedBoolean(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_CLIENT_CONFIGURABLE_PROPERTY_KEY, false);
+ info.Id = internal::StringToGuid(transportKV.Key().c_str());
+ info.Name = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_NAME_PROPERTY_KEY, L"");
+ info.TransportCode = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_TRANSPORT_CODE_PROPERTY_KEY, L"");
+ info.Description = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_DESCRIPTION_PROPERTY_KEY, L"");
+ info.SmallImagePath = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_SMALL_IMAGE_PATH_PROPERTY_KEY, L"");
+ info.Author = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_AUTHOR_PROPERTY_KEY, L"");
+ info.Version = transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_VERSION_PROPERTY_KEY, L"");
+ info.IsSystemManaged = transport.GetNamedBoolean(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_SYSTEM_MANAGED_PROPERTY_KEY, false);
+ info.IsRuntimeCreatableByApps = transport.GetNamedBoolean(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_RT_CREATABLE_APPS_PROPERTY_KEY, false);
+ info.IsRuntimeCreatableBySettings = transport.GetNamedBoolean(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_RT_CREATABLE_SETTINGS_PROPERTY_KEY, false);
+ info.CanConfigure = transport.GetNamedBoolean(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_IS_CLIENT_CONFIGURABLE_PROPERTY_KEY, false);
- //transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_CLIENT_CONFIG_ASSEMBLY_PROPERTY_KEY, L"");
+ //transport.GetNamedString(MIDI_SERVICE_JSON_ABSTRACTION_PLUGIN_INFO_CLIENT_CONFIG_ASSEMBLY_PROPERTY_KEY, L"");
- transportList.Append(std::move(info));
+ transportList.Append(std::move(info));
+ }
}
}
}
+
+
}
}
}
diff --git a/src/user-tools/midi-console/Midi/Midi.csproj b/src/user-tools/midi-console/Midi/Midi.csproj
index bc4aa098..b5cffe3f 100644
--- a/src/user-tools/midi-console/Midi/Midi.csproj
+++ b/src/user-tools/midi-console/Midi/Midi.csproj
@@ -38,7 +38,8 @@
-
+
+