Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UndockedRegFreeWinRT doesn't check Dynamic packages for WinRT Metadata #1649

Merged

Conversation

DrusTheAxe
Copy link
Member

@DrusTheAxe DrusTheAxe commented Oct 26, 2021

Fixes https://task.ms/36717508

Add PACKAGE_FILTER_STATIC|DYNAMIC in ResolveThirdPartyType() so metadata resolution also doesn't just search static package graph entries (and fail to find metadata in dynamic packages)

Kudos to @huichen123 for spotting the problem

Manually tested by applying privates to the UndockedRegFreeWinRT IntegratedTest (URFW_ExeUsingWinAppSDK.exe) and tracing code flow in the debugger for the various permutations of usage.

closes #2382

…'t just search static package graph entries (and fail to find metadata in dynamic packages)
@DrusTheAxe
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@huichen123
Copy link
Contributor

        return RO_E_METADATA_NAME_NOT_FOUND;

Then unpackaged WAS app will return RO_E_METADATA_NAME_NOT_FOUND, and then fail in TrueRoGetMetaDataFile.


Refers to: dev/UndockedRegFreeWinRT/typeresolution.cpp:464 in 1f6f5f7. [](commit_id = 1f6f5f7, deletion_comment = False)

@huichen123
Copy link
Contributor

            // For compatibility purposes, if we fail to find the type in the unpackaged location, we should return

I feel we still need to do static check above, but here call GetCurrentPackageInfo(DYNAMIC), and try to find the type in each dependency path.


Refers to: dev/UndockedRegFreeWinRT/typeresolution.cpp:455 in 1f6f5f7. [](commit_id = 1f6f5f7, deletion_comment = False)

Copy link
Contributor

@EHO-makai EHO-makai left a comment

Choose a reason for hiding this comment

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

Feels like there is a missing test or tests here?

@DrusTheAxe
Copy link
Member Author

Feels like there is a missing test or tests here?

We've got a manual test how we discovered it and will verify.

URFW has zero direct tests here. Known issue on the backlog.

@DrusTheAxe DrusTheAxe requested a review from EHO-makai October 26, 2021 18:01
@DrusTheAxe
Copy link
Member Author

DrusTheAxe commented Oct 26, 2021

            // For compatibility purposes, if we fail to find the type in the unpackaged location, we should return

I feel we still need to do static check above, but here call GetCurrentPackageInfo(DYNAMIC), and try to find the type in each dependency path.

@huichen123 Why split the check for Static+Dynamic instead of the 1 call above?

@huichen123
Copy link
Contributor

            // For compatibility purposes, if we fail to find the type in the unpackaged location, we should return

I feel we still need to do static check above, but here call GetCurrentPackageInfo(DYNAMIC), and try to find the type in each dependency path.

@huichen123 Why split the check for Static+Dynamic instead of the 1 call above?

for packaged app, we don't need to handle here.

@DrusTheAxe
Copy link
Member Author

            // For compatibility purposes, if we fail to find the type in the unpackaged location, we should return

I feel we still need to do static check above, but here call GetCurrentPackageInfo(DYNAMIC), and try to find the type in each dependency path.

@huichen123

        Hui Chen
        FTE Why split the check for Static+Dynamic instead of the 1 call above?

for packaged app, we don't need to handle here.

Is it harmful or just inefficient?

@huichen123
Copy link
Contributor

            // For compatibility purposes, if we fail to find the type in the unpackaged location, we should return

I feel we still need to do static check above, but here call GetCurrentPackageInfo(DYNAMIC), and try to find the type in each dependency path.

@huichen123

        Hui Chen
        FTE Why split the check for Static+Dynamic instead of the 1 call above?

for packaged app, we don't need to handle here.

Is it harmful or just inefficient?

inefficient? I don't know this code. You'd want to check with the owner. Regardless, it needs to handle unpackaged app with dynamic package graph.

@DrusTheAxe
Copy link
Member Author

inefficient? I don't know this code. You'd want to check with the owner.

I ping'd @kythant above. It's a bit of a mixed ownership

needs to handle unpackaged app with dynamic package graph.

Yes, hence this PR.

@huichen123
Copy link
Contributor

inefficient? I don't know this code. You'd want to check with the owner.

I ping'd @kythant above. It's a bit of a mixed ownership

needs to handle unpackaged app with dynamic package graph.

Yes, hence this PR.
This PR doesn't fix the issue. With this fix, the function will return RO_E_METADATA_NAME_NOT_FOUND for unpackaged WAS app, then TrueRoGetMetaDataFile will be used, which won't find for unpackaged app.

@DrusTheAxe
Copy link
Member Author

inefficient? I don't know this code. You'd want to check with the owner.

I ping'd @kythant above. It's a bit of a mixed ownership

needs to handle unpackaged app with dynamic package graph.

Yes, hence this PR.
This PR doesn't fix the issue. With this fix, the function will return RO_E_METADATA_NAME_NOT_FOUND for unpackaged WAS app, then TrueRoGetMetaDataFile will be used, which won't find for unpackaged app.

Aha! Yes, sorry, brain fart on my part. Update posted.

@DrusTheAxe
Copy link
Member Author

/azp run

@DrusTheAxe DrusTheAxe force-pushed the user/drustheaxe/URFW-GetCurrentPackageInfo-ResolveThirdPartyType branch from dbf83fb to c9bc151 Compare April 21, 2022 19:07
// Walk the dynamic package graph looking for the requested metadata
const uint32_t filter{ PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_IS_IN_RELATED_SET | PACKAGE_FILTER_DYNAMIC };
// Walk the package graph looking for the requested metadata
const uint32_t filter{ PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_IS_IN_RELATED_SET | PACKAGE_FILTER_DYNAMIC | PACKAGE_FILTER_STATIC };
Copy link
Contributor

Choose a reason for hiding this comment

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

This is an undocumented flag, though is in the public SDK.

#define PACKAGE_PROPERTY_STATIC             0x00080000
#define PACKAGE_FILTER_STATIC               PACKAGE_PROPERTY_STATIC

Can you shed some light on what it does and/or edit the docs? https://docs.microsoft.com/windows/win32/appxpkg/package-constants

Copy link
Member Author

Choose a reason for hiding this comment

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

Doc update is coming. In the meantime...

  • PACKAGE_PROPERTY_STATIC - search the package graph's static entries
  • PACKAGE_PROPERTY_DYNAMIC - search the package graph's dynamic entries

Packaged apps are born with entries in their package graph, aka static package graph entries, aka the static portion of the package graph or more simply, the static package graph.

Unpackaged apps are born with an empty package graph.

The Dynamic Dependency API adds entries dynamically to the package graph, aka dynamic package graph entries, aka the dynamic portion of the package graph or more simply, the dynamic package graph

For backwards compatibility reasons GetCurrentPackageInfo[2](...filter...) assumes if filter doesn't contain PACKAGE_FILTER_DYNAMIC then only look at the static package graph. IOW calling GetCurrentPackageInfo[2]() without PACKAGE_FILTER_DYNAMIC is implicitly the same as calling GetCurrentPackageInfo2withPACKAGE_FILTER_STATIC`.

This is explained in the comment block in DynamicGetCurrentPackageInfo2()indev\DynamicDependency\API\MddDetourPacckageGraph.cpp`:

    // Legacy callers may not be aware of dynamic packages and a common mistake is to assume PACKAGE_FILTER_HEAD will return the
    // main package as the first entry which is not going to be true when packages have been added dynamically to the head of the graph.
    // Maintain pre-dynamic behavior by requiring the caller to opt into receiving dynamic packages.

Thus GetCurrentPackageInfo[2]() are dynamic-oblivous unless explicitly told to consider dynamic package graph entries.

OTOH GetCurrentPackageInfo3() assumes the caller is dynamic-savvy so it doesn't make any such backwards compatibility game. If you specify neither option to GetCurrentPackageInfo3() it's equivalent to specifying both (i.e. search static+dynamic entries).

@DrusTheAxe
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@DrusTheAxe
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@DrusTheAxe DrusTheAxe requested review from huichen123 and jonwis May 18, 2022 04:38
Copy link
Member

@BenJKuhn BenJKuhn left a comment

Choose a reason for hiding this comment

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

Comments are suggestions / stylistic. Non-blocking, so signing off.

@DrusTheAxe
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@DrusTheAxe
Copy link
Member Author

Feels like there is a missing test or tests here?

Tests exist in the aggregator pipeline

As noted in the description, I manually tested by using those tests to see the repro fail, then updated microsoft.windowsappruntime.dll and watched the test succeed. Plus a lot of interesting walk-the-debugger-through-the-code.

Functional tests will be added here (under /test/UndockedRegFreeWinRT/) after we address some issues in our test infrastructure.

@DrusTheAxe DrusTheAxe dismissed EHO-makai’s stale review May 19, 2022 01:02

Non-blocking. See comment

@DrusTheAxe DrusTheAxe merged commit 2c23172 into main May 19, 2022
@DrusTheAxe DrusTheAxe deleted the user/drustheaxe/URFW-GetCurrentPackageInfo-ResolveThirdPartyType branch May 19, 2022 03:28
DrusTheAxe added a commit that referenced this pull request May 20, 2022
#1649)

* Added PACKAGE_FILTER_STATIC|DYNAMIC so metadata resolution also doesn't just search static package graph entries (and fail to find metadata in dynamic packages)

* Revise ResolveThirdPartyType() to be savvy to dynamic package graph

* Incorporated feedback

* Added PACKAGE_FILTER_STATIC|DYNAMIC so metadata resolution also doesn't just search static package graph entries (and fail to find metadata in dynamic packages)

* Revise ResolveThirdPartyType() to be savvy to dynamic package graph

* Incorporated feedback

* Add Dynamic+Static filters when retrieving the package graph as required to get the whole package graph

* Fix check for not-found-in-package-graph-let's-try-exe-dir

* Updated by VS

* Incorporated feedback
DrusTheAxe added a commit that referenced this pull request Jun 8, 2022
#1649) (#2537)

* Added PACKAGE_FILTER_STATIC|DYNAMIC so metadata resolution also doesn't just search static package graph entries (and fail to find metadata in dynamic packages)

* Revise ResolveThirdPartyType() to be savvy to dynamic package graph

* Incorporated feedback

* Added PACKAGE_FILTER_STATIC|DYNAMIC so metadata resolution also doesn't just search static package graph entries (and fail to find metadata in dynamic packages)

* Revise ResolveThirdPartyType() to be savvy to dynamic package graph

* Incorporated feedback

* Add Dynamic+Static filters when retrieving the package graph as required to get the whole package graph

* Fix check for not-found-in-package-graph-let's-try-exe-dir

* Updated by VS

* Incorporated feedback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ApiInformation.IsPropertyPresent throws in an unpackaged app
7 participants