Skip to content

Add full MIDI setup detection sample#934

Open
sauloverissimo wants to merge 3 commits intomicrosoft:mainfrom
sauloverissimo:detectmidi-full-sample
Open

Add full MIDI setup detection sample#934
sauloverissimo wants to merge 3 commits intomicrosoft:mainfrom
sauloverissimo:detectmidi-full-sample

Conversation

@sauloverissimo
Copy link
Copy Markdown

Addresses #862 and #793.

The existing detectmidi sample only checks COM activation, which gives false positives when Windows MIDI Services is present via Controlled Feature Rollout (CFR) but not fully configured.

This new sample runs four sequential checks based on the midicheckservice tool logic:

  1. Registry — looks for wdmaud2.drv in HKLM...\Drivers32 (midi, midi1..midi9) using wil::reg::try_get_value_string
  2. COM registration — CoCreateInstance on the MidiSrvTransportPlaceholder CLSID
  3. Service availability — opens midisrv via SCM, verifies it exists and is not disabled
  4. SDK Runtime — CoCreateInstance on the MidiClientInitializer CLSID

Each check prints a clear pass/fail message with a specific return code (1-3 for each failure point, 0 for all good). Uses wil:: for resource management (scope_exit, com_ptr_nothrow).

Files: main.cpp, pch.h, pch.cpp (precompiled header stub).

Tested compilation with MSVC. Follows the same structure as the existing detectmidi sample.

Addresses microsoft#862 and microsoft#793. The existing detectmidi sample only checks
COM activation, which gives false positives with Controlled Feature
Rollout (CFR). This new sample performs registry, COM, service, and
SDK Runtime checks based on the midicheckservice tool logic.
{
std::wstring valueName = (i == 0) ? L"midi" : L"midi" + std::to_wstring(i);

auto val = wil::reg::try_get_value_string(HKEY_LOCAL_MACHINE, keyPath.c_str(), valueName.c_str());
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this instruction throw an exception? If yes, we need to wrap it to try/catch I suppose. Also what about the case when a user doesn't have rights to access registry? Will Windows MIDI Services work at all in this case?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! wil::reg::try_get_value_string is the nothrow variant — it returns std::optional and doesn't throw on missing keys or access denied. If the key doesn't exist or the user can't read it, it just returns std::nullopt and the check reports "NOT FOUND" gracefully. The Drivers32 key has read access for all users by default, but even in a restricted scenario the code handles it fine — no crash, no exception.


bool CheckMidiServiceAvailable()
{
SC_HANDLE hSCManager = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about access denied case? It affects only this check or entire Windows MIDI Services won't work?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SC_MANAGER_CONNECT is the most basic SCM permission — any standard user has it. Access denied here would be a very unusual scenario (restrictive group policy, for example), and in that case the MIDI Service itself probably would not work either. But I agree it would be better to distinguish the cases — I can add a GetLastError() check to print a specific message for access denied instead of just "NOT AVAILABLE". Want me to make that change?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want me to make that change?

If it's not too difficult, yes. Thank you!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! CheckMidiServiceAvailable now returns distinct error codes so the caller can tell if it was access denied (suggests running as Administrator) or a missing/disabled service (suggests midifixreg). Thanks for the feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Address review feedback: CheckMidiServiceAvailable now returns
distinct error codes so the caller can tell the user whether the
failure is an access denied (suggest running as Administrator) or
a missing/disabled service (suggest midifixreg).
@melanchall
Copy link
Copy Markdown

@Psychlist1972 Can you please review the PR? Is the code OK?

@Psychlist1972
Copy link
Copy Markdown
Collaborator

@Psychlist1972 Can you please review the PR? Is the code OK?

I haven't had a chance yet due to working on bugs and customer support. I haven't forgotten about it, however. Thank you for submitting this @sauloverissimo !

Pete
Microsoft

@sauloverissimo
Copy link
Copy Markdown
Author

Thank you very much for your attention and reply, Pete.🤝

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants