다음을 통해 공유


Servicing Windows: Part Two

I wanted to talk a little more about the way things work inside of the component store and how things are actually built inside of the servicing mechanisms in Windows.  So, today we'll look at how the various packages and manifests are manipulated for a specific feature, in this case Chess Titans, and how that package is installed on a machine. NOTE: I truncated most of these files to make this a little more readable. Sorry about the formatting of the page, something isn’t translating as well as I would like.

When we look at the installation of the Chess Titans feature, we start by checking out the packages that make up the feature itself.  These packages are located in the C:\Windows\servicing\packages directory and typically have a strong naming convention that allows for users to find the package that matches the feature.  In this case, looking in the servicing directory would not show a package with the name of Chess Titans.  However, by looking at the figure above we can see that Chess Titans falls under a category known as Games.  If we look for the keyword Games inside the servicing folder, we would see the following packages:

Microsoft-Windows-Shell-MultiplayerInboxGames-Package~31bf3856ad364e35~amd64~~6.1.7600.16385

Microsoft-Windows-Shell-MultiplayerInboxGames-Package~31bf3856ad364e35~amd64~en-US~6.1.7600.16385

Microsoft-Windows-Shell-PremiumInboxGames-Package~31bf3856ad364e35~amd64~~6.1.7600.16385 

Microsoft-Windows-Shell-PremiumInboxGames-Package~31bf3856ad364e35~amd64~en-US~6.1.7600.16385

Microsoft-Windows-Shell-InboxGames-Package~31bf3856ad364e35~amd64~~6.1.7600.16385

Microsoft-Windows-Shell-InboxGames-Package~31bf3856ad364e35~amd64~en-US~6.1.7600.16385

From here we need to figure out which packages are responsible for the Chess Titans feature.  We can eliminate all of the ~en-US packages right away as these are the localized versions of the package.  Additionally, if I want to quickly find just the manifests that contain the word chess, I can use the findstr tool with the following command when inside the servicing directory:

findstr /s /i /m "chess" *.*

This will yield the following three package manifests:

Microsoft-Windows-EnterpriseEdition~31bf3856ad364e35~amd64~~6.1.7600.16385.mum

Microsoft-Windows-Shell-PremiumInboxGames-Package~31bf3856ad364e35~amd64~en-US~6.1.7600.16385.mum

Microsoft-Windows-Shell-PremiumInboxGames-Package~31bf3856ad364e35~amd64~~6.1.7600.16385.mum

First we notice that the Enterprise-Edition package is listed, this is interesting information because it tells me that this component shipped as a portion of this specific Windows Edition.  If this Windows edition did not include the PremiumInboxGames package, we would not even see it listed here.  However, I can eliminate the EnterpriseEdition package because we know that this is the edition of Windows that is running on the machine.  We can also eliminate the ~en-US package as any package with a language and localized environment identifier in the name applies only to it’s the localized version of the package.  Localized packages are those that contain resources specific to a language.  These are used during language pack installation to provide the localization of the user interface.  Once we eliminate the language resources, it leaves us with the Microsoft-Windows-Shell-PremiumInboxGames-Package~31bf3856ad364e35~amd64~~6.1.7600.16385.mum package as our starting point.  If we open this manifest, we see the following information:

<?xml version='1.0' encoding='utf-8' standalone='yes'?>

<?Copyright (c) Microsoft Corporation. All rights reserved.?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v3" copyright="Copyright (c) Microsoft Corporation. All Rights Reserved." manifestVersion="1.0">

  <assemblyIdentity buildType="release" language="neutral" name="Microsoft-Windows-Shell-PremiumInboxGames-Package" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" version="6.1.7600.16385"/>

  <package identifier="PremiumInboxGames-Package" releaseType="Feature Pack">

    <parent integrate="delegate">

      <assemblyIdentity buildType="release" language="neutral" name="Microsoft-Windows-Shell-InboxGames-Package" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" version="6.1.7600.16385"/>

    </parent>

    <update description="Chess Titans" displayName="Chess Titans" name="Chess">

      <applicable disposition="staged">

        <detectUpdate>

          <parent name="InboxGames"/>

        </detectUpdate>

      </applicable>

      <selectable disposition="staged">

        <detectNone default="true"/>

      </selectable>

      <component>

        <assemblyIdentity buildType="release" language="neutral" name="Microsoft-Windows-Shell-PremiumInboxGames-Chess-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" version="6.1.7600.16385" versionScope="nonSxS"/>

      </component>

  </package>

</assembly>

From within this package we can see that there is a parent package that must be present for this package to be installed.  It is the Microsoft-Windows-Shell-InboxGames-Package as referenced by the <parent integrate> element in the manifest.  Additionally we can see that this update has been staged on the system and that it is selectable.  Staging refers to the binaries for the feature being present on the machine but not being installed on the machine, this means that the files are physically present on the system but are not in an active, useable state.  Selectable refers to the ability for the feature to show up in the Control Panel as a checkable item for installation (refer to the figure above).  Lastly, we can see the deployment that makes up this feature.  This is referenced in the <assemblyIdentity> element in the manifest and it points to Microsoft-Windows-Shell-PremiumInboxGames-Chess-Deployment.

So where do we go from here?  The first thing we should do is look at the parent package for this package to see if there is anything interesting there that we would need to know.  If we look at the Microsoft-Windows-Shell-InboxGames-Package manifest we will see the following information:

<?xml version='1.0' encoding='utf-8' standalone='yes'?>

<?Copyright (c) Microsoft Corporation. All rights reserved.?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v3" copyright="Copyright (c) Microsoft Corporation. All Rights Reserved." manifestVersion="1.0">

  <assemblyIdentity buildType="release" language="neutral" name="Microsoft-Windows-Shell-InboxGames-Package" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" version="6.1.7600.16385"/>

  <package identifier="InboxGames-Package" releaseType="Feature Pack">

    <parent integrate="delegate">

      <assemblyIdentity buildType="release" language="neutral" name="Microsoft-Windows-Foundation-Package" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" version="6.1.7600.16385"/>

    </parent>

    <update description="Standard inbox games." displayName="Games" name="InboxGames">

      <selectable disposition="staged">

        <detectNone default="true"/>

      </selectable>

    </update>

From this, we can see that this package contains references to the other games that can be installed on Windows.  Additionally, we can see that this package is parented to the Microsoft-Windows-Foundation-Package.  The WindowsFoundation package is a special package that defines features that are common to all Windows client and server installations.  There are three foundation packages, Windows, server and winpe.  The Windows foundation is for all client and server installations, the Server foundation is for Windows Server Core installations and the winpe foundation is for Windows PE installations. When we see a package that is parented to the foundation packages, we know that we’ve reached the end of the package chain because we cannot supersede the foundation during installation.  This provides a top-level endpoint for examining how this feature will be installed; from here, we can start to look into the components and deployments that would be involved in the installation of the Chess Titans feature.  For this we now need to look into the deployment manifest for Chess Titans. 

From the feature manifest we initially looked at, we know the deployment manifest is named Microsoft-Windows-Shell-PremiumInboxGames-Chess-Deployment.  To find this file we need to move out of the \Windows\servicing\packages folder and into the component store.  The component store is the repository of components that contain all previous versions of files, including the current version, which are then projected to the file system. The component store is comprised in the \Windows\winsxs directory.  If we look in the component store for the Microsoft-Windows-Shell-PremiumInboxGames-Chess-Deployment manifest we will not find it initially.  This is because the naming convention within the component store is truncated.  The actual name of the component manifest is amd64_microsoft-windows-s..es-chess-deployment_31bf3856ad364e35_6.1.7600.16385_none_441bb7844e864bcf.manifest.  If we open this deployment manifest we see the following:

<?xml version="1.0" encoding="UTF-8"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0" copyright="Copyright (c) Microsoft Corporation. All Rights Reserved.">

  <assemblyIdentity name="Microsoft-Windows-Shell-PremiumInboxGames-Chess-Deployment" version="6.1.7600.16385" processorArchitecture="amd64" language="neutral" buildType="release" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" />

  <dependency discoverable="no">

    <dependentAssembly dependencyType="install">

      <assemblyIdentity name="Microsoft-Windows-Shell-PremiumInboxGames-Chess" version="6.1.7600.16385" processorArchitecture="amd64" language="neutral" buildType="release" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" />

    </dependentAssembly>

  </dependency>

  <localization>

    <resources culture="en-US">

      <stringTable>

        <string id="displayName0" value="Chess Titans" />

      </stringTable>

    </resources>

  </localization>

  <deployment xmlns="urn:schemas-microsoft-com:asm.v3" />

</assembly>

This provides us more information on the parenting of this deployment, which is what we need to find the actual payload for this feature install.  From the deployment manifest we can see that it is parented to the Microsoft-Windows-Shell-PremiumInboxGames-Chess component manifest based on the <assemblyIdentity> element.  We can also see that this deployment has a localization value for English.  Once again, due to naming truncation, this manifest is actually named amd64_microsoft-windows-s..iuminboxgames-chess_31bf3856ad364e35_6.1.7600.16385_none_d0c99374981840d5.manifest.  If we then open this manifest, we see the following:

<?xml version="1.0" encoding="UTF-8"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0" copyright="Copyright (c) Microsoft Corporation. All Rights Reserved.">

  <assemblyIdentity name="Microsoft-Windows-Shell-PremiumInboxGames-Chess" version="6.1.7600.16385" processorArchitecture="amd64" language="neutral" buildType="release" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" />

  <dependency discoverable="no" resourceType="Resources">

    <dependentAssembly dependencyType="prerequisite">

      <assemblyIdentity name="Microsoft-Windows-Shell-PremiumInboxGames-Chess.Resources" version="6.1.7600.16385" processorArchitecture="amd64" language="*" buildType="release" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" />

    </dependentAssembly>

  </dependency>

  <file name="Chess.exe" destinationPath="$(runtime.programFiles)\Microsoft Games\Chess\" sourceName="Chess.exe" sourcePath=".\" importPath="$(build.nttree)\">

    <securityDescriptor name="#DefaultAdminSd" />

    <asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2">

      <dsig:Transforms xmlns:dsig="https://www.w3.org/2000/09/xmldsig#">

        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />

      </dsig:Transforms>

      <dsig:DigestMethod xmlns:dsig="https://www.w3.org/2000/09/xmldsig#" Algorithm="https://www.w3.org/2000/09/xmldsig#sha256" />

      <dsig:DigestValue xmlns:dsig="https://www.w3.org/2000/09/xmldsig#">mzkUfhungeqORjwicA9s41SsXndeNmV/2Hv0EHSDVgI=</dsig:DigestValue>

    </asmv2:hash>

  </file>

  <file name="Chess.dll" destinationPath="$(runtime.programFiles)\Microsoft Games\Chess\" sourceName="Chess.dll" sourcePath=".\" importPath="$(build.nttree)\">

    <securityDescriptor name="#DefaultAdminSd" />

    <asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2">

      <dsig:Transforms xmlns:dsig="https://www.w3.org/2000/09/xmldsig#">

        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />

      </dsig:Transforms>

      <dsig:DigestMethod xmlns:dsig="https://www.w3.org/2000/09/xmldsig#" Algorithm="https://www.w3.org/2000/09/xmldsig#sha256" />

      <dsig:DigestValue xmlns:dsig="https://www.w3.org/2000/09/xmldsig#">ZMJYRaWVzsvCedFwR16Sh7iq+h1dhq8/wCMLY009m5U=</dsig:DigestValue>

    </asmv2:hash>

  </file>

  <file name="ChessMCE.png" destinationPath="$(runtime.programFiles)\Microsoft Games\Chess\" sourceName="ChessMCE.png" sourcePath=".\" importPath="$(build.nttree)\">

    <securityDescriptor name="WRP_FILE_DEFAULT_SDDL" />

    <asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2">

      <dsig:Transforms xmlns:dsig="https://www.w3.org/2000/09/xmldsig#">

        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />

      </dsig:Transforms>

      <dsig:DigestMethod xmlns:dsig="https://www.w3.org/2000/09/xmldsig#" Algorithm="https://www.w3.org/2000/09/xmldsig#sha256" />

      <dsig:DigestValue xmlns:dsig="https://www.w3.org/2000/09/xmldsig#">OedcuWlD3wuKZr1I7Qa9h8qlhTNEmqDImxe4nf3b0xY=</dsig:DigestValue>

    </asmv2:hash>

   <directories>

    <directory destinationPath="$(runtime.programFiles)\Microsoft Games\Chess\" owner="true">

      <securityDescriptor name="WRP_PARENT_DIR_DEFAULT_SDDL" />

    </directory>

  </directories>

  <memberships>

    <categoryMembership>

      <id name="Microsoft.Windows.Categories.Explorer" version="6.1.7600.16385" publicKeyToken="31bf3856ad364e35" typeName="Shortcut" />

      <categoryInstance subcategory="ChessMCE.lnk\$(runtime.programFiles)\Microsoft Games\Chess">

        <shortCut arguments="-mce" destinationPath="$(runtime.programFiles)\Microsoft Games\Chess" destinationName="ChessMCE.lnk" targetPath="$(runtime.programFiles)\Microsoft Games\chess\chess.exe" iconPath="$(runtime.programFiles)\Microsoft Games\chess\chess.exe,0" windowStyle="normal" description="@$(runtime.programFiles)\Microsoft Games\chess\chess.exe,-310" displayResource="$(runtime.programFiles)\Microsoft Games\chess\chess.exe,310" />

      </categoryInstance>

    </categoryMembership>

    <categoryMembership>

      <id name="Microsoft.Windows.Categories.Explorer" version="6.1.7600.16385" publicKeyToken="31bf3856ad364e35" typeName="Shortcut" />

      <categoryInstance subcategory="Chess.lnk\$(runtime.StartMenu)\Programs\Games">

        <shortCut arguments="" destinationPath="$(runtime.StartMenu)\Programs\Games" destinationName="Chess.lnk" targetPath="shell:::{ED228FDF-9EA8-4870-83b1-96b02CFE0D52}\{205286E5-F5F2-4306-BDB1-864245E33227}" iconPath="$(runtime.programFiles)\Microsoft Games\chess\chess.exe,0" windowStyle="normal" description="@%SystemRoot%\system32\gameux.dll,-10303" displayResource="%SystemRoot%\system32\gameux.dll,10054" />

      </categoryInstance>

    </categoryMembership>

  </memberships>

  <registryKeys>

    <registryKey keyName="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Extensibility\Applications\{3C1BB651-D564-46a7-99BA-8D40BCB6FA7D}\" owner="false">

      <registryValue name="Title" valueType="REG_EXPAND_SZ" value="@$(runtime.programFiles)\Microsoft Games\Chess\Chess.exe,-170" operationHint="replace" owner="true" />

    </registryKey>

    <registryKey keyName="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Extensibility\Categories\Services\Games\{115EADF1-41C4-471b-8FE5-7A52B91BFE75}\" owner="false">

      <registryValue name="AppId" valueType="REG_SZ" value="{3C1BB651-D564-46a7-99BA-8D40BCB6FA7D}" operationHint="replace" owner="true" />

   </registryKey>

    <registryKey keyName="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Extensibility\Entry Points\{115EADF1-41C4-471b-8FE5-7A52B91BFE75}\" owner="false">

      <registryValue name="AppId" valueType="REG_SZ" value="{3C1BB651-D564-46a7-99BA-8D40BCB6FA7D}" operationHint="replace" owner="true" />

      <registryValue name="Title" valueType="REG_EXPAND_SZ" value="@$(runtime.programFiles)\Microsoft Games\Chess\Chess.exe,-170" operationHint="replace" owner="true" />

      <registryValue name="Description" valueType="REG_EXPAND_SZ" value="@$(runtime.programFiles)\Microsoft Games\Chess\Chess.exe,-308" operationHint="replace" owner="true" />

      <registryValue name="Run" valueType="REG_EXPAND_SZ" value="$(runtime.programFiles)\Microsoft Games\Chess\ChessMCE.lnk" operationHint="replace" owner="true" />

      <registryValue name="ImageUrl" valueType="REG_EXPAND_SZ" value="$(runtime.programFiles)\Microsoft Games\Chess\ChessMCE.png" operationHint="replace" owner="true" />

    </registryKey>

    Here we can see a lot more information about what is contained in the Chess Titans feature.  First, we see that this package has one more parental dependency for the Microsoft-Windows-Shell-PremiumInboxGames-Chess.Resources component manifest.  However, we also see a lot more about the payload of this particular package.  We can see that this package contains several files, registry entries and permission attributes.  Further we can tell the path to which the files are going to be installed, the registry values and type which are going to be set and the ACLs that are going to be applied for the installation of this component manifest.

If we look at the last manifest in this chain, the Microsoft-Windows-Shell-PremiumInboxGames-Chess.Resources manifest (which is referenced in the amd64_microsoft-windows-s..mes-chess.resources_31bf3856ad364e35_6.1.7600.16385_en-us_8ce17f80cc8e9b4a.manifest file) we can see from the manifest name that this is the English language localized copy of the manifest. 

Hope that makes a little sense.

--Joseph