Skip to content

Add fallback for MrmGetFilePathFromName - #5828

Closed
Yuyi Wang (Berrysoft) wants to merge 4 commits into
microsoft:mainfrom
Berrysoft:fix/res-not-found
Closed

Yuyi Wang (Berrysoft) wants to merge 4 commits into
microsoft:mainfrom
Berrysoft:fix/res-not-found

Conversation

@Berrysoft

@Berrysoft Yuyi Wang (Berrysoft) commented Sep 12, 2025 •

Copy link
Copy Markdown
Contributor

Closes #5814

Closes #5940

According to the docs, this method should success even if no resource file is found.

@Scottj1s

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@Scottj1s

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Comment thread dev/MRTCore/mrt/Core/src/MRM.cpp Resolved
Comment on lines +1090 to +1091
if ((pass == SearchPass::DefaultFallback) ||
((attributes != INVALID_FILE_ATTRIBUTES) && !(attributes & FILE_ATTRIBUTE_DIRECTORY)))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is going to need an audit of all the code in MUX and WAS where MRM was expected to fail right? (e.g., https://github.com/microsoft/WindowsAppSDK/blob/main/dev/MRTCore/mrt/Microsoft.Windows.ApplicationModel.Resources/src/Helper.cpp#L77-L103)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There are two paths calling this method. One is the ResourceManager:

which is OK if the file not found, and is expected (

// provided) under module file path. The reason is that we don't want to fail the creation of
// ResourceManager even if an app doesn't have PRI file.
). The other one is the ResourceLoader:

which will fail if it cannot find the pri file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Indeed - thanks for the heads up. Code like that will now need to test for nonexistent path as well (not just S_OK).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Do I need to add tests in this PR?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

that would be great, Yuyi Wang (@Berrysoft) - thanks

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Well. I have to admit that the PR was created more than half a year before. I need some time to investigate how to add the tests. If it is a must, I'll do it later. But if it is not, I think I'll keep the PR as-is.

Before 1.8, all code works well with the nonexistent path. Furthermore, I have been live-patching the MRM.dll since 1.8 to the latest 2.2. The patch always works well with all versions' WinUI. So I think this PR doesn't break the code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hello, Scott Jones (@Scottj1s) Rafael Rivera (@riverar) . I read the test code in this repo and found that it already contains tests for this case:

VERIFY_ARE_EQUAL(MrmGetFilePathFromName(L"something.pri", &path), S_OK);
// Even if the file doesn't exist, we will still return a path. This is for those don't use PRI for resource.
VERIFY_IS_NOT_NULL(wcsstr(path, L"something.pri"));
MrmFreeResource(path);

But I don't know why it didn't fail before this PR. I think I don't need to add other tests. They already fill the need.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Did the audit. Both callers of MrmGetFilePathFromName are fine: ResourceManager already tolerates a missing PRI (only its check_hresult(GetDefaultPriFile) gate was breaking on the 1.8 ERROR_FILE_NOT_FOUND regression), and ResourceLoader throws with or without the change by design. The one internal path that keyed off the failure was GetDefaultPriFile's sparse-packaged [modulename].pri fallback (added in #6376), which gated on IsResourceNotFound(hr) — since the fix makes MrmGetFilePathFromName return S_OK, that now gates on actual file existence (CheckFile) instead. Handled in #6603.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

On tests: MrmTests::GetFilePath and MrtCoreUnpackagedTests.TestClass.DefaultResourceManager already cover this — they just didn't catch the original regression because they were on the BypassTests.json allowlist (added in #5498, extended in #5919, after the regression). #6603 un-bypasses both and strengthens GetFilePath. Verified locally: MrmUnitTest 21/21, MrtCoreUnpackagedTests 27/27.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Awesome work Scott Jones (@Scottj1s), thank you. Squeaking a little more to get this landed too.

Yuyi Wang (Berrysoft) and others added 2 commits June 10, 2026 00:07
@riverar

Copy link
Copy Markdown
Contributor

Can we slot this in for the next preview build Scott Jones (@Scottj1s) Roy (@RDMacLachlan)? This is impacting reactor projects downstream.

@Berrysoft

Copy link
Copy Markdown
Contributor Author

Hello Scott Jones (@Scottj1s) , is it still possible to merge this PR?

@Scottj1s

Copy link
Copy Markdown
Member

Thanks for this, Yuyi Wang (@Berrysoft) — I've opened #6603 to wrap it up on top of your change. The DefaultFallback pass added here isn't actually reachable (both terminal passes jump to Final), so the function returns S_OK with a null *filePath. #6603 makes DefaultFallback the reachable final pass returning a non-null best-effort path (legacy parity), fixes the dependent GetDefaultPriFile sparse-packaged fallback, and re-enables the two tests that were bypassed. Your commits are included there, so this supersedes the PR.

@Berrysoft

Copy link
Copy Markdown
Contributor Author

Thanks!

@Scottj1s

Copy link
Copy Markdown
Member

Thanks!

Thanks for opening the issue, suggesting a fix, and waiting patiently - much appreciated.

Scott Jones (Scottj1s) added a commit that referenced this pull request Jul 10, 2026
…(supersedes #5828) (#6603)

* Add fallback for MrmGetFilePathFromName

* Update dev/MRTCore/mrt/Core/src/MRM.cpp

Co-authored-by: Rafael Rivera <rafael@withinwindows.com>

* Complete MrmGetFilePathFromName fallback: return S_OK with a valid path

PR #5828 added a DefaultFallback search pass to restore the documented
"always succeed, return a best-effort path" contract of MrmGetFilePathFromName
(regressed in #4965 to return ERROR_FILE_NOT_FOUND, breaking ResourceManager
creation when no resources.pri exists - #5814 / #5940).

However DefaultFallback was unreachable: both terminal passes
(ParentPathForFileName, exeDirForModulePri) jumped to Final, skipping it. The
function therefore returned S_OK with *filePath == nullptr, which crashes
callers that dereference the path (e.g. MrmCreateResourceManager rejects an
empty path with E_INVALIDARG, and the GetFilePath unit test AVs on wcsstr).

Changes:
- MRM.cpp: route both terminal passes into DefaultFallback so it runs as the
  final pass; return S_OK with a non-null best-effort path (the provided
  filename, else resources.pri) under the base directory (if set) otherwise the
  module directory - matching pre-#4965 (legacy) behavior. Preserve the module
  directory since the parent-folder search mutates exeDir in place.
- Helper.cpp (GetDefaultPriFile): the sparse-packaged [modulename].pri fallback
  gated on IsResourceNotFound(hr); since MrmGetFilePathFromName now returns
  S_OK, gate on actual file existence (CheckFile) instead, and only adopt the
  unpackaged result if it resolves to an existing file (avoids re-regressing
  #6376 / microsoft-ui-xaml#10856).
- MrmTests.cpp: strengthen GetFilePath to assert the fallback path is under the
  module directory.
- BypassTests.json: remove the now-passing UnitTest::BasicTest::GetFilePath and
  MrtCoreUnpackagedTests.TestClass.DefaultResourceManager entries so they gate
  again (they were bypassed in #5498 / #5919 after the #4965 regression, which
  is why the regression shipped undetected).

Verified locally (x64 Debug): MrmUnitTest 21/21, MrtCoreUnpackagedTests 27/27.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: 王宇逸 <Strawberry_Str@hotmail.com>
Co-authored-by: Rafael Rivera <rafael@withinwindows.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Berrysoft

Copy link
Copy Markdown
Contributor Author

This PR is not needed now, I think? Regarding that #6603 has been merged.

@riverar

Copy link
Copy Markdown
Contributor

Did that fix ship in a release we can test with?

@riverar

Copy link
Copy Markdown
Contributor

Any updates on this? cc: Scott Jones (@Scottj1s)

@Berrysoft

Copy link
Copy Markdown
Contributor Author

I don't know if there's a release, but it seems that this PR is not needed.

@riverar

Copy link
Copy Markdown
Contributor

I'm confused because it seems like Scott Jones (@Scottj1s) was building on top of this PR, not replacing it.

@riverar

Copy link
Copy Markdown
Contributor

I see now, you're right. This PR was superseded and never cleaned up. The lack of normal GitHub usage patterns by this team continues to frustrate me.

@Scottj1s

Copy link
Copy Markdown
Member

Yuyi Wang (@Berrysoft) , Rafael Rivera (@riverar) - fix has been cherry picked for August's 1.8 and 2.0 servicing releases (note: usual caveats, schedules always subject to change)

@Scottj1s

Copy link
Copy Markdown
Member

I see now, you're right. This PR was superseded and never cleaned up. The lack of normal GitHub usage patterns by this team continues to frustrate me.

fair - I considered building on top of this PR, and do appreciate your contribution, Yuyi Wang (@Berrysoft). there was enough divergence to warrant a new PR.

@Berrysoft

Copy link
Copy Markdown
Contributor Author

fix has been cherry picked for August's 1.8 and 2.0 servicing releases

Thanks, Scott Jones (@Scottj1s) ! However, when I'm using the latest WinUI3 (2.3.1.0), MrmGetFilePathFromName still returns ERROR_FILE_NOT_FOUND (0x80070002). I detoured this method and get this return code. I watch my process through Process Explorer, and confirmed that the process is really loading the MRM.dll from C:\Program Files\WindowsApps\Microsoft.WindowsAppRuntime.2_2.3.1.0_x64__8wekyb3d8bbwe\MRM.dll. So, does winappsdk 2.3.1 really contain this fix?

@riverar

Rafael Rivera (riverar) commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

I was confused too because at one point the PR or commits were tagged 2.3.1.0. But seems that's gone now, I can't find it.

Update: This commit is tagged 2.3.1.0. 91160b0

So now we wait for August release!

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

Projects

None yet

3 participants