Cumulative Service Packs with MinorUpdateTargetRTM

Microsoft has had a long-standing
policy of providing
cumulative service packs – service packs that can be installed for a product whether a
previous service pack for that product has been installed or not. Prior to the release of

Windows Installer 3.1
,

minor upgrades
which typically serve as service packs had to contain a pair
of transforms for every servicing level including the original product (RTM) and all
previous service packs (SPs) – perhaps even beta service packs. This not only
increases time to create a patch since you’ll have ever-increasing numbers of
pairs of target and upgrade .msi files, but also increases the
patch size
because of all data contained in the patch transforms.

It’s not enough to have a single transform pair target the product RTM because of
how
patch sequencing works
. Whether using obsolescence or supersedence, minor
upgrades are still considered in the applicable view of the product, namely when
comparing the target

ProductCode
and

ProductVersion
properties with the actual ProductCode and ProductVersion
properties currently installed on the machine – even when

installing multiple patches
at once, which is supported starting in

Windows Installer 3.0
. Consider the following abridged log from a
multi-patch installation scenario with SP1 and SP2, both targeting the RTM.

MSI (c) (A4:84) [10:03:36:693]: SequencePatches starts. Product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, Product version: 1.0.0, Upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}, Product language 1033

MSI (c) (A4:84) [10:03:36:693]: 3.0 patch sp1.msp of type minor upgrade takes product {1E37580C-4EC8-4CF1-A887-651D8AD74177} to version 1.1.0

MSI (c) (A4:84) [10:03:36:693]: 3.0 patch sp2.msp of type minor upgrade takes product {1E37580C-4EC8-4CF1-A887-651D8AD74177} to version 1.2.0

MSI (c) (A4:84) [10:03:36:693]: PATCH SEQUENCER: verifying the applicability of minor upgrade patch sp1.msp against product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, product version: 1.0.0, product language 1033 and upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}

MSI (c) (A4:84) [10:03:36:693]: Validating transform ‘T1ToU1’ with validation bits 0x922

MSI (c) (A4:84) [10:03:36:693]: Transform ‘T1ToU1’ is valid.

MSI (c) (A4:84) [10:03:36:713]: PATCH SEQUENCER: minor upgrade patch sp1.msp is applicable.

MSI (c) (A4:84) [10:03:36:713]: PATCH SEQUENCER: verifying the applicability of minor upgrade patch sp2.msp against product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, product version: 1.1.0, product language 1033 and upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}

MSI (c) (A4:84) [10:03:36:713]: Validating transform ‘T1ToU1’ with validation bits 0x922

MSI (c) (A4:84) [10:03:36:713]: Note: 1: 2749 2: T1ToU1 3: C:DOCUME~1USERLOCALS~1Temp17bad5.msp 4: 1.0.0 5: 1.1.0

MSI (c) (A4:84) [10:03:36:713]: 1: 2749 2: T1ToU1 3: C:DOCUME~1USERLOCALS~1Temp17bad5.msp 4: 1.0.0 5: 1.1.0

MSI (c) (A4:84) [10:03:36:713]: PATCH SEQUENCER: minor upgrade patch sp2.msp is not applicable.

MSI (c) (A4:84) [10:03:36:713]: SequencePatches returns success.

MSI (c) (A4:84) [10:03:36:713]: Final Patch Application Order:

MSI (c) (A4:84) [10:03:36:713]: {D34AA461-D159-48E5-908B-62F565F303E4} – sp1.msp

MSI (c) (A4:84) [10:03:36:713]: Other Patches:

MSI (c) (A4:84) [10:03:36:713]: UnknownAbsent: {4B45E0A7-7D85-410B-9D3F-E5DF343BFF95} – sp2.msp

Rather than fail the entire installation when installing multiple patches,
only applicable patches are applied. If you installed SP1 then SP2 in succession,
Windows Installer would return ERROR_PATCH_TARGET_NOT_FOUND (1642)
when attempting to install SP2. The reason is that SP1 is still applicable when
calculating supersedence. To remedy this situation, SP2 would require transforms
from the SP1 servicing level to SP2. This can be done by either building the RTM
up to look like the SP1, or creating what we call a “service release”, or SR,
which is essentially an administrative installation with a minor upgrade
applied.

The advent of Windows Installer 3.1 introduced an easier way, however, that
actually supersedes all previous patches before the final supersedence is even
calculated: the MinorUpdateTargetRTM property in the patch package’s

MsiPatchMetadata table
.

With this property present in the MsiPatchMetadata table of SP2 in our
example, only a single pair of transforms are necessary to target the product RTM. This
means that generating a number of transforms for every possible target is not
necessary, and when you consider that we elease beta SPs this number can
grow quite rapidly. Take a look at the difference in the abridged log
below where the only change was adding the MinorUpdateTargetRTM property into the MsiPatchMetadata
table for SP2.

MSI (s) (F0:48) [11:12:57:664]: SequencePatches starts. Product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, Product version: 1.0.0, Upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}, Product language 1033

MSI (s) (F0:48) [11:12:57:664]: 3.0 patch sp1.msp of type minor upgrade takes product {1E37580C-4EC8-4CF1-A887-651D8AD74177} to version 1.1.0

MSI (s) (F0:48) [11:12:57:664]: 3.0 patch sp2.msp of type minor upgrade takes product {1E37580C-4EC8-4CF1-A887-651D8AD74177} to version 1.2.0

MSI (s) (F0:48) [11:12:57:664]: PATCH SEQUENCER: verifying the applicability of minor upgrade patch sp1.msp against product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, product version: 1.0.0, product language 1033 and upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}

MSI (s) (F0:48) [11:12:57:664]: Validating transform ‘T1ToU1’ with validation bits 0x922

MSI (s) (F0:48) [11:12:57:664]: Transform ‘T1ToU1’ is valid.

MSI (s) (F0:48) [11:12:57:674]: PATCH SEQUENCER: minor upgrade patch sp1.msp is applicable.

MSI (s) (F0:48) [11:12:57:674]: PATCH SEQUENCER: verifying the applicability of minor upgrade patch sp2.msp against product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, product version: 1.0.0, product language 1033 and upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}

MSI (s) (F0:48) [11:12:57:684]: Validating transform ‘T1ToU1’ with validation bits 0x922

MSI (s) (F0:48) [11:12:57:684]: Transform ‘T1ToU1’ is valid.

MSI (s) (F0:48) [11:12:57:684]: PATCH SEQUENCER: minor upgrade patch sp2.msp is applicable.

MSI (s) (F0:48) [11:12:57:684]: SequencePatches returns success.

MSI (s) (F0:48) [11:12:57:684]: Final Patch Application Order:

MSI (s) (F0:48) [11:12:57:684]: {4B45E0A7-7D85-410B-9D3F-E5DF343BFF95} – sp2.msp

MSI (s) (F0:48) [11:12:57:684]: Other Patches:

MSI (s) (F0:48) [11:12:57:684]: Superseded:
{D34AA461-D159-48E5-908B-62F565F303E4} – sp1.msp

You can have this property added to your patch by authoring it into the
PatchMetadata table of your .pcp file to be processed by
PatchWiz.dll
. Unfortunately,
PatchWiz.dll version 3.1 doesn’t consider the MinorUpdateTargetRTM
property to be a standard property; that is, a property in the resulting
MsiPatchMetadata table that does not require a value for the Company field. This
is fixed for PatchWiz.dll version 4.0 that ships with the

Windows Vista Platform SDK
for beta 2 or newer, which can be used to create
patches targeting older versions of Windows Installer.

If you cannot use PatchWiz.dll version 4.0 or newer for whatever
reason, you can open the .msp package and add the property yourself
rather easily, as developed in the

sample script
using the

Windows Installer automation interface
. Please note this script is only an
example of how to programmatically add the MinorUpdateTargetRTM property and is
not officially supported.