winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 3f0346609df7a4efc2851858a8e6a8c2507d024a
parent 6aff1fb2f5e5eeee808efe2e5a7f23711fe738bf
Author: Jonathan Abbott <jtabbott2001@gmail.com>
Date:   Thu, 21 Jul 2022 11:33:26 -0700

Expand WinMD discovery (#2348)


Diffstat:
Msrc/AppInstallerCLI.sln | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj | 4++--
Msrc/UndockedRegFreeWinRT/UndockedRegFreeWinRT/dllmain.cpp | 9++++-----
Msrc/UndockedRegFreeWinRT/UndockedRegFreeWinRT/typeresolution.cpp | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/UndockedRegFreeWinRT/UndockedRegFreeWinRT/typeresolution.h | 3+++
5 files changed, 141 insertions(+), 11 deletions(-)

diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln @@ -136,6 +136,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "COMServer", "COMServer\COMS EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.InProc", "Microsoft.Management.Deployment.InProc\Microsoft.Management.Deployment.InProc.vcxproj", "{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UndockedRegFreeWinRT", "UndockedRegFreeWinRT\UndockedRegFreeWinRT\UndockedRegFreeWinRT.vcxproj", "{31ED69A8-5310-45A9-953F-56C351D2C3E1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Detours", "UndockedRegFreeWinRT\detours\detours.vcxproj", "{787EC629-C0FB-4BA9-9746-4A82CD06B73E}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ManifestSchema\ManifestSchema.vcxitems*{1622da16-914f-4f57-a259-d5169003cc8c}*SharedItemsImports = 4 @@ -1026,6 +1030,62 @@ Global {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|x64.Build.0 = Release|x64 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|x86.ActiveCfg = Release|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|x86.Build.0 = Release|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|ARM.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|ARM64.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x64.ActiveCfg = Debug|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x64.Build.0 = Debug|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x86.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Debug|x86.Build.0 = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|Any CPU.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|Any CPU.Build.0 = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|ARM.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|ARM64.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|x64.ActiveCfg = Debug|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Fuzzing|x86.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|Any CPU.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM64.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x64.ActiveCfg = Debug|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x64.Build.0 = Debug|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x86.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x86.Build.0 = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|Any CPU.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|Any CPU.Build.0 = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|ARM.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|ARM64.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x64.ActiveCfg = Debug|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x64.Build.0 = Debug|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x86.ActiveCfg = Debug|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x86.Build.0 = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|ARM.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|ARM64.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|x64.ActiveCfg = Debug|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|x64.Build.0 = Debug|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|x86.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|x86.Build.0 = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|Any CPU.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|Any CPU.Build.0 = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|ARM.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|ARM64.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|x64.ActiveCfg = Debug|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Fuzzing|x86.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|Any CPU.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|ARM.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|ARM64.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x64.ActiveCfg = Debug|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x64.Build.0 = Debug|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x86.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x86.Build.0 = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|Any CPU.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|Any CPU.Build.0 = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|ARM.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|ARM64.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x64.ActiveCfg = Debug|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x64.Build.0 = Debug|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x86.ActiveCfg = Debug|Win32 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x86.Build.0 = Debug|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1045,6 +1105,8 @@ Global {866C3F06-636F-4BE8-BC24-5F86ECC606A1} = {60618CAC-2995-4DF9-9914-45C6FC02C995} {1A47951F-5C7A-4D6D-BB5F-D77484437940} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7} {409CD681-22A4-469D-88AE-CB5E4836E07A} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7} + {31ED69A8-5310-45A9-953F-56C351D2C3E1} = {60618CAC-2995-4DF9-9914-45C6FC02C995} + {787EC629-C0FB-4BA9-9746-4A82CD06B73E} = {60618CAC-2995-4DF9-9914-45C6FC02C995} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B6FDB70C-A751-422C-ACD1-E35419495857} diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj @@ -200,12 +200,12 @@ </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> - <Import Project="..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> + <Import Project="$(SolutionDir)packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" /> </ImportGroup> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <PropertyGroup> <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> </PropertyGroup> - <Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> + <Error Condition="!Exists('$(SolutionDir)packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.ImplementationLibrary.1.0.200519.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" /> </Target> </Project> \ No newline at end of file diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/dllmain.cpp b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/dllmain.cpp @@ -306,7 +306,10 @@ HRESULT WINAPI RoResolveNamespaceDetour( PCWSTR exeFilePath = nullptr; UndockedRegFreeWinRT::GetProcessExeDir(&exeFilePath); auto pathReference = Microsoft::WRL::Wrappers::HStringReference(exeFilePath); - HSTRING packageGraphDirectories[] = { pathReference.Get() }; + PCWSTR dllFilePath = nullptr; + UndockedRegFreeWinRT::GetProcessDllDir(&dllFilePath); + auto dllPathReference = Microsoft::WRL::Wrappers::HStringReference(dllFilePath); + HSTRING packageGraphDirectories[] = { pathReference.Get(), dllPathReference.Get() }; HRESULT hr = TrueRoResolveNamespace(name, pathReference.Get(), ARRAYSIZE(packageGraphDirectories), packageGraphDirectories, metaDataFilePathsCount, metaDataFilePaths, @@ -442,10 +445,6 @@ HRESULT ExtRoLoadCatalog() BOOL WINAPI DllMain(HINSTANCE hmodule, DWORD reason, LPVOID /*lpvReserved*/) { - if (IsWindows1019H1OrGreater()) - { - return true; - } if (reason == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(hmodule); diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/typeresolution.cpp b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/typeresolution.cpp @@ -11,6 +11,7 @@ namespace UndockedRegFreeWinRT { static const UINT32 g_uiMaxTypeName = 512; static wil::unique_process_heap_string g_cachedProcessExeDir; + static wil::unique_process_heap_string g_cachedProcessDllDir; BOOL CALLBACK GetProcessExeDirInitOnceCallback( _Inout_ PINIT_ONCE, @@ -51,6 +52,57 @@ namespace UndockedRegFreeWinRT return S_OK; } + BOOL CALLBACK GetProcessDllDirInitOnceCallback( + _Inout_ PINIT_ONCE, + _Inout_opt_ PVOID, + _Out_opt_ PVOID*) + { + wil::unique_process_heap_string localDllPath; + HMODULE hm = NULL; + + // Get handle to the module that contains this function (this one). + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCWSTR)&GetProcessDllDirInitOnceCallback, &hm) == 0) + { + // Error has already been set (GetLastError). + return FALSE; + } + + // Get the path for this module. + HRESULT hr = wil::GetModuleFileNameW(hm, localDllPath); + if (FAILED_LOG(hr)) + { + SetLastError(hr); + return FALSE; + } + + // Modify the retrieved string to truncate the actual dll name and leave the containing directory path. This API + // expects a buffer size including the terminating null, so add 1 to the string length. + hr = PathCchRemoveFileSpec(localDllPath.get(), wcslen(localDllPath.get()) + 1); + if (FAILED_LOG(hr)) + { + SetLastError(hr); + return FALSE; + } + + g_cachedProcessDllDir = std::move(localDllPath); + return TRUE; + } + + // Returned string is cached globally, and should not be freed by the caller. + HRESULT GetProcessDllDir(PCWSTR* path) + { + *path = nullptr; + static INIT_ONCE ProcessDllDirInitOnce = INIT_ONCE_STATIC_INIT; + + RETURN_IF_WIN32_BOOL_FALSE(InitOnceExecuteOnce(&ProcessDllDirInitOnce, GetProcessDllDirInitOnceCallback, nullptr, nullptr)); + + // The cache has been successfully populated by the InitOnce, so we can just use it directly. + *path = g_cachedProcessDllDir.get(); + return S_OK; + } + HRESULT FindTypeInMetaDataFile( _In_ IMetaDataDispenserEx* pMetaDataDispenser, _In_ PCWSTR pszFullName, @@ -446,10 +498,24 @@ namespace UndockedRegFreeWinRT if (hr == RO_E_METADATA_NAME_NOT_FOUND) { - // For compatibility purposes, if we fail to find the type in the unpackaged location, we should return - // HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE) instead of a "not found" error. This preserves the - // behavior that existed before unpackaged type resolution was implemented. - hr = HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE); + PCWSTR dllDir = nullptr; // Never freed; owned by process global. + RETURN_IF_FAILED(GetProcessDllDir(&dllDir)); + + hr = FindTypeInDirectoryWithNormalization( + pMetaDataDispenser, + pszFullName, + dllDir, + phstrMetaDataFilePath, + ppMetaDataImport, + pmdTypeDef); + + if (hr == RO_E_METADATA_NAME_NOT_FOUND) + { + // For compatibility purposes, if we fail to find the type in the unpackaged location, we should return + // HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE) instead of a "not found" error. This preserves the + // behavior that existed before unpackaged type resolution was implemented. + hr = HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE); + } } return hr; } diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/typeresolution.h b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/typeresolution.h @@ -25,6 +25,9 @@ namespace UndockedRegFreeWinRT // Returned string is cached globally, and should not be freed by the caller. HRESULT GetProcessExeDir(PCWSTR* path); + // Returned string is cached globally, and should not be freed by the caller. + HRESULT GetProcessDllDir(PCWSTR* path); + HRESULT FindTypeInMetaDataFile( _In_ IMetaDataDispenserEx* pMetaDataDispenser, _In_ PCWSTR pszFullName,