Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions build/replace_just_ksa_x64.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@echo off
echo This must be run as administrator.

set servicepath="%ProgramFiles%\Windows MIDI Services\Service"
set apipath="%ProgramFiles%\Windows MIDI Services\API"
set dmppath="%ProgramFiles%\Windows MIDI Services\"
set buildoutput="%midi_repo_root%src\api\VSFiles\x64\Release"



echo Stopping midisrv
net stop midisrv

echo Copying KSA Transport
mkdir %servicepath%
copy /Y %buildoutput%\Midi2.KSAggregateTransport.dll %servicepath%
regsvr32 %servicepath%\Midi2.KSAggregateTransport.dll

net start midisrv

pause
4 changes: 2 additions & 2 deletions build/staging/version/BundleInfo.wxi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Include>
<?define SetupVersionName="Service Preview 14 Arm64" ?>
<?define SetupVersionNumber="1.0.15-preview.14.73" ?>
<?define MidiSdkAndToolsVersion="1.0.15-preview.14.73" ?>
<?define SetupVersionNumber="1.0.15-preview.14.79" ?>
<?define MidiSdkAndToolsVersion="1.0.15-preview.14.79" ?>
</Include>
12 changes: 6 additions & 6 deletions build/staging/version/WindowsMidiServicesVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ public static class MidiNuGetBuildInformation
{
public const bool IsPreview = true;
public const string Source = "GitHub Preview";
public const string BuildDate = "2026-01-19";
public const string BuildDate = "2026-02-16";
public const string Name = "Service Preview 14";
public const string BuildFullVersion = "1.0.15-preview.14.73";
public const string BuildFullVersion = "1.0.15-preview.14.79";
public const ushort VersionMajor = 1;
public const ushort VersionMinor = 0;
public const ushort VersionPatch = 15;
public const ushort VersionBuildNumber = 73;
public const string Preview = "preview.14.73";
public const string AssemblyFullVersion = "1.0.15.73";
public const string FileFullVersion = "1.0.15.73";
public const ushort VersionBuildNumber = 79;
public const string Preview = "preview.14.79";
public const string AssemblyFullVersion = "1.0.15.79";
public const string FileFullVersion = "1.0.15.79";
}
}
10 changes: 5 additions & 5 deletions build/staging/version/WindowsMidiServicesVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_IS_PREVIEW true
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_SOURCE L"GitHub Preview"
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_DATE L"2026-01-19"
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_DATE L"2026-02-16"
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_VERSION_NAME L"Service Preview 14"
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_VERSION_FULL L"1.0.15-preview.14.73"
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_VERSION_FULL L"1.0.15-preview.14.79"
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_VERSION_MAJOR 1
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_VERSION_MINOR 0
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_VERSION_PATCH 15
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_VERSION_BUILD_NUMBER 73
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_PREVIEW L"preview.14.73"
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_VERSION_FILE L"1.0.15.73"
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_VERSION_BUILD_NUMBER 79
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_PREVIEW L"preview.14.79"
#define WINDOWS_MIDI_SERVICES_NUGET_BUILD_VERSION_FILE L"1.0.15.79"

#endif
4 changes: 4 additions & 0 deletions src/api/Drivers/USBMIDI2/Driver/USBMidi2.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,28 @@
<TargetName>USBMidi2</TargetName>
<OutDir>$(SolutionDir)VSFiles\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)VSFiles\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<IncludePath>$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH);$(SolutionDir)\inc</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<TargetName>USBMidi2</TargetName>
<OutDir>$(SolutionDir)VSFiles\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)VSFiles\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<IncludePath>$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH);$(SolutionDir)\inc</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<TargetName>USBMidi2</TargetName>
<OutDir>$(SolutionDir)VSFiles\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)VSFiles\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<IncludePath>$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH);$(SolutionDir)\inc</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<TargetName>USBMidi2</TargetName>
<OutDir>$(SolutionDir)VSFiles\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)VSFiles\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
<IncludePath>$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH);$(SolutionDir)\inc</IncludePath>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
Expand Down
18 changes: 18 additions & 0 deletions src/api/Inc/Feature_Servicing_MIDI2VirtualPortDriversFix.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License
// ============================================================================
// This is part of the Windows MIDI Services App API and should be used
// in your Windows application via an official binary distribution.
// Further information: https://aka.ms/midi
// ============================================================================

#pragma once

class Feature_Servicing_MIDI2VirtualPortDriversFix
{
public:
static bool IsEnabled()
{
return true;
}
};
200 changes: 142 additions & 58 deletions src/api/Transport/KSAggregateTransport/Midi2.KSAggregateMidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

#include "ump_iterator.h"


_Use_decl_annotations_
HRESULT
CMidi2KSAggregateMidi::Initialize(
Expand Down Expand Up @@ -205,40 +204,84 @@ CMidi2KSAggregateMidi::Initialize(
wil::com_ptr_nothrow<CMidi2KSAggregateMidiInProxy> proxy;
RETURN_IF_FAILED(Microsoft::WRL::MakeAndInitialize<CMidi2KSAggregateMidiInProxy>(&proxy));

auto initResult =
proxy->Initialize(
endpointDeviceInterfaceId,
handleDupe.get(),
pinMapEntry->PinId,
requestedBufferSize,
mmCssTaskId,
m_callback,
context,
pinMapEntry->GroupIndex
);

if (SUCCEEDED(initResult))
// needed for internal consumption. Gary to replace this with feature enablement check
// defined in pch.h
if (Feature_Servicing_MIDI2VirtualPortDriversFix::IsEnabled())
{
m_midiInDeviceGroupMap.insert_or_assign(pinMapEntry->GroupIndex, std::move(proxy));
auto initResult =
proxy->Initialize(
filterInterfaceId.c_str(),
handleDupe.get(),
pinMapEntry->PinId,
requestedBufferSize,
mmCssTaskId,
m_callback,
context,
pinMapEntry->GroupIndex
);

if (SUCCEEDED(initResult))
{
m_midiInDeviceGroupMap.insert_or_assign(pinMapEntry->GroupIndex, std::move(proxy));
}
else
{
TraceLoggingWrite(
MidiKSAggregateTransportTelemetryProvider::Provider(),
MIDI_TRACE_EVENT_ERROR,
TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
TraceLoggingPointer(this, "this"),
TraceLoggingWideString(L"Unable to initialize Midi Input proxy", MIDI_TRACE_EVENT_MESSAGE_FIELD),
TraceLoggingWideString(endpointDeviceInterfaceId, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD),
TraceLoggingUInt32(requestedBufferSize, "buffer size"),
TraceLoggingUInt32(pinMapEntry->PinId, "pin id"),
TraceLoggingUInt8(pinMapEntry->GroupIndex, "group"),
TraceLoggingWideString(filterInterfaceId.c_str(), "filter")
);

RETURN_IF_FAILED(initResult);
}
}
else
{
TraceLoggingWrite(
MidiKSAggregateTransportTelemetryProvider::Provider(),
MIDI_TRACE_EVENT_ERROR,
TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
TraceLoggingPointer(this, "this"),
TraceLoggingWideString(L"Unable to initialize Midi Input proxy", MIDI_TRACE_EVENT_MESSAGE_FIELD),
TraceLoggingWideString(endpointDeviceInterfaceId, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD),
TraceLoggingUInt32(requestedBufferSize, "buffer size"),
TraceLoggingUInt32(pinMapEntry->PinId, "pin id"),
TraceLoggingUInt8(pinMapEntry->GroupIndex, "group"),
TraceLoggingWideString(filterInterfaceId.c_str(), "filter")
);

RETURN_IF_FAILED(initResult);
auto initResult =
proxy->Initialize(
endpointDeviceInterfaceId,
handleDupe.get(),
pinMapEntry->PinId,
requestedBufferSize,
mmCssTaskId,
m_callback,
context,
pinMapEntry->GroupIndex
);

if (SUCCEEDED(initResult))
{
m_midiInDeviceGroupMap.insert_or_assign(pinMapEntry->GroupIndex, std::move(proxy));
}
else
{
TraceLoggingWrite(
MidiKSAggregateTransportTelemetryProvider::Provider(),
MIDI_TRACE_EVENT_ERROR,
TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
TraceLoggingPointer(this, "this"),
TraceLoggingWideString(L"Unable to initialize Midi Input proxy", MIDI_TRACE_EVENT_MESSAGE_FIELD),
TraceLoggingWideString(endpointDeviceInterfaceId, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD),
TraceLoggingUInt32(requestedBufferSize, "buffer size"),
TraceLoggingUInt32(pinMapEntry->PinId, "pin id"),
TraceLoggingUInt8(pinMapEntry->GroupIndex, "group"),
TraceLoggingWideString(filterInterfaceId.c_str(), "filter")
);

RETURN_IF_FAILED(initResult);
}
}


}
else if (pinMapEntry->PinDataFlow == MidiFlow::MidiFlowIn)
{
Expand All @@ -247,38 +290,79 @@ CMidi2KSAggregateMidi::Initialize(
wil::com_ptr_nothrow<CMidi2KSAggregateMidiOutProxy> proxy;
RETURN_IF_FAILED(Microsoft::WRL::MakeAndInitialize<CMidi2KSAggregateMidiOutProxy>(&proxy));

auto initResult =
proxy->Initialize(
endpointDeviceInterfaceId,
handleDupe.get(),
pinMapEntry->PinId,
requestedBufferSize,
mmCssTaskId,
context,
pinMapEntry->GroupIndex
);

if (SUCCEEDED(initResult))
// needed for internal consumption. Gary to replace this with feature enablement check
// defined in pch.h
if (Feature_Servicing_MIDI2VirtualPortDriversFix::IsEnabled())
{
m_midiOutDeviceGroupMap.insert_or_assign(pinMapEntry->GroupIndex, std::move(proxy));
auto initResult =
proxy->Initialize(
filterInterfaceId.c_str(),
handleDupe.get(),
pinMapEntry->PinId,
requestedBufferSize,
mmCssTaskId,
context,
pinMapEntry->GroupIndex
);

if (SUCCEEDED(initResult))
{
m_midiOutDeviceGroupMap.insert_or_assign(pinMapEntry->GroupIndex, std::move(proxy));
}
else
{
TraceLoggingWrite(
MidiKSAggregateTransportTelemetryProvider::Provider(),
MIDI_TRACE_EVENT_ERROR,
TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
TraceLoggingPointer(this, "this"),
TraceLoggingWideString(L"Unable to initialize Midi Output proxy", MIDI_TRACE_EVENT_MESSAGE_FIELD),
TraceLoggingWideString(endpointDeviceInterfaceId, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD),
TraceLoggingUInt32(requestedBufferSize, "buffer size"),
TraceLoggingUInt32(pinMapEntry->PinId, "pin id"),
TraceLoggingUInt8(pinMapEntry->GroupIndex, "group"),
TraceLoggingWideString(filterInterfaceId.c_str(), "filter")
);

RETURN_IF_FAILED(initResult);
}
}
else
{
TraceLoggingWrite(
MidiKSAggregateTransportTelemetryProvider::Provider(),
MIDI_TRACE_EVENT_ERROR,
TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
TraceLoggingPointer(this, "this"),
TraceLoggingWideString(L"Unable to initialize Midi Output proxy", MIDI_TRACE_EVENT_MESSAGE_FIELD),
TraceLoggingWideString(endpointDeviceInterfaceId, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD),
TraceLoggingUInt32(requestedBufferSize, "buffer size"),
TraceLoggingUInt32(pinMapEntry->PinId, "pin id"),
TraceLoggingUInt8(pinMapEntry->GroupIndex, "group"),
TraceLoggingWideString(filterInterfaceId.c_str(), "filter")
);

RETURN_IF_FAILED(initResult);
auto initResult =
proxy->Initialize(
endpointDeviceInterfaceId,
handleDupe.get(),
pinMapEntry->PinId,
requestedBufferSize,
mmCssTaskId,
context,
pinMapEntry->GroupIndex
);

if (SUCCEEDED(initResult))
{
m_midiOutDeviceGroupMap.insert_or_assign(pinMapEntry->GroupIndex, std::move(proxy));
}
else
{
TraceLoggingWrite(
MidiKSAggregateTransportTelemetryProvider::Provider(),
MIDI_TRACE_EVENT_ERROR,
TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
TraceLoggingLevel(WINEVENT_LEVEL_ERROR),
TraceLoggingPointer(this, "this"),
TraceLoggingWideString(L"Unable to initialize Midi Output proxy", MIDI_TRACE_EVENT_MESSAGE_FIELD),
TraceLoggingWideString(endpointDeviceInterfaceId, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD),
TraceLoggingUInt32(requestedBufferSize, "buffer size"),
TraceLoggingUInt32(pinMapEntry->PinId, "pin id"),
TraceLoggingUInt8(pinMapEntry->GroupIndex, "group"),
TraceLoggingWideString(filterInterfaceId.c_str(), "filter")
);

RETURN_IF_FAILED(initResult);
}
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ CMidi2KSAggregateMidiBidi::Initialize(
TraceLoggingString(__FUNCTION__, MIDI_TRACE_EVENT_LOCATION_FIELD),
TraceLoggingLevel(WINEVENT_LEVEL_INFO),
TraceLoggingPointer(this, "this"),
TraceLoggingPointer(L"Enter", MIDI_TRACE_EVENT_MESSAGE_FIELD),
TraceLoggingWideString(device, MIDI_TRACE_EVENT_DEVICE_SWD_ID_FIELD)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,26 @@ CMidi2KSAggregateMidiConfigurationManager::UpdateConfiguration(

// Resolve the EndpointDeviceId in case we matched on something else
winrt::hstring matchingEndpointDeviceId{};
auto em = TransportState::Current().GetEndpointManager();
if (em != nullptr)


if (Feature_Servicing_MIDI2VirtualPortDriversFix::IsEnabled())
{
auto em = TransportState::Current().GetEndpointManager2();
if (em != nullptr)
{
matchingEndpointDeviceId = em->FindMatchingInstantiatedEndpoint(*matchCriteria);
}
}
else
{
matchingEndpointDeviceId = em->FindMatchingInstantiatedEndpoint(*matchCriteria);
auto em = TransportState::Current().GetEndpointManager();
if (em != nullptr)
{
matchingEndpointDeviceId = em->FindMatchingInstantiatedEndpoint(*matchCriteria);
}
}


// process all the custom props like Name, Description, Image, etc.
LOG_IF_FAILED(ProcessCustomProperties(
matchingEndpointDeviceId,
Expand Down
Loading