Skip to content

Commit 10609e9

Browse files
authored
DynamicDependencies: Only Detour functions in not-packaged processes (#620)
* Only detour APIs if DynamicDependencies are enabled (i.e. process is not-packaged). Detoured GetCurrentPackageInfo2 incorrectly continued on if there were no dynamic packages in the package graph and GetCurrentPackageInfo2 for the static package graph didn't return APPMODEL_ERROR_NO_PACKAGE. Expanded tests * Add tests fto verify GetCurrentPackageInfo[2]'s invalid parameter handling
1 parent dd87c67 commit 10609e9

4 files changed

Lines changed: 123 additions & 4 deletions

File tree

dev/DynamicDependency/PackageGraphManager.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ HRESULT MddCore::PackageGraphManager::GetCurrentPackageInfo2(
6565
UINT32* count,
6666
GetCurrentPackageInfo2Function getCurrentPackageInfo2) noexcept try
6767
{
68+
// Check parameter(s) per GetCurrentPackageInfo2 compatibility
69+
// * bufferLength is required
70+
// * buffer is required if bufferLength >0
71+
// * count is required if buffer is not nullptr
72+
RETURN_HR_IF(E_INVALIDARG, (bufferLength == nullptr) || (*bufferLength > 0 && buffer == nullptr) || ((count == nullptr) && (buffer != nullptr)));
73+
6874
if (count)
6975
{
7076
*count = 0;
@@ -75,14 +81,15 @@ HRESULT MddCore::PackageGraphManager::GetCurrentPackageInfo2(
7581
// Is the package graph empty?
7682
if (s_packageGraph.PackageGraphNodes().empty())
7783
{
78-
// No dynamic package data. Is there a static package graph?
84+
// No dynamic package data. Is there a static package graph? Regardless of the outcome our work here is done
7985
UINT32 length{};
8086
const LONG rc{ getCurrentPackageInfo2(flags, packagePathType, &length, nullptr, nullptr) };
81-
if (rc == APPMODEL_ERROR_NO_PACKAGE)
87+
if ((rc == ERROR_SUCCESS) || (rc == APPMODEL_ERROR_NO_PACKAGE) || (rc == ERROR_INSUFFICIENT_BUFFER))
8288
{
83-
// No static package data either
84-
RETURN_WIN32(APPMODEL_ERROR_NO_PACKAGE);
89+
// Don't log expected outcomes (Success, AppmodelErrorNoPackage, ErrorInsufficientBuffer)
90+
return HRESULT_FROM_WIN32(rc);
8591
}
92+
RETURN_WIN32_MSG(rc, "GetCurrentPackageInfo2(): %d (0x%X)", rc, rc);
8693
}
8794

8895
// We manage the package graph as a list of nodes, where each contain contains information about 1+ package.

dev/ProjectReunion_DLL/dllmain.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,22 @@
88

99
#include <../Detours/detours.h>
1010

11+
static bool IsPackagedProcess()
12+
{
13+
UINT32 n{};
14+
const auto rc = ::GetCurrentPackageFullName(&n, nullptr);
15+
(void) LOG_HR_IF_MSG(HRESULT_FROM_WIN32(rc), (rc != APPMODEL_ERROR_NO_PACKAGE) && (rc != ERROR_INSUFFICIENT_BUFFER), "GetCurrentPackageFullName rc=%d", rc);
16+
return rc == ERROR_INSUFFICIENT_BUFFER;
17+
}
18+
1119
static HRESULT DetoursInitialize()
1220
{
21+
// Only detour APIs for not-packaged processes
22+
if (IsPackagedProcess())
23+
{
24+
return S_OK;
25+
}
26+
1327
// Do we need to detour APIs?
1428
if (DetourIsHelperProcess())
1529
{
@@ -29,6 +43,12 @@ static HRESULT DetoursInitialize()
2943

3044
static HRESULT DetoursShutdown()
3145
{
46+
// Only detour APIs for not-packaged processes
47+
if (IsPackagedProcess())
48+
{
49+
return S_OK;
50+
}
51+
3252
// Did we detour APIs?
3353
if (DetourIsHelperProcess())
3454
{

test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,96 @@ namespace Test::DynamicDependency
8888
MddBootstrapShutdown();
8989
}
9090

91+
TEST_METHOD(GetCurrentPackageInfo_NotPackaged_InvalidParameter)
92+
{
93+
const UINT32 c_filter{ PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_INFORMATION_BASIC };
94+
95+
{
96+
Assert::AreEqual(E_INVALIDARG, HRESULT_FROM_WIN32(::GetCurrentPackageInfo(c_filter, nullptr, nullptr, nullptr)));
97+
}
98+
{
99+
UINT32 count{};
100+
Assert::AreEqual(E_INVALIDARG, HRESULT_FROM_WIN32(::GetCurrentPackageInfo(c_filter, nullptr, nullptr, &count)));
101+
}
102+
103+
{
104+
UINT32 bufferLength{ 1 };
105+
Assert::AreEqual(E_INVALIDARG, HRESULT_FROM_WIN32(::GetCurrentPackageInfo(c_filter, &bufferLength, nullptr, nullptr)));
106+
}
107+
{
108+
UINT32 bufferLength{ 1 };
109+
UINT32 count{};
110+
Assert::AreEqual(E_INVALIDARG, HRESULT_FROM_WIN32(::GetCurrentPackageInfo(c_filter, &bufferLength, nullptr, &count)));
111+
}
112+
113+
{
114+
BYTE buffer[1]{};
115+
UINT32 bufferLength{ static_cast<UINT32>(ARRAYSIZE(buffer)) };
116+
Assert::AreEqual(E_INVALIDARG, HRESULT_FROM_WIN32(::GetCurrentPackageInfo(c_filter, &bufferLength, buffer, nullptr)));
117+
}
118+
}
119+
120+
TEST_METHOD(GetCurrentPackageInfo_NotPackaged)
121+
{
122+
VerifyGetCurrentPackageInfo();
123+
124+
winrt::hstring packageFamilyName{ Test::Packages::DynamicDependencyLifetimeManager::c_PackageFamilyName };
125+
auto applicationData{ winrt::Windows::Management::Core::ApplicationDataManager::CreateForPackageFamily(packageFamilyName) };
126+
127+
Assert::AreEqual(S_OK, MddBootstrapTestInitialize(Test::Packages::DynamicDependencyLifetimeManager::c_PackageNamePrefix, Test::Packages::DynamicDependencyLifetimeManager::c_PackagePublisherId));
128+
129+
// Version <major>.0.0.0 to find any framework package for this major version
130+
PACKAGE_VERSION minVersion{ static_cast<UINT64>(Test::Packages::DynamicDependencyLifetimeManager::c_Version.Major) << 48 };
131+
Assert::AreEqual(S_OK, MddBootstrapInitialize(minVersion));
132+
133+
VerifyGetCurrentPackageInfo(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), 1, 700);
134+
135+
winrt::Windows::ApplicationModel::AppExtensions::AppExtensionCatalog::Open(L"Does.Not.Exist");
136+
137+
MddBootstrapShutdown();
138+
139+
VerifyGetCurrentPackageInfo();
140+
}
141+
142+
#if defined(TODO_EnableAfterConvertingToTAEF)
143+
TEST_METHOD(GetCurrentPackageInfo_Packaged)
144+
{
145+
VerifyGetCurrentPackageInfo();
146+
147+
winrt::hstring packageFamilyName{ Test::Packages::DynamicDependencyLifetimeManager::c_PackageFamilyName };
148+
auto applicationData{ winrt::Windows::Management::Core::ApplicationDataManager::CreateForPackageFamily(packageFamilyName) };
149+
150+
Assert::AreEqual(S_OK, MddBootstrapTestInitialize(Test::Packages::DynamicDependencyLifetimeManager::c_PackageNamePrefix, Test::Packages::DynamicDependencyLifetimeManager::c_PackagePublisherId));
151+
152+
// Version <major>.0.0.0 to find any framework package for this major version
153+
PACKAGE_VERSION minVersion{ static_cast<UINT64>(Test::Packages::DynamicDependencyLifetimeManager::c_Version.Major) << 48 };
154+
Assert::AreEqual(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), MddBootstrapInitialize(minVersion));
155+
156+
VerifyGetCurrentPackageInfo();
157+
}
158+
#endif
159+
160+
private:
161+
static void VerifyGetCurrentPackageInfo(
162+
const HRESULT expectedHR = HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE),
163+
const UINT32 expectedCount = 0,
164+
const UINT32 minExpectedBufferLength = 0)
165+
{
166+
UINT32 bufferLength{};
167+
UINT32 count{};
168+
Assert::AreEqual(expectedHR, HRESULT_FROM_WIN32(::GetCurrentPackageInfo(PACKAGE_FILTER_HEAD | PACKAGE_FILTER_DIRECT | PACKAGE_INFORMATION_BASIC, &bufferLength, nullptr, &count)));
169+
Assert::AreEqual(expectedCount, count);
170+
if (minExpectedBufferLength > 0)
171+
{
172+
auto message{ wil::str_printf<wil::unique_process_heap_string>(L"GetCurrentPackageInfo2() expectedBufferLength>=%u bufferLength=%u", minExpectedBufferLength, bufferLength) };
173+
Assert::IsTrue(bufferLength >= minExpectedBufferLength, message.get());
174+
}
175+
else
176+
{
177+
Assert::AreEqual(0u, bufferLength);
178+
}
179+
}
180+
91181
private:
92182
static wil::unique_hmodule m_bootstrapDll;
93183
};

test/DynamicDependency/Test_Win32/pch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include <winrt/Windows.Foundation.Collections.h>
2020

2121
#include <winrt/Windows.ApplicationModel.h>
22+
#include <winrt/Windows.ApplicationModel.AppExtensions.h>
23+
#include <winrt/Windows.Management.Core.h>
2224
#include <winrt/Windows.Management.Deployment.h>
2325

2426
#include <filesystem>

0 commit comments

Comments
 (0)