Skip to content

Commit

Permalink
v1.1 SDK throws an access violation from MddBootstrapInitialize's log…
Browse files Browse the repository at this point in the history
…ging code if no matching packages are installed #2592 (#2608) - 1.1-servicing (#2624)

!cherry-pick 42ba331
!cherry-pick 6198c22

1.1-servicing of v1.1 SDK throws an access violation from MddBootstrapInitialize's logging code if no matching packages are installed #2592 (#2608)

Summary

Telemetry char=crash. Needs be string-literal
Retrieve the Main package's family name for AppData for the release matching the framework (not always 1.0)
Add/Remove the test Main package (DataStore) just like we do the test Framework
Fixup test packages with naming more aligned with the actual runtime (test package Names were "blah" but product is "blah-1.2", and we now have code that parses release out of package name for further processing)
For more details see #2608

https://task.ms/39995920 for 1.1-servicing consideration
  • Loading branch information
DrusTheAxe authored Jun 17, 2022
1 parent 1abc818 commit 9bfb310
Show file tree
Hide file tree
Showing 62 changed files with 841 additions and 502 deletions.
1 change: 0 additions & 1 deletion WindowsAppRuntime.sln
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,6 @@ Global
dev\AppLifecycle\AppLifecycle.vcxitems*{e3a522a3-6635-4a42-bded-1af46a15f63c}*SharedItemsImports = 9
test\inc\inc.vcxitems*{e5659a29-fe68-417b-9bc5-613073dd54df}*SharedItemsImports = 4
test\inc\inc.vcxitems*{e977b1bd-00dc-4085-a105-e0a18e0183d7}*SharedItemsImports = 4
dev\Common\Common.vcxitems*{f76b776e-86f5-48c5-8fc7-d2795ecc9746}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
2 changes: 1 addition & 1 deletion dev/Common/WindowsAppRuntime.SelfContained.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ STDAPI WindowsAppRuntime_IsSelfContained(
const PACKAGE_INFO* packageInfo{};
wil::unique_cotaskmem_ptr<BYTE[]> buffer;
RETURN_IF_FAILED(::AppModel::PackageGraph::GetCurrentPackageGraph(flags, packageInfoCount, packageInfo, buffer));
const auto frameworkPackageFamilyName{ ::WindowsAppRuntime::VersionInfo::GetPackageFamilyName() };
const auto frameworkPackageFamilyName{ ::WindowsAppRuntime::VersionInfo::Framework::GetPackageFamilyName() };
for (uint32_t index=0; index < packageInfoCount; ++index)
{
if (CompareStringOrdinal(packageInfo[index].packageFamilyName, -1, frameworkPackageFamilyName.c_str(), -1, TRUE) == CSTR_EQUAL)
Expand Down
38 changes: 36 additions & 2 deletions dev/Common/WindowsAppRuntime.VersionInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "WindowsAppRuntime.VersionInfo.h"

static std::wstring g_test_frameworkPackageFamilyName;
static std::wstring g_test_mainPackageFamilyName;

namespace Microsoft::WindowsAppRuntime::VersionInfo
{
Expand All @@ -26,6 +27,18 @@ class RuntimeInformation
return frameworkPackageFamilyName;
}

static const std::wstring& GetMainPackageFamilyName()
{
if (!g_test_mainPackageFamilyName.empty())
{
return g_test_mainPackageFamilyName;
}

const uint32_t c_mainPackageFamilyNameResourceId{ 10002 };
static std::wstring mainPackageFamilyName{ LoadStringWFromResource(c_mainPackageFamilyNameResourceId) };
return mainPackageFamilyName;
}

private:
static std::wstring LoadStringWFromResource(uint32_t id)
{
Expand Down Expand Up @@ -65,18 +78,39 @@ STDAPI WindowsAppRuntime_VersionInfo_MSIX_Framework_PackageFamilyName_Get(
}
CATCH_RETURN();

STDAPI WindowsAppRuntime_VersionInfo_MSIX_Main_PackageFamilyName_Get(
PCWSTR* packageFamilyName) noexcept try
{
*packageFamilyName = nullptr;
const auto& mainPackageFamilyName{ ::Microsoft::WindowsAppRuntime::VersionInfo::RuntimeInformation::GetMainPackageFamilyName() };
*packageFamilyName = mainPackageFamilyName.c_str();
RETURN_HR_IF_MSG(E_UNEXPECTED, mainPackageFamilyName.empty(), "WindowsAppSDK main PackageFamilyName resource not valid (\"\")");
return S_OK;
}
CATCH_RETURN();

STDAPI WindowsAppRuntime_VersionInfo_TestInitialize(
PCWSTR frameworkPackageFamilyName) noexcept try
PCWSTR frameworkPackageFamilyName,
PCWSTR mainPackageFamilyName) noexcept try
{
if (!frameworkPackageFamilyName || (*frameworkPackageFamilyName == L'0'))
// Both or neither must be valued
const bool frameworkPackageFamilyNameIsEmpty{ !frameworkPackageFamilyName || (*frameworkPackageFamilyName == L'0') };
const bool mainPackageFamilyNameIsEmpty{ !mainPackageFamilyName || (*mainPackageFamilyName == L'0') };
FAIL_FAST_HR_IF(E_UNEXPECTED, frameworkPackageFamilyNameIsEmpty && !mainPackageFamilyNameIsEmpty);
FAIL_FAST_HR_IF(E_UNEXPECTED, !frameworkPackageFamilyNameIsEmpty && mainPackageFamilyNameIsEmpty);

// Update our state
if (frameworkPackageFamilyNameIsEmpty)
{
// Shutdown test support
g_test_frameworkPackageFamilyName.clear();
g_test_mainPackageFamilyName.clear();
}
else
{
// Initialize test support
g_test_frameworkPackageFamilyName = frameworkPackageFamilyName;
g_test_mainPackageFamilyName = mainPackageFamilyName;
}
return S_OK;
}
Expand Down
33 changes: 29 additions & 4 deletions dev/Common/WindowsAppRuntime.VersionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,70 @@
STDAPI WindowsAppRuntime_VersionInfo_MSIX_Framework_PackageFamilyName_Get(
PCWSTR* packageFamilyName) noexcept;

/// Determine if Windows App SDK in use by the current process is deployed Self-Contained (vs deployed as MSIX packages)
///
/// @param packageFamilyName main's package family name.
STDAPI WindowsAppRuntime_VersionInfo_MSIX_Main_PackageFamilyName_Get(
PCWSTR* packageFamilyName) noexcept;

/// Initialize SelfContained's test support. This will constrain package enumeration
/// and matching for test purposes.
///
/// @param frameworkPackageFamilyName only match framework packages with this family name.
/// If nullptr test support is disabled.
/// @param mainPackageFamilyName only match main packages with this family name.
/// If nullptr test support is disabled.
///
/// @note Not for product use. This is for test purposes only to verify the implementation.
STDAPI WindowsAppRuntime_VersionInfo_TestInitialize(
PCWSTR frameworkPackageFamilyName) noexcept;
PCWSTR frameworkPackageFamilyName,
PCWSTR mainPackageFamilyName) noexcept;

#if defined(__cplusplus)
namespace WindowsAppRuntime::VersionInfo
{
namespace Framework
{
/// Return the Windows App SDK framework's package family name.
inline std::wstring GetPackageFamilyName()
{
PCWSTR packageFamilyName{};
THROW_IF_FAILED(WindowsAppRuntime_VersionInfo_MSIX_Framework_PackageFamilyName_Get(&packageFamilyName));
return std::wstring{ packageFamilyName };
}
}

namespace Main
{
/// Return the Windows App SDK main's package family name.
inline std::wstring GetPackageFamilyName()
{
PCWSTR packageFamilyName{};
THROW_IF_FAILED(WindowsAppRuntime_VersionInfo_MSIX_Main_PackageFamilyName_Get(&packageFamilyName));
return std::wstring{ packageFamilyName };
}
}

/// Initialize VersionInfo's test support. This will constrain package enumeration
/// and matching for test purposes.
///
/// @param frameworkPackageFamilyName only match framework packages with this family name
/// @param mainPackageFamilyName only match main packages with this family name
///
/// @note Not for product use. This is for test purposes only to verify the implementation.
inline void TestInitialize(
_In_ PCWSTR frameworkPackageFamilyName)
_In_ PCWSTR frameworkPackageFamilyName,
_In_ PCWSTR mainPackageFamilyName)
{
THROW_IF_FAILED(WindowsAppRuntime_VersionInfo_TestInitialize(frameworkPackageFamilyName));
THROW_IF_FAILED(WindowsAppRuntime_VersionInfo_TestInitialize(frameworkPackageFamilyName, mainPackageFamilyName));
}

/// Shutdown VersionInfo's test support.
///
/// @note Not for product use. This is for test purposes only to verify the implementation.
inline void TestShutdown()
{
WindowsAppRuntime_VersionInfo_TestInitialize(nullptr);
WindowsAppRuntime_VersionInfo_TestInitialize(nullptr, nullptr);
}
}
#endif // defined(__cplusplus)
Expand Down
37 changes: 30 additions & 7 deletions dev/DynamicDependency/API/DataStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,36 @@ std::filesystem::path MddCore::DataStore::GetDataStorePathForUserViaCOMDataStore

std::filesystem::path MddCore::DataStore::GetDataStorePathForUserViaApplicationDataManager()
{
static winrt::hstring mainPackageFamilyName{ GetWindowsAppRuntimeMainPackageFamilyName().c_str() };
auto applicationData{ winrt::Windows::Management::Core::ApplicationDataManager::CreateForPackageFamily(mainPackageFamilyName) };

return std::filesystem::path(applicationData.LocalFolder().Path().c_str());
const auto& mainPackageFamilyName{ GetWindowsAppRuntimeMainPackageFamilyName() };
try
{
static winrt::hstring mainPackageFamilyNameAsHString{ mainPackageFamilyName.c_str() };
winrt::Windows::Storage::ApplicationData applicationData{ winrt::Windows::Management::Core::ApplicationDataManager::CreateForPackageFamily(mainPackageFamilyNameAsHString) };
return std::filesystem::path(applicationData.LocalFolder().Path().c_str());
}
catch (winrt::hresult_error& e)
{
if (e.code() == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
// If the Main package isn't registered for the caller there'll be no ApplicationData
// available but we get ERROR_FILE_NOT_FOUND. This may be technically correct but it's
// routinely misleading as that's the very (most) common NotFound error for Registry
// APIs. Worse, it'll cause us to throw it as an exception but our higher level
// machine handles 'NotFound' as ERROR_NOT_FOUND so this would just further confuse
// folks (and our higher level logic before it even makes it to the caller!). So we'll
// trap the ERROR_FILE_NOT_FOUND case and map it to our more expected ERROR_NOT_FOUND
// (and log something so callers can understand).
THROW_HR_MSG(MDD_E_WINDOWSAPPRUNTIME_DATASTORE_NOT_FOUND, "PackageFamily:%ls", mainPackageFamilyName.c_str());
}
throw;
}
}

std::wstring MddCore::DataStore::GetWindowsAppRuntimeMainPackageFamilyName()
{
#if 1
return ::WindowsAppRuntime::VersionInfo::Main::GetPackageFamilyName();
#else
const UINT32 flags{ PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_FILTER_STATIC | PACKAGE_FILTER_DYNAMIC | PACKAGE_INFORMATION_BASIC };
uint32_t packageInfosCount{};
const PACKAGE_INFO* packageInfos{};
Expand All @@ -206,7 +228,7 @@ std::wstring MddCore::DataStore::GetWindowsAppRuntimeMainPackageFamilyName()
continue;
}
// Framework package's name in the package graph is Microsoft.WindowsAppRuntime.Main.<major>.<minor>
// Framework package's name in the package graph is Microsoft.WindowsAppRuntime.<major>.<minor>
const auto packageName{ packageId.name };
const auto packageNameLength{ wcslen(packageName) };
PCWSTR c_windowsAppRuntimeNamePrefix{ L"Microsoft.WindowsAppRuntime." };
Expand All @@ -219,14 +241,15 @@ std::wstring MddCore::DataStore::GetWindowsAppRuntimeMainPackageFamilyName()
{
continue;
}
PCWSTR packageNameSuffix{ packageName + packageNameLength };
PCWSTR packageNameSuffix{ packageName + c_windowsAppRuntimeNamePrefixLength };
// Gotcha!
WCHAR mainPackageFamilyName[PACKAGE_FAMILY_NAME_MAX_LENGTH + 1]{};
wsprintf(mainPackageFamilyName, L"MicrosoftCorporationII.WindowsAppRuntime.Main.1.0_8wekyb3d8bbwe", packageNameSuffix);
wsprintf(mainPackageFamilyName, L"MicrosoftCorporationII.WinAppRuntime.Main.%s_8wekyb3d8bbwe", packageNameSuffix);
return std::wstring(mainPackageFamilyName);
}
// Didn't find the Windows App SDK framework package in the package graph. Can't determine the package identity!
THROW_HR(MDD_E_WINDOWSAPPRUNTIME_NOT_IN_PACKAGE_GRAPH);
#endif
}
3 changes: 3 additions & 0 deletions dev/DynamicDependency/API/MsixDynamicDependency.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
/// MSIX Dynamic Dependency HRESULT: Windows App Runtime is not in the package graph.
#define MDD_E_WINDOWSAPPRUNTIME_NOT_IN_PACKAGE_GRAPH _HRESULT_TYPEDEF_(0x80040001L)

/// MSIX Dynamic Dependency HRESULT: Data Store not found (Windows App Runtime's Main package not registered?)
#define MDD_E_WINDOWSAPPRUNTIME_DATASTORE_NOT_FOUND _HRESULT_TYPEDEF_(0x80040002L)

/// MSIX Dynamic Dependency: Bootstrap initialization is scanning for an applicable DynamicDependencyLifetimeManager (DDLM) package
#define MDD_E_BOOTSTRAP_INITIALIZE_SCAN_FOR_DDLM _HRESULT_TYPEDEF_(0x80040010L)

Expand Down
1 change: 1 addition & 0 deletions dev/DynamicDependency/API/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@
#include <appmodel.packagegraph.h>
#include <microsoft.utf8.h>
#include <security.integritylevel.h>
#include <windowsappruntime.versioninfo.h>
Loading

0 comments on commit 9bfb310

Please sign in to comment.