@joebigelow / wix-1 / commits / 90982fbf

Add PathConcatRelativeToBase and use it in Burn.

Fixes 6707

Sean Hall committed May 26, 2022 at 17:34 UTC 90982fbf1c887a3ed3454f9ab3ab8dfbd57a1383
14 files changed +233 -41
src/burn/engine/apply.cpp
+1 -1
@@ -1371,7 +1371,7 @@ static HRESULT LayoutBundle(
1371 ExitOnFailure(hr, "Failed to get path to bundle to layout.");
1372 }
1373
1374 - hr = PathConcat(pContext->wzLayoutDirectory, wzExecutableName, &sczDestinationPath);
1374 + hr = PathConcatRelativeToBase(pContext->wzLayoutDirectory, wzExecutableName, &sczDestinationPath);
1375 ExitOnFailure(hr, "Failed to concat layout path for bundle.");
1376
1377 // If the destination path is the currently running bundle, bail.
src/burn/engine/bundlepackageengine.cpp
+26 -8
@@ -23,6 +23,7 @@ static HRESULT ExecuteBundle(
23 __in BOOTSTRAPPER_ACTION_STATE action,
24 __in BOOTSTRAPPER_RELATION_TYPE relationType,
25 __in BURN_PACKAGE* pPackage,
26 + __in BOOL fPseudoPackage,
27 __in_z_opt LPCWSTR wzParent,
28 __in_z_opt LPCWSTR wzIgnoreDependencies,
29 __in_z_opt LPCWSTR wzAncestors,
@@ -614,7 +615,7 @@ extern "C" HRESULT BundlePackageEngineExecutePackage(
615 BOOTSTRAPPER_RELATION_TYPE relationType = BOOTSTRAPPER_RELATION_CHAIN_PACKAGE;
616 BURN_PACKAGE* pPackage = pExecuteAction->bundlePackage.pPackage;
617
617 - return ExecuteBundle(pCache, pVariables, fRollback, pfnGenericMessageHandler, pvContext, action, relationType, pPackage, wzParent, wzIgnoreDependencies, wzAncestors, wzEngineWorkingDirectory, pRestart);
618 + return ExecuteBundle(pCache, pVariables, fRollback, pfnGenericMessageHandler, pvContext, action, relationType, pPackage, FALSE, wzParent, wzIgnoreDependencies, wzAncestors, wzEngineWorkingDirectory, pRestart);
619 }
620
621 extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle(
@@ -636,7 +637,7 @@ extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle(
637 BOOTSTRAPPER_RELATION_TYPE relationType = ConvertRelationType(pRelatedBundle->planRelationType);
638 BURN_PACKAGE* pPackage = &pRelatedBundle->package;
639
639 - return ExecuteBundle(pCache, pVariables, fRollback, pfnGenericMessageHandler, pvContext, action, relationType, pPackage, wzParent, wzIgnoreDependencies, wzAncestors, wzEngineWorkingDirectory, pRestart);
640 + return ExecuteBundle(pCache, pVariables, fRollback, pfnGenericMessageHandler, pvContext, action, relationType, pPackage, TRUE, wzParent, wzIgnoreDependencies, wzAncestors, wzEngineWorkingDirectory, pRestart);
641 }
642
643 extern "C" void BundlePackageEngineUpdateInstallRegistrationState(
@@ -733,6 +734,7 @@ static HRESULT ExecuteBundle(
734 __in BOOTSTRAPPER_ACTION_STATE action,
735 __in BOOTSTRAPPER_RELATION_TYPE relationType,
736 __in BURN_PACKAGE* pPackage,
737 + __in BOOL fPseudoPackage,
738 __in_z_opt LPCWSTR wzParent,
739 __in_z_opt LPCWSTR wzIgnoreDependencies,
740 __in_z_opt LPCWSTR wzAncestors,
@@ -759,17 +761,33 @@ static HRESULT ExecuteBundle(
761 LPCWSTR wzOperationCommandLine = NULL;
762 BOOL fRunEmbedded = pPackage->Bundle.fSupportsBurnProtocol;
763
762 - // get cached executable path
763 - hr = CacheGetCompletedPath(pCache, pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory);
764 - ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId);
764 + if (fPseudoPackage)
765 + {
766 + if (!PathIsFullyQualified(pPackagePayload->sczFilePath, NULL))
767 + {
768 + ExitWithRootFailure(hr, E_INVALIDSTATE, "Related bundles must have a fully qualified target path.");
769 + }
770 +
771 + hr = StrAllocString(&sczExecutablePath, pPackagePayload->sczFilePath, 0);
772 + ExitOnFailure(hr, "Failed to build executable path.");
773 +
774 + hr = PathGetDirectory(sczExecutablePath, &sczCachedDirectory);
775 + ExitOnFailure(hr, "Failed to get cached path for related bundle: %ls", pPackage->sczId);
776 + }
777 + else
778 + {
779 + // get cached executable path
780 + hr = CacheGetCompletedPath(pCache, pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory);
781 + ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId);
782 +
783 + hr = PathConcatRelativeToBase(sczCachedDirectory, pPackagePayload->sczFilePath, &sczExecutablePath);
784 + ExitOnFailure(hr, "Failed to build executable path.");
785 + }
786
787 // Best effort to set the execute package cache folder and action variables.
788 VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
789 VariableSetNumeric(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, action, TRUE);
790
770 - hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczExecutablePath);
771 - ExitOnFailure(hr, "Failed to build executable path.");
772 -
791 // pick arguments
792 switch (action)
793 {
src/burn/engine/cache.cpp
+16 -16
@@ -251,7 +251,7 @@ extern "C" HRESULT CacheInitializeSources(
251 hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczId, &sczCompletedFolder);
252 ExitOnFailure(hr, "Failed to get completed path for bundle.");
253
254 - hr = PathConcat(sczCompletedFolder, pRegistration->sczExecutableName, &sczCompletedPath);
254 + hr = PathConcatRelativeToBase(sczCompletedFolder, pRegistration->sczExecutableName, &sczCompletedPath);
255 ExitOnFailure(hr, "Failed to combine working path with engine file name.");
256
257 hr = PathCompare(sczCurrentPath, sczCompletedPath, &nCompare);
@@ -390,7 +390,7 @@ extern "C" HRESULT CacheCalculateBundleLayoutWorkingPath(
390
391 HRESULT hr = S_OK;
392
393 - hr = PathConcat(pCache->sczAcquisitionFolder, wzBundleId, psczWorkingPath);
393 + hr = PathConcatRelativeToBase(pCache->sczAcquisitionFolder, wzBundleId, psczWorkingPath);
394 ExitOnFailure(hr, "Failed to append bundle id for bundle layout working path.");
395
396 LExit:
@@ -407,7 +407,7 @@ extern "C" HRESULT CacheCalculatePayloadWorkingPath(
407
408 HRESULT hr = S_OK;
409
410 - hr = PathConcat(pCache->sczAcquisitionFolder, pPayload->sczKey, psczWorkingPath);
410 + hr = PathConcatRelativeToBase(pCache->sczAcquisitionFolder, pPayload->sczKey, psczWorkingPath);
411 ExitOnFailure(hr, "Failed to append Id as payload unverified path.");
412
413 LExit:
@@ -424,7 +424,7 @@ extern "C" HRESULT CacheCalculateContainerWorkingPath(
424
425 HRESULT hr = S_OK;
426
427 - hr = PathConcat(pCache->sczAcquisitionFolder, pContainer->sczHash, psczWorkingPath);
427 + hr = PathConcatRelativeToBase(pCache->sczAcquisitionFolder, pContainer->sczHash, psczWorkingPath);
428 ExitOnFailure(hr, "Failed to append hash as container unverified path.");
429
430 LExit:
@@ -479,7 +479,7 @@ extern "C" HRESULT CacheGetCompletedPath(
479 // GetRootPath returns S_FALSE if the package cache is redirected elsewhere.
480 fRedirected = S_FALSE == hr;
481
482 - hr = PathConcat(sczRootPath, wzCacheId, &sczCurrentCompletedPath);
482 + hr = PathConcatRelativeToBase(sczRootPath, wzCacheId, &sczCurrentCompletedPath);
483 ExitOnFailure(hr, "Failed to construct cache path.");
484
485 hr = PathBackslashTerminate(&sczCurrentCompletedPath);
@@ -492,7 +492,7 @@ extern "C" HRESULT CacheGetCompletedPath(
492 hr = GetRootPath(pCache, fPerMachine, FALSE, &sczRootPath);
493 ExitOnFailure(hr, "Failed to get old %hs package cache root directory.", fPerMachine ? "per-machine" : "per-user");
494
495 - hr = PathConcat(sczRootPath, wzCacheId, &sczDefaultCompletedPath);
495 + hr = PathConcatRelativeToBase(sczRootPath, wzCacheId, &sczDefaultCompletedPath);
496 ExitOnFailure(hr, "Failed to construct cache path.");
497
498 hr = PathBackslashTerminate(&sczDefaultCompletedPath);
@@ -933,7 +933,7 @@ extern "C" HRESULT CacheLayoutBundle(
933 HRESULT hr = S_OK;
934 LPWSTR sczTargetPath = NULL;
935
936 - hr = PathConcat(wzLayoutDirectory, wzExecutableName, &sczTargetPath);
936 + hr = PathConcatRelativeToBase(wzLayoutDirectory, wzExecutableName, &sczTargetPath);
937 ExitOnFailure(hr, "Failed to combine completed path with engine file name for layout.");
938
939 LogStringLine(REPORT_STANDARD, "Layout bundle from: '%ls' to: '%ls'", wzSourceBundlePath, sczTargetPath);
@@ -968,7 +968,7 @@ extern "C" HRESULT CacheCompleteBundle(
968 hr = CreateCompletedPath(pCache, fPerMachine, wzBundleId, NULL, &sczTargetDirectory);
969 ExitOnFailure(hr, "Failed to create completed cache path for bundle.");
970
971 - hr = PathConcat(sczTargetDirectory, wzExecutableName, &sczTargetPath);
971 + hr = PathConcatRelativeToBase(sczTargetDirectory, wzExecutableName, &sczTargetPath);
972 ExitOnFailure(hr, "Failed to combine completed path with engine file name.");
973
974 // We can't just use wzExecutablePath because we needed to call CreateCompletedPath to ensure that the destination was secured.
@@ -1021,7 +1021,7 @@ extern "C" HRESULT CacheLayoutContainer(
1021 HRESULT hr = S_OK;
1022 LPWSTR sczCachedPath = NULL;
1023
1024 - hr = PathConcat(wzLayoutDirectory, pContainer->sczFilePath, &sczCachedPath);
1024 + hr = PathConcatRelativeToBase(wzLayoutDirectory, pContainer->sczFilePath, &sczCachedPath);
1025 ExitOnFailure(hr, "Failed to concat complete cached path.");
1026
1027 hr = VerifyThenTransferContainer(pContainer, sczCachedPath, wzUnverifiedContainerPath, fMove, pfnCacheMessageHandler, pfnProgress, pContext);
@@ -1046,7 +1046,7 @@ extern "C" HRESULT CacheLayoutPayload(
1046 HRESULT hr = S_OK;
1047 LPWSTR sczCachedPath = NULL;
1048
1049 - hr = PathConcat(wzLayoutDirectory, pPayload->sczFilePath, &sczCachedPath);
1049 + hr = PathConcatRelativeToBase(wzLayoutDirectory, pPayload->sczFilePath, &sczCachedPath);
1050 ExitOnFailure(hr, "Failed to concat complete cached path.");
1051
1052 hr = VerifyThenTransferPayload(pPayload, sczCachedPath, wzUnverifiedPayloadPath, fMove, pfnCacheMessageHandler, pfnProgress, pContext);
@@ -1141,7 +1141,7 @@ extern "C" HRESULT CacheVerifyContainer(
1141 HRESULT hr = S_OK;
1142 LPWSTR sczCachedPath = NULL;
1143
1144 - hr = PathConcat(wzCachedDirectory, pContainer->sczFilePath, &sczCachedPath);
1144 + hr = PathConcatRelativeToBase(wzCachedDirectory, pContainer->sczFilePath, &sczCachedPath);
1145 ExitOnFailure(hr, "Failed to concat complete cached path.");
1146
1147 hr = VerifyFileAgainstContainer(pContainer, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE, pfnCacheMessageHandler, pfnProgress, pContext);
@@ -1163,7 +1163,7 @@ extern "C" HRESULT CacheVerifyPayload(
1163 HRESULT hr = S_OK;
1164 LPWSTR sczCachedPath = NULL;
1165
1166 - hr = PathConcat(wzCachedDirectory, pPayload->sczFilePath, &sczCachedPath);
1166 + hr = PathConcatRelativeToBase(wzCachedDirectory, pPayload->sczFilePath, &sczCachedPath);
1167 ExitOnFailure(hr, "Failed to concat complete cached path.");
1168
1169 hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE, pfnCacheMessageHandler, pfnProgress, pContext);
@@ -1596,7 +1596,7 @@ static HRESULT CreateCompletedPath(
1596 else
1597 {
1598 // Get the cache completed file path.
1599 - hr = PathConcat(sczCacheDirectory, wzFilePath, &sczCacheFile);
1599 + hr = PathConcatRelativeToBase(sczCacheDirectory, wzFilePath, &sczCacheFile);
1600 ExitOnFailure(hr, "Failed to construct cache file.");
1601
1602 // Don't reset permissions here. The payload's package must reset its cache folder when it starts caching.
@@ -1634,7 +1634,7 @@ static HRESULT CreateUnverifiedPath(
1634 pCache->fUnverifiedCacheFolderCreated = TRUE;
1635 }
1636
1637 - hr = PathConcat(sczUnverifiedCacheFolder, wzPayloadId, psczUnverifiedPayloadPath);
1637 + hr = PathConcatRelativeToBase(sczUnverifiedCacheFolder, wzPayloadId, psczUnverifiedPayloadPath);
1638 ExitOnFailure(hr, "Failed to concat payload id to unverified folder path.");
1639
1640 LExit:
@@ -2055,13 +2055,13 @@ static HRESULT CopyEngineToWorkingFolder(
2055 hr = CacheEnsureBaseWorkingFolder(pCache, &sczWorkingFolder);
2056 ExitOnFailure(hr, "Failed to create working path to copy engine.");
2057
2058 - hr = PathConcat(sczWorkingFolder, wzWorkingFolderName, &sczTargetDirectory);
2058 + hr = PathConcatRelativeToBase(sczWorkingFolder, wzWorkingFolderName, &sczTargetDirectory);
2059 ExitOnFailure(hr, "Failed to calculate the bundle working folder target name.");
2060
2061 hr = DirEnsureExists(sczTargetDirectory, NULL);
2062 ExitOnFailure(hr, "Failed create bundle working folder.");
2063
2064 - hr = PathConcat(sczTargetDirectory, wzExecutableName, &sczTargetPath);
2064 + hr = PathConcatRelativeToBase(sczTargetDirectory, wzExecutableName, &sczTargetPath);
2065 ExitOnFailure(hr, "Failed to combine working path with engine file name.");
2066
2067 // Copy the engine without any attached containers to the working path.
src/burn/engine/core.cpp
+1 -1
@@ -2217,7 +2217,7 @@ static HRESULT DetectPackagePayloadsCached(
2217 {
2218 BURN_PAYLOAD* pPayload = pPackage->payloads.rgItems[i].pPayload;
2219
2220 - hr = PathConcat(sczCachePath, pPayload->sczFilePath, &sczPayloadCachePath);
2220 + hr = PathConcatRelativeToBase(sczCachePath, pPayload->sczFilePath, &sczPayloadCachePath);
2221 ExitOnFailure(hr, "Failed to concat payload cache path.");
2222
2223 if (FileExistsEx(sczPayloadCachePath, NULL))
src/burn/engine/exeengine.cpp
+22 -6
@@ -361,17 +361,33 @@ extern "C" HRESULT ExeEngineExecutePackage(
361 BURN_PACKAGE* pPackage = pExecuteAction->exePackage.pPackage;
362 BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload;
363
364 - // get cached executable path
365 - hr = CacheGetCompletedPath(pCache, pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory);
366 - ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId);
364 + if (pPackage->Exe.fPseudoPackage && BURN_PAYLOAD_VERIFICATION_UPDATE_BUNDLE != pPackagePayload->verification)
365 + {
366 + if (!PathIsFullyQualified(pPackagePayload->sczFilePath, NULL))
367 + {
368 + ExitWithRootFailure(hr, E_INVALIDSTATE, "Pseudo ExePackages must have a fully qualified target path.");
369 + }
370 +
371 + hr = StrAllocString(&sczExecutablePath, pPackagePayload->sczFilePath, 0);
372 + ExitOnFailure(hr, "Failed to build executable path.");
373 +
374 + hr = PathGetDirectory(sczExecutablePath, &sczCachedDirectory);
375 + ExitOnFailure(hr, "Failed to get cached path for pseudo-package: %ls", pPackage->sczId);
376 + }
377 + else
378 + {
379 + // get cached executable path
380 + hr = CacheGetCompletedPath(pCache, pPackage->fPerMachine, pPackage->sczCacheId, &sczCachedDirectory);
381 + ExitOnFailure(hr, "Failed to get cached path for package: %ls", pPackage->sczId);
382 +
383 + hr = PathConcatRelativeToBase(sczCachedDirectory, pPackagePayload->sczFilePath, &sczExecutablePath);
384 + ExitOnFailure(hr, "Failed to build executable path.");
385 + }
386
387 // Best effort to set the execute package cache folder and action variables.
388 VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
389 VariableSetNumeric(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, pExecuteAction->exePackage.action, TRUE);
390
372 - hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczExecutablePath);
373 - ExitOnFailure(hr, "Failed to build executable path.");
374 -
391 // pick arguments
392 switch (pExecuteAction->exePackage.action)
393 {
src/burn/engine/msiengine.cpp
+2 -2
@@ -1236,7 +1236,7 @@ extern "C" HRESULT MsiEngineExecutePackage(
1236 // Best effort to set the execute package cache folder variable.
1237 VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
1238
1239 - hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczMsiPath);
1239 + hr = PathConcatRelativeToBase(sczCachedDirectory, pPackagePayload->sczFilePath, &sczMsiPath);
1240 ExitOnFailure(hr, "Failed to build MSI path.");
1241 }
1242
@@ -2195,7 +2195,7 @@ static HRESULT ConcatPatchProperty(
2195 hr = CacheGetCompletedPath(pCache, pMspPackage->fPerMachine, pMspPackage->sczCacheId, &sczCachedDirectory);
2196 ExitOnFailure(hr, "Failed to get cached path for MSP package: %ls", pMspPackage->sczId);
2197
2198 - hr = PathConcat(sczCachedDirectory, pMspPackagePayload->sczFilePath, &sczMspPath);
2198 + hr = PathConcatRelativeToBase(sczCachedDirectory, pMspPackagePayload->sczFilePath, &sczMspPath);
2199 ExitOnFailure(hr, "Failed to build MSP path.");
2200
2201 if (!sczPatches)
src/burn/engine/mspengine.cpp
+1 -1
@@ -613,7 +613,7 @@ extern "C" HRESULT MspEngineExecutePackage(
613 // Best effort to set the execute package cache folder variable.
614 VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
615
616 - hr = PathConcat(sczCachedDirectory, pMspPackagePayload->sczFilePath, &sczMspPath);
616 + hr = PathConcatRelativeToBase(sczCachedDirectory, pMspPackagePayload->sczFilePath, &sczMspPath);
617 ExitOnFailure(hr, "Failed to build MSP path.");
618
619 wzAppend = sczMspPath;
src/burn/engine/msuengine.cpp
+1 -1
@@ -320,7 +320,7 @@ extern "C" HRESULT MsuEngineExecutePackage(
320 // Best effort to set the execute package cache folder variable.
321 VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
322
323 - hr = PathConcat(sczCachedDirectory, pPackagePayload->sczFilePath, &sczMsuPath);
323 + hr = PathConcatRelativeToBase(sczCachedDirectory, pPackagePayload->sczFilePath, &sczMsuPath);
324 ExitOnFailure(hr, "Failed to build MSU path.");
325
326 // format command
src/burn/engine/payload.cpp
+1 -1
@@ -294,7 +294,7 @@ extern "C" HRESULT PayloadExtractUXContainer(
294 ExitOnFailure(hr, "Failed to find embedded payload: %ls", sczStreamName);
295
296 // make file path
297 - hr = PathConcat(wzTargetDir, pPayload->sczFilePath, &pPayload->sczLocalFilePath);
297 + hr = PathConcatRelativeToBase(wzTargetDir, pPayload->sczFilePath, &pPayload->sczLocalFilePath);
298 ExitOnFailure(hr, "Failed to concat file paths.");
299
300 // extract file
src/burn/engine/registration.cpp
+3 -3
@@ -1149,7 +1149,7 @@ static HRESULT SetPaths(
1149 ExitOnFailure(hr, "Failed to build cache directory.");
1150
1151 // build cached executable path
1152 - hr = PathConcat(sczCacheDirectory, pRegistration->sczExecutableName, &pRegistration->sczCacheExecutablePath);
1152 + hr = PathConcatRelativeToBase(sczCacheDirectory, pRegistration->sczExecutableName, &pRegistration->sczCacheExecutablePath);
1153 ExitOnFailure(hr, "Failed to build cached executable path.");
1154
1155 // build state file path
@@ -1367,7 +1367,7 @@ static HRESULT WriteSoftwareTags(
1367 hr = PathConcat(sczRootFolder, SWIDTAG_FOLDER, &sczTagFolder);
1368 ExitOnFailure(hr, "Failed to allocate regid folder path.");
1369
1370 - hr = PathConcat(sczTagFolder, pSoftwareTag->sczFilename, &sczPath);
1370 + hr = PathConcatRelativeToBase(sczTagFolder, pSoftwareTag->sczFilename, &sczPath);
1371 ExitOnFailure(hr, "Failed to allocate regid file path.");
1372
1373 hr = DirEnsureExists(sczTagFolder, NULL);
@@ -1405,7 +1405,7 @@ static HRESULT RemoveSoftwareTags(
1405 hr = PathConcat(sczRootFolder, SWIDTAG_FOLDER, &sczTagFolder);
1406 ExitOnFailure(hr, "Failed to allocate regid folder path.");
1407
1408 - hr = PathConcat(sczTagFolder, pSoftwareTag->sczFilename, &sczPath);
1408 + hr = PathConcatRelativeToBase(sczTagFolder, pSoftwareTag->sczFilename, &sczPath);
1409 ExitOnFailure(hr, "Failed to allocate regid file path.");
1410
1411 // Best effort to delete the software tag file and the regid folder.
src/ext/Bal/dnchost/dnchost.cpp
+1 -1
@@ -199,7 +199,7 @@ static HRESULT LoadDncConfiguration(
199 hr = XmlGetAttributeEx(pixnHost, L"FilePath", &sczPayloadName);
200 BalExitOnRequiredXmlQueryFailure(hr, "Failed to get WixBalBAFactoryAssembly/@FilePath.");
201
202 - hr = PathConcat(pArgs->pCommand->wzBootstrapperWorkingFolder, sczPayloadName, &pState->sczBaFactoryAssemblyPath);
202 + hr = PathConcatRelativeToBase(pArgs->pCommand->wzBootstrapperWorkingFolder, sczPayloadName, &pState->sczBaFactoryAssemblyPath);
203 BalExitOnFailure(hr, "Failed to create BaFactoryAssemblyPath.");
204
205 LPCWSTR wzFileName = PathFile(pState->sczBaFactoryAssemblyPath);
src/libs/dutil/WixToolset.DUtil/inc/pathutil.h
+11
@@ -236,6 +236,17 @@ DAPI_(HRESULT) PathConcatCch(
236 __deref_out_z LPWSTR* psczCombined
237 );
238
239 +/*******************************************************************
240 + PathConcatRelativeToBase - canonicalizes a relative path before
241 + concatenating it to the base path to ensure the resulting path
242 + is inside the base path.
243 +*******************************************************************/
244 +DAPI_(HRESULT) PathConcatRelativeToBase(
245 + __in LPCWSTR wzBase,
246 + __in_opt LPCWSTR wzRelative,
247 + __deref_out_z LPWSTR* psczCombined
248 + );
249 +
250 /*******************************************************************
251 PathCompare - compares the fully expanded path of the two paths using
252 ::CompareStringW().
src/libs/dutil/WixToolset.DUtil/path2utl.cpp
+40
@@ -131,6 +131,46 @@ LExit:
131 return hr;
132 }
133
134 +DAPI_(HRESULT) PathConcatRelativeToBase(
135 + __in LPCWSTR wzBase,
136 + __in_opt LPCWSTR wzRelative,
137 + __deref_out_z LPWSTR* psczCombined
138 + )
139 +{
140 + HRESULT hr = S_OK;
141 + LPWSTR sczCanonicalizedRelative = NULL;
142 +
143 + if (!wzBase || !*wzBase)
144 + {
145 + PathExitWithRootFailure(hr, E_INVALIDARG, "wzBase is required.");
146 + }
147 +
148 + if (PathIsRooted(wzRelative))
149 + {
150 + PathExitWithRootFailure(hr, E_INVALIDARG, "wzRelative cannot be rooted.");
151 + }
152 +
153 + hr = StrAllocString(psczCombined, wzBase, 0);
154 + PathExitOnFailure(hr, "Failed to copy base to output.");
155 +
156 + if (wzRelative && *wzRelative)
157 + {
158 + hr = PathBackslashTerminate(psczCombined);
159 + PathExitOnFailure(hr, "Failed to backslashify.");
160 +
161 + hr = PathCanonicalizeForComparison(wzRelative, 0, &sczCanonicalizedRelative);
162 + PathExitOnFailure(hr, "Failed to canonicalize wzRelative.");
163 +
164 + hr = StrAllocConcat(psczCombined, sczCanonicalizedRelative, 0);
165 + PathExitOnFailure(hr, "Failed to append relative to output.");
166 + }
167 +
168 +LExit:
169 + ReleaseStr(sczCanonicalizedRelative);
170 +
171 + return hr;
172 +}
173 +
174 DAPI_(HRESULT) PathDirectoryContainsPath(
175 __in_z LPCWSTR wzDirectory,
176 __in_z LPCWSTR wzPath
src/libs/dutil/test/DUtilUnitTest/PathUtilTest.cpp
+107
@@ -220,6 +220,113 @@ namespace DutilTests
220 }
221 }
222
223 + [Fact]
224 + void PathConcatTest()
225 + {
226 + HRESULT hr = S_OK;
227 + LPWSTR sczPath = NULL;
228 + LPCWSTR rgwzPaths[54] =
229 + {
230 + L"a", NULL, L"a",
231 + L"a", L"", L"a",
232 + L"C:\\", L"a", L"C:\\a",
233 + L"\\a", L"b", L"\\a\\b",
234 + L"a", L"b", L"a\\b",
235 + L"C:\\", L"..\\a", L"C:\\..\\a",
236 + L"C:\\a", L"..\\b", L"C:\\a\\..\\b",
237 + L"\\\\server\\share", L"..\\a", L"\\\\server\\share\\..\\a",
238 + L"\\\\server\\share\\a", L"..\\b", L"\\\\server\\share\\a\\..\\b",
239 + NULL, L"b", L"b",
240 + L"", L"b", L"b",
241 + L"a", L"\\b", L"\\b",
242 + L"a", L"b:", L"b:",
243 + L"a", L"b:\\", L"b:\\",
244 + L"a", L"\\\\?\\b", L"\\\\?\\b",
245 + L"a", L"\\\\?\\UNC\\b", L"\\\\?\\UNC\\b",
246 + L"a", L"\\b", L"\\b",
247 + L"a", L"\\\\", L"\\\\",
248 + };
249 +
250 + try
251 + {
252 + for (DWORD i = 0; i < countof(rgwzPaths); i += 3)
253 + {
254 + hr = PathConcat(rgwzPaths[i], rgwzPaths[i + 1], &sczPath);
255 + NativeAssert::Succeeded(hr, "PathConcat: {0}, {1}", rgwzPaths[i], rgwzPaths[i + 1]);
256 + NativeAssert::StringEqual(rgwzPaths[i + 2], sczPath);
257 + }
258 + }
259 + finally
260 + {
261 + ReleaseStr(sczPath);
262 + }
263 + }
264 +
265 + [Fact]
266 + void PathConcatRelativeToBaseTest()
267 + {
268 + HRESULT hr = S_OK;
269 + LPWSTR sczPath = NULL;
270 + LPCWSTR rgwzPaths[27] =
271 + {
272 + L"a", NULL, L"a",
273 + L"a", L"", L"a",
274 + L"C:\\", L"a", L"C:\\a",
275 + L"\\a", L"b", L"\\a\\b",
276 + L"a", L"b", L"a\\b",
277 + L"C:\\", L"..\\a", L"C:\\a",
278 + L"C:\\a", L"..\\b", L"C:\\a\\b",
279 + L"\\\\server\\share", L"..\\a", L"\\\\server\\share\\a",
280 + L"\\\\server\\share\\a", L"..\\b", L"\\\\server\\share\\a\\b",
281 + };
282 +
283 + try
284 + {
285 + for (DWORD i = 0; i < countof(rgwzPaths); i += 3)
286 + {
287 + hr = PathConcatRelativeToBase(rgwzPaths[i], rgwzPaths[i + 1], &sczPath);
288 + NativeAssert::Succeeded(hr, "PathConcatRelativeToBase: {0}, {1}", rgwzPaths[i], rgwzPaths[i + 1]);
289 + NativeAssert::StringEqual(rgwzPaths[i + 2], sczPath);
290 + }
291 + }
292 + finally
293 + {
294 + ReleaseStr(sczPath);
295 + }
296 + }
297 +
298 + [Fact]
299 + void PathConcatRelativeToBaseFailureTest()
300 + {
301 + HRESULT hr = S_OK;
302 + LPWSTR sczPath = NULL;
303 + LPCWSTR rgwzPaths[18] =
304 + {
305 + NULL, L"b",
306 + L"", L"b",
307 + L"a", L"\\b",
308 + L"a", L"b:",
309 + L"a", L"b:\\",
310 + L"a", L"\\\\?\\b",
311 + L"a", L"\\\\?\\UNC\\b",
312 + L"a", L"\\b",
313 + L"a", L"\\\\",
314 + };
315 +
316 + try
317 + {
318 + for (DWORD i = 0; i < countof(rgwzPaths); i += 2)
319 + {
320 + hr = PathConcatRelativeToBase(rgwzPaths[i], rgwzPaths[i + 1], &sczPath);
321 + NativeAssert::SpecificReturnCode(hr, E_INVALIDARG, "PathConcatRelativeToBase: {0}, {1}", rgwzPaths[i], rgwzPaths[i + 1]);
322 + }
323 + }
324 + finally
325 + {
326 + ReleaseStr(sczPath);
327 + }
328 + }
329 +
330 [Fact]
331 void PathDirectoryContainsPathTest()
332 {