aboutsummaryrefslogtreecommitdiff
path: root/src/engine/msiengine.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-10-17 19:12:21 -0500
committerSean Hall <r.sean.hall@gmail.com>2020-10-24 20:07:21 -0500
commit273c69f34311f4f4e5f6b5896e71d0788f12d96a (patch)
tree4cf8f42f3ecfa9341a41686b74aa5e48068ede87 /src/engine/msiengine.cpp
parent3f8e35223216ebbe7f6683a5031a5a97bbc66d5a (diff)
downloadwix-273c69f34311f4f4e5f6b5896e71d0788f12d96a.tar.gz
wix-273c69f34311f4f4e5f6b5896e71d0788f12d96a.tar.bz2
wix-273c69f34311f4f4e5f6b5896e71d0788f12d96a.zip
WIXFEAT:6210 Change data type of versions to strings.
Diffstat (limited to 'src/engine/msiengine.cpp')
-rw-r--r--src/engine/msiengine.cpp94
1 files changed, 59 insertions, 35 deletions
diff --git a/src/engine/msiengine.cpp b/src/engine/msiengine.cpp
index e7cffd62..e274df28 100644
--- a/src/engine/msiengine.cpp
+++ b/src/engine/msiengine.cpp
@@ -79,7 +79,7 @@ extern "C" HRESULT MsiEngineParsePackageFromXml(
79 hr = XmlGetAttributeEx(pixnMsiPackage, L"Version", &scz); 79 hr = XmlGetAttributeEx(pixnMsiPackage, L"Version", &scz);
80 ExitOnFailure(hr, "Failed to get @Version."); 80 ExitOnFailure(hr, "Failed to get @Version.");
81 81
82 hr = FileVersionFromStringEx(scz, 0, &pPackage->Msi.qwVersion); 82 hr = VerParseVersion(scz, 0, FALSE, &pPackage->Msi.pVersion);
83 ExitOnFailure(hr, "Failed to parse @Version: %ls", scz); 83 ExitOnFailure(hr, "Failed to parse @Version: %ls", scz);
84 84
85 // @UpgradeCode 85 // @UpgradeCode
@@ -399,6 +399,7 @@ extern "C" HRESULT MsiEngineDetectPackage(
399 Trace(REPORT_STANDARD, "Detecting MSI package 0x%p", pPackage); 399 Trace(REPORT_STANDARD, "Detecting MSI package 0x%p", pPackage);
400 400
401 HRESULT hr = S_OK; 401 HRESULT hr = S_OK;
402 int nCompareResult = 0;
402 LPWSTR sczInstalledVersion = NULL; 403 LPWSTR sczInstalledVersion = NULL;
403 LPWSTR sczInstalledLanguage = NULL; 404 LPWSTR sczInstalledLanguage = NULL;
404 LPWSTR sczInstalledProductCode = NULL; 405 LPWSTR sczInstalledProductCode = NULL;
@@ -407,7 +408,7 @@ extern "C" HRESULT MsiEngineDetectPackage(
407 BOOTSTRAPPER_RELATED_OPERATION operation = BOOTSTRAPPER_RELATED_OPERATION_NONE; 408 BOOTSTRAPPER_RELATED_OPERATION operation = BOOTSTRAPPER_RELATED_OPERATION_NONE;
408 BOOTSTRAPPER_RELATED_OPERATION relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_NONE; 409 BOOTSTRAPPER_RELATED_OPERATION relatedMsiOperation = BOOTSTRAPPER_RELATED_OPERATION_NONE;
409 WCHAR wzProductCode[MAX_GUID_CHARS + 1] = { }; 410 WCHAR wzProductCode[MAX_GUID_CHARS + 1] = { };
410 DWORD64 qwVersion = 0; 411 VERUTIL_VERSION* pVersion = NULL;
411 UINT uLcid = 0; 412 UINT uLcid = 0;
412 BOOL fPerMachine = FALSE; 413 BOOL fPerMachine = FALSE;
413 414
@@ -416,18 +417,21 @@ extern "C" HRESULT MsiEngineDetectPackage(
416 hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); 417 hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
417 if (SUCCEEDED(hr)) 418 if (SUCCEEDED(hr))
418 { 419 {
419 hr = FileVersionFromStringEx(sczInstalledVersion, 0, &pPackage->Msi.qwInstalledVersion); 420 hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pPackage->Msi.pInstalledVersion);
420 ExitOnFailure(hr, "Failed to convert version: %ls to DWORD64 for ProductCode: %ls", sczInstalledVersion, pPackage->Msi.sczProductCode); 421 ExitOnFailure(hr, "Failed to parse installed version: '%ls' for ProductCode: %ls", sczInstalledVersion, pPackage->Msi.sczProductCode);
421 422
422 // compare versions 423 // compare versions
423 if (pPackage->Msi.qwVersion < pPackage->Msi.qwInstalledVersion) 424 hr = VerCompareParsedVersions(pPackage->Msi.pVersion, pPackage->Msi.pInstalledVersion, &nCompareResult);
425 ExitOnFailure(hr, "Failed to compare version '%ls' to installed version: '%ls'", pPackage->Msi.pVersion->sczVersion, pPackage->Msi.pInstalledVersion->sczVersion);
426
427 if (nCompareResult < 0)
424 { 428 {
425 operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE; 429 operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE;
426 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED; 430 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
427 } 431 }
428 else 432 else
429 { 433 {
430 if (pPackage->Msi.qwVersion > pPackage->Msi.qwInstalledVersion) 434 if (nCompareResult > 0)
431 { 435 {
432 operation = BOOTSTRAPPER_RELATED_OPERATION_MINOR_UPDATE; 436 operation = BOOTSTRAPPER_RELATED_OPERATION_MINOR_UPDATE;
433 } 437 }
@@ -438,9 +442,9 @@ extern "C" HRESULT MsiEngineDetectPackage(
438 // Report related MSI package to BA. 442 // Report related MSI package to BA.
439 if (BOOTSTRAPPER_RELATED_OPERATION_NONE != operation) 443 if (BOOTSTRAPPER_RELATED_OPERATION_NONE != operation)
440 { 444 {
441 LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, pPackage->Msi.sczProductCode, LoggingPerMachineToString(pPackage->fPerMachine), LoggingVersionToString(pPackage->Msi.qwInstalledVersion), pPackage->Msi.dwLanguage, LoggingRelatedOperationToString(operation)); 445 LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, pPackage->Msi.sczProductCode, LoggingPerMachineToString(pPackage->fPerMachine), pPackage->Msi.pInstalledVersion->sczVersion, pPackage->Msi.dwLanguage, LoggingRelatedOperationToString(operation));
442 446
443 hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pPackage->Msi.sczUpgradeCode, pPackage->Msi.sczProductCode, pPackage->fPerMachine, pPackage->Msi.qwInstalledVersion, operation); 447 hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pPackage->Msi.sczUpgradeCode, pPackage->Msi.sczProductCode, pPackage->fPerMachine, pPackage->Msi.pInstalledVersion, operation);
444 ExitOnRootFailure(hr, "BA aborted detect related MSI package."); 448 ExitOnRootFailure(hr, "BA aborted detect related MSI package.");
445 } 449 }
446 } 450 }
@@ -453,21 +457,26 @@ extern "C" HRESULT MsiEngineDetectPackage(
453 hr = WiuGetProductInfoEx(sczInstalledProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); 457 hr = WiuGetProductInfoEx(sczInstalledProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
454 if (SUCCEEDED(hr)) 458 if (SUCCEEDED(hr))
455 { 459 {
456 hr = FileVersionFromStringEx(sczInstalledVersion, 0, &qwVersion); 460 hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pVersion);
457 ExitOnFailure(hr, "Failed to convert version: %ls to DWORD64 for ProductCode: %ls", sczInstalledVersion, sczInstalledProductCode); 461 ExitOnFailure(hr, "Failed to parse dependency version: '%ls' for ProductCode: %ls", sczInstalledVersion, sczInstalledProductCode);
462
463 // compare versions
464 hr = VerCompareParsedVersions(pPackage->Msi.pVersion, pVersion, &nCompareResult);
465 ExitOnFailure(hr, "Failed to compare version '%ls' to dependency version: '%ls'", pPackage->Msi.pVersion->sczVersion, pVersion->sczVersion);
458 466
459 if (pPackage->Msi.qwVersion < qwVersion) 467 if (nCompareResult < 0)
460 { 468 {
461 LogId(REPORT_STANDARD, MSG_DETECTED_COMPATIBLE_PACKAGE_FROM_PROVIDER, pPackage->sczId, sczInstalledProviderKey, sczInstalledProductCode, sczInstalledVersion, pPackage->Msi.sczProductCode); 469 LogId(REPORT_STANDARD, MSG_DETECTED_COMPATIBLE_PACKAGE_FROM_PROVIDER, pPackage->sczId, sczInstalledProviderKey, sczInstalledProductCode, sczInstalledVersion, pPackage->Msi.sczProductCode);
462 470
463 hr = UserExperienceOnDetectCompatibleMsiPackage(pUserExperience, pPackage->sczId, sczInstalledProductCode, qwVersion); 471 hr = UserExperienceOnDetectCompatibleMsiPackage(pUserExperience, pPackage->sczId, sczInstalledProductCode, pVersion);
464 ExitOnRootFailure(hr, "BA aborted detect compatible MSI package."); 472 ExitOnRootFailure(hr, "BA aborted detect compatible MSI package.");
465 473
466 hr = StrAllocString(&pPackage->Msi.sczInstalledProductCode, sczInstalledProductCode, 0); 474 hr = StrAllocString(&pPackage->Msi.sczInstalledProductCode, sczInstalledProductCode, 0);
467 ExitOnFailure(hr, "Failed to copy the installed ProductCode to the package."); 475 ExitOnFailure(hr, "Failed to copy the installed ProductCode to the package.");
468 476
469 pPackage->Msi.qwInstalledVersion = qwVersion; 477 pPackage->Msi.pInstalledVersion = pVersion;
470 pPackage->Msi.fCompatibleInstalled = TRUE; 478 pPackage->Msi.fCompatibleInstalled = TRUE;
479 pVersion = NULL;
471 } 480 }
472 } 481 }
473 } 482 }
@@ -524,18 +533,30 @@ extern "C" HRESULT MsiEngineDetectPackage(
524 } 533 }
525 } 534 }
526 535
527 hr = FileVersionFromStringEx(sczInstalledVersion, 0, &qwVersion); 536 hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pVersion);
528 ExitOnFailure(hr, "Failed to convert version: %ls to DWORD64 for ProductCode: %ls", sczInstalledVersion, wzProductCode); 537 ExitOnFailure(hr, "Failed to parse related installed version: '%ls' for ProductCode: %ls", sczInstalledVersion, wzProductCode);
529 538
530 // compare versions 539 // compare versions
531 if (pRelatedMsi->fMinProvided && (pRelatedMsi->fMinInclusive ? (qwVersion < pRelatedMsi->qwMinVersion) : (qwVersion <= pRelatedMsi->qwMinVersion))) 540 if (pRelatedMsi->fMinProvided)
532 { 541 {
533 continue; 542 hr = VerCompareParsedVersions(pVersion, pRelatedMsi->pMinVersion, &nCompareResult);
543 ExitOnFailure(hr, "Failed to compare related installed version '%ls' to related min version: '%ls'", pVersion->sczVersion, pRelatedMsi->pMinVersion->sczVersion);
544
545 if (pRelatedMsi->fMinInclusive ? (nCompareResult < 0) : (nCompareResult <= 0))
546 {
547 continue;
548 }
534 } 549 }
535 550
536 if (pRelatedMsi->fMaxProvided && (pRelatedMsi->fMaxInclusive ? (qwVersion > pRelatedMsi->qwMaxVersion) : (qwVersion >= pRelatedMsi->qwMaxVersion))) 551 if (pRelatedMsi->fMaxProvided)
537 { 552 {
538 continue; 553 hr = VerCompareParsedVersions(pVersion, pRelatedMsi->pMaxVersion, &nCompareResult);
554 ExitOnFailure(hr, "Failed to compare related installed version '%ls' to related max version: '%ls'", pVersion->sczVersion, pRelatedMsi->pMaxVersion->sczVersion);
555
556 if (pRelatedMsi->fMaxInclusive ? (nCompareResult > 0) : (nCompareResult >= 0))
557 {
558 continue;
559 }
539 } 560 }
540 561
541 // Filter by language if necessary. 562 // Filter by language if necessary.
@@ -605,10 +626,10 @@ extern "C" HRESULT MsiEngineDetectPackage(
605 operation = BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE; 626 operation = BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE;
606 } 627 }
607 628
608 LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, wzProductCode, LoggingPerMachineToString(fPerMachine), LoggingVersionToString(qwVersion), uLcid, LoggingRelatedOperationToString(relatedMsiOperation)); 629 LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, wzProductCode, LoggingPerMachineToString(fPerMachine), pVersion->sczVersion, uLcid, LoggingRelatedOperationToString(relatedMsiOperation));
609 630
610 // Pass to BA. 631 // Pass to BA.
611 hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pRelatedMsi->sczUpgradeCode, wzProductCode, fPerMachine, qwVersion, relatedMsiOperation); 632 hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pRelatedMsi->sczUpgradeCode, wzProductCode, fPerMachine, pVersion, relatedMsiOperation);
612 ExitOnRootFailure(hr, "BA aborted detect related MSI package."); 633 ExitOnRootFailure(hr, "BA aborted detect related MSI package.");
613 } 634 }
614 } 635 }
@@ -667,6 +688,7 @@ LExit:
667 ReleaseStr(sczInstalledProductCode); 688 ReleaseStr(sczInstalledProductCode);
668 ReleaseStr(sczInstalledLanguage); 689 ReleaseStr(sczInstalledLanguage);
669 ReleaseStr(sczInstalledVersion); 690 ReleaseStr(sczInstalledVersion);
691 ReleaseVerutilVersion(pVersion);
670 692
671 return hr; 693 return hr;
672} 694}
@@ -684,8 +706,9 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
684 Trace(REPORT_STANDARD, "Planning MSI package 0x%p", pPackage); 706 Trace(REPORT_STANDARD, "Planning MSI package 0x%p", pPackage);
685 707
686 HRESULT hr = S_OK; 708 HRESULT hr = S_OK;
687 DWORD64 qwVersion = pPackage->Msi.qwVersion; 709 VERUTIL_VERSION* pVersion = pPackage->Msi.pVersion;
688 DWORD64 qwInstalledVersion = pPackage->Msi.qwInstalledVersion; 710 VERUTIL_VERSION* pInstalledVersion = pPackage->Msi.pInstalledVersion;
711 int nCompareResult = 0;
689 BOOTSTRAPPER_ACTION_STATE execute = BOOTSTRAPPER_ACTION_STATE_NONE; 712 BOOTSTRAPPER_ACTION_STATE execute = BOOTSTRAPPER_ACTION_STATE_NONE;
690 BOOTSTRAPPER_ACTION_STATE rollback = BOOTSTRAPPER_ACTION_STATE_NONE; 713 BOOTSTRAPPER_ACTION_STATE rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
691 BOOL fFeatureActionDelta = FALSE; 714 BOOL fFeatureActionDelta = FALSE;
@@ -739,10 +762,13 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
739 case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED: 762 case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED:
740 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested) 763 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested)
741 { 764 {
765 hr = VerCompareParsedVersions(pVersion, pInstalledVersion, &nCompareResult);
766 ExitOnFailure(hr, "Failed to compare '%ls' to '%ls' for planning.", pVersion->sczVersion, pInstalledVersion->sczVersion);
767
742 // Take a look at the version and determine if this is a potential 768 // Take a look at the version and determine if this is a potential
743 // minor upgrade (same ProductCode newer ProductVersion), otherwise, 769 // minor upgrade (same ProductCode newer ProductVersion), otherwise,
744 // there is a newer version so no work necessary. 770 // there is a newer version so no work necessary.
745 if (qwVersion > qwInstalledVersion) 771 if (nCompareResult > 0)
746 { 772 {
747 execute = BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE; 773 execute = BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE;
748 } 774 }
@@ -1014,20 +1040,18 @@ extern "C" HRESULT MsiEngineAddCompatiblePackage(
1014 } 1040 }
1015 1041
1016 // Read in the compatible ProductVersion if not already available. 1042 // Read in the compatible ProductVersion if not already available.
1017 if (pPackage->Msi.qwInstalledVersion) 1043 if (pPackage->Msi.pInstalledVersion)
1018 { 1044 {
1019 pCompatiblePackage->Msi.qwVersion = pPackage->Msi.qwInstalledVersion; 1045 hr = VerCopyVersion(pPackage->Msi.pInstalledVersion, &pCompatiblePackage->Msi.pVersion);
1020 1046 ExitOnFailure(hr, "Failed to copy version for compatible package.");
1021 hr = FileVersionToStringEx(pCompatiblePackage->Msi.qwVersion, &sczInstalledVersion);
1022 ExitOnFailure(hr, "Failed to format version number string.");
1023 } 1047 }
1024 else 1048 else
1025 { 1049 {
1026 hr = WiuGetProductInfoEx(pCompatiblePackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); 1050 hr = WiuGetProductInfoEx(pCompatiblePackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion);
1027 ExitOnFailure(hr, "Failed to read version from compatible package."); 1051 ExitOnFailure(hr, "Failed to read version from compatible package.");
1028 1052
1029 hr = FileVersionFromStringEx(sczInstalledVersion, 0, &pCompatiblePackage->Msi.qwVersion); 1053 hr = VerParseVersion(sczInstalledVersion, 0, FALSE, &pCompatiblePackage->Msi.pVersion);
1030 ExitOnFailure(hr, "Failed to convert version: %ls to DWORD64 for ProductCode: %ls", sczInstalledVersion, pCompatiblePackage->Msi.sczProductCode); 1054 ExitOnFailure(hr, "Failed to parse version: '%ls' for ProductCode: %ls", sczInstalledVersion, pCompatiblePackage->Msi.sczProductCode);
1031 } 1055 }
1032 1056
1033 // For now, copy enough information to support uninstalling the newer, compatible package. 1057 // For now, copy enough information to support uninstalling the newer, compatible package.
@@ -1046,7 +1070,7 @@ extern "C" HRESULT MsiEngineAddCompatiblePackage(
1046 ExitOnFailure(hr, "Failed to format log path variable for compatible package."); 1070 ExitOnFailure(hr, "Failed to format log path variable for compatible package.");
1047 1071
1048 // Use the default cache ID generation from the binder. 1072 // Use the default cache ID generation from the binder.
1049 hr = StrAllocFormatted(&pCompatiblePackage->sczCacheId, L"%lsv%ls", pCompatiblePackage->sczId, sczInstalledVersion); 1073 hr = StrAllocFormatted(&pCompatiblePackage->sczCacheId, L"%lsv%ls", pCompatiblePackage->sczId, pCompatiblePackage->Msi.pVersion->sczVersion);
1050 ExitOnFailure(hr, "Failed to format cache ID for compatible package."); 1074 ExitOnFailure(hr, "Failed to format cache ID for compatible package.");
1051 1075
1052 pCompatiblePackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT; 1076 pCompatiblePackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT;
@@ -1068,7 +1092,7 @@ extern "C" HRESULT MsiEngineAddCompatiblePackage(
1068 ExitOnFailure(hr, "Failed to copy the compatible provider key."); 1092 ExitOnFailure(hr, "Failed to copy the compatible provider key.");
1069 1093
1070 // Assume the package version is the same as the provider version. 1094 // Assume the package version is the same as the provider version.
1071 hr = StrAllocString(&pCompatibleProvider->sczVersion, sczInstalledVersion, 0); 1095 hr = StrAllocString(&pCompatibleProvider->sczVersion, pCompatiblePackage->Msi.pVersion->sczVersion, 0);
1072 ExitOnFailure(hr, "Failed to copy the compatible provider version."); 1096 ExitOnFailure(hr, "Failed to copy the compatible provider version.");
1073 1097
1074 // Assume provider keys are similarly authored for this package. 1098 // Assume provider keys are similarly authored for this package.
@@ -1479,7 +1503,7 @@ static HRESULT ParseRelatedMsiFromXml(
1479 { 1503 {
1480 ExitOnFailure(hr, "Failed to get @MinVersion."); 1504 ExitOnFailure(hr, "Failed to get @MinVersion.");
1481 1505
1482 hr = FileVersionFromStringEx(scz, 0, &pRelatedMsi->qwMinVersion); 1506 hr = VerParseVersion(scz, 0, FALSE, &pRelatedMsi->pMinVersion);
1483 ExitOnFailure(hr, "Failed to parse @MinVersion: %ls", scz); 1507 ExitOnFailure(hr, "Failed to parse @MinVersion: %ls", scz);
1484 1508
1485 // flag that we have a min version 1509 // flag that we have a min version
@@ -1496,7 +1520,7 @@ static HRESULT ParseRelatedMsiFromXml(
1496 { 1520 {
1497 ExitOnFailure(hr, "Failed to get @MaxVersion."); 1521 ExitOnFailure(hr, "Failed to get @MaxVersion.");
1498 1522
1499 hr = FileVersionFromStringEx(scz, 0, &pRelatedMsi->qwMaxVersion); 1523 hr = VerParseVersion(scz, 0, FALSE, &pRelatedMsi->pMaxVersion);
1500 ExitOnFailure(hr, "Failed to parse @MaxVersion: %ls", scz); 1524 ExitOnFailure(hr, "Failed to parse @MaxVersion: %ls", scz);
1501 1525
1502 // flag that we have a max version 1526 // flag that we have a max version