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
{