{"id":2213,"date":"2006-05-19T16:47:00","date_gmt":"2006-05-19T16:47:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/heaths\/2006\/05\/19\/file-sequencing-and-how-files-are-located\/"},"modified":"2006-05-19T16:47:00","modified_gmt":"2006-05-19T16:47:00","slug":"file-sequencing-and-how-files-are-located","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/setup\/file-sequencing-and-how-files-are-located\/","title":{"rendered":"File Sequencing and How Files are Located"},"content":{"rendered":"<p>The\n<a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msi\/setup\/file_table.asp\">File\ntable<\/a> in a Windows Installer package has a Sequence column that begins with\n1. Besides determining in what order files are to be installed, this column\nserves another, relatively more important function: determining where the source\nfiles are located.<\/p>\n<p>In concert with the\n<a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msi\/setup\/media_table.asp\">\nMedia table<\/a>, a range of sequence numbers identify in which cabinet &#8211; if that\nrange of files is even compressed &#8211; the files are located. The Media table has a\ncolumn named LastSequence that is inclusive of the maximum sequence number of a\nparticular file range. All files in the File table with a sequence number\ngreater than the previous Media table entry&#8217;s LastSequence and less than or\nequal to another Media table entry&#8217;s LastSequence are contained in the latter\nmedia. To put that a little more plainly, see the following color-coded\ntables.<\/p>\n<table border=\"0\" style=\"margin-bottom: 1em\">\n<caption>\n<p align=\"left\">File table (partial)<\/p>\n<\/caption>\n<tr>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">File<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">&#8230;<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">FileName<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">&#8230;<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">Attributes<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">Sequence<\/font><\/th>\n<\/tr>\n<tr>\n<td bgcolor=\"#CCFFCC\">A_DLL<\/td>\n<td bgcolor=\"#CCFFCC\">&#8230;<\/td>\n<td bgcolor=\"#CCFFCC\">a.dll<\/td>\n<td bgcolor=\"#CCFFCC\">&#8230;<\/td>\n<td bgcolor=\"#CCFFCC\">0<\/td>\n<td bgcolor=\"#CCFFCC\">1<\/td>\n<\/tr>\n<tr>\n<td bgcolor=\"#CCFFCC\">B_DLL<\/td>\n<td bgcolor=\"#CCFFCC\">&#8230;<\/td>\n<td bgcolor=\"#CCFFCC\">b.dll<\/td>\n<td bgcolor=\"#CCFFCC\">&#8230;<\/td>\n<td bgcolor=\"#CCFFCC\">0<\/td>\n<td bgcolor=\"#CCFFCC\">2<\/td>\n<\/tr>\n<tr>\n<td bgcolor=\"#FFCCCC\">C_DLL<\/td>\n<td bgcolor=\"#FFCCCC\">&#8230;<\/td>\n<td bgcolor=\"#FFCCCC\">c.dll<\/td>\n<td bgcolor=\"#FFCCCC\">&#8230;<\/td>\n<td bgcolor=\"#FFCCCC\">16384<\/td>\n<td bgcolor=\"#FFCCCC\">3<\/td>\n<\/tr>\n<tr>\n<td bgcolor=\"#FFCCCC\">D_DLL<\/td>\n<td bgcolor=\"#FFCCCC\">&#8230;<\/td>\n<td bgcolor=\"#FFCCCC\">d.dll<\/td>\n<td bgcolor=\"#FFCCCC\">&#8230;<\/td>\n<td bgcolor=\"#FFCCCC\">16384<\/td>\n<td bgcolor=\"#FFCCCC\">4<\/td>\n<\/tr>\n<\/table>\n<table border=\"0\" style=\"margin-bottom: 1em\">\n<caption>\n<p align=\"left\">Media table<\/p>\n<\/caption>\n<tr>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">DiskId<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">LastSequence<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">DiskPrompt<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">Cabinet<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">VolumeLabel<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">Source<\/font><\/th>\n<\/tr>\n<tr>\n<td bgcolor=\"#CCFFCC\">1<\/td>\n<td bgcolor=\"#CCFFCC\">2<\/td>\n<td bgcolor=\"#CCFFCC\">Disk 1<\/td>\n<td bgcolor=\"#CCFFCC\">AB.cab<\/td>\n<td bgcolor=\"#CCFFCC\">DISK1<\/td>\n<td bgcolor=\"#CCFFCC\">&nbsp;<\/td>\n<\/tr>\n<tr>\n<td bgcolor=\"#FFCCCC\">2<\/td>\n<td bgcolor=\"#FFCCCC\">4<\/td>\n<td bgcolor=\"#FFCCCC\">Disk 2<\/td>\n<td bgcolor=\"#FFCCCC\">#CD.cab<\/td>\n<td bgcolor=\"#FFCCCC\">DISK2<\/td>\n<td bgcolor=\"#FFCCCC\">&nbsp;<\/td>\n<\/tr>\n<\/table>\n<p>The files <i>a.dll<\/i> and <i>b.dll<\/i> <b>may<\/b> be compressed into <i>AB.cab<\/i>,\nwhile <i>c.dll<\/i> and <i>d.dll<\/i> will be compressed into <i>CD.cab<\/i>. <i>\nCD.cab<\/i> begins with a hash symbol (#) because, as documented for the\n<a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msi\/setup\/cabinet.asp\">Cabinet\ndata type<\/a>, that cabinet will be embedded as a stream within the <i>.msi<\/i>\npackage. <i>AB.cab<\/i> would identify a cabinet in the root of the source tree\nspecified in the\n<a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msi\/setup\/directory_table.asp\">\nDirectory table<\/a>.<\/p>\n<p>You might also notice that I said the files <i>a.dll<\/i>\nand <i>b.dll<\/i> <b>may<\/b> be compressed into <i>AB.cab<\/i> because, depending on the\nWord Count, those files aren&#8217;t explicitly attributed to be compressed.\n<a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msi\/setup\/word_count_summary.asp\">\nThe Word Count Summary Property<\/a> describes the default setting for whether\nfiles are compressed or uncompressed. As documented in\n<a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msi\/setup\/compressed_and_uncompressed_sources.asp\">\nCompressed and Uncompressed Sources<\/a>, the Attributes column values of the File table\noverride the Word Count property value. So, if the Word Count property\nspecified that all sources were compressed then files <i>a.dll<\/i> and <i>b.dll<\/i>\nwould be compressed into <i>AB.cab<\/i>; otherwise, if the Word Count property\nspecified that all sources were uncompressed then only files <i>c.dll<\/i> and <i>\nd.dll<\/i> would be compressed into their respective cabinet.<\/p>\n<p>Now, for example, <i>b.dll<\/i> needs to be patched. A patch must carry the\nnew copy (or binary delta patch) of <i>b.dll<\/i> so it must change the file\nsequence of <i>b.dll<\/i> to match up with a new entry in the Media table to be\nadded by one of the patch transforms for a particular product, as discussed in more detail in\n<a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2005\/09\/01\/459561.aspx\">What&#8217;s in\na Patch<\/a>. The transform beginning with a hash symbol (#) would make the\nfollowing changes from the previous tables.<\/p>\n<table border=\"0\" style=\"margin-bottom: 1em\">\n<caption>\n<p align=\"left\">File table (partial)<\/p>\n<\/caption>\n<tr>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">File<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">&#8230;<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">FileName<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">&#8230;<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">Attributes<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">Sequence<\/font><\/th>\n<\/tr>\n<tr>\n<td bgcolor=\"#CCFFCC\">A_DLL<\/td>\n<td bgcolor=\"#CCFFCC\">&#8230;<\/td>\n<td bgcolor=\"#CCFFCC\">a.dll<\/td>\n<td bgcolor=\"#CCFFCC\">&#8230;<\/td>\n<td bgcolor=\"#CCFFCC\">0<\/td>\n<td bgcolor=\"#CCFFCC\">1<\/td>\n<\/tr>\n<tr>\n<td bgcolor=\"#FFCCCC\">C_DLL<\/td>\n<td bgcolor=\"#FFCCCC\">&#8230;<\/td>\n<td bgcolor=\"#FFCCCC\">c.dll<\/td>\n<td bgcolor=\"#FFCCCC\">&#8230;<\/td>\n<td bgcolor=\"#FFCCCC\">16384<\/td>\n<td bgcolor=\"#FFCCCC\">3<\/td>\n<\/tr>\n<tr>\n<td bgcolor=\"#FFCCCC\">D_DLL<\/td>\n<td bgcolor=\"#FFCCCC\">&#8230;<\/td>\n<td bgcolor=\"#FFCCCC\">d.dll<\/td>\n<td bgcolor=\"#FFCCCC\">&#8230;<\/td>\n<td bgcolor=\"#FFCCCC\">16384<\/td>\n<td bgcolor=\"#FFCCCC\">4<\/td>\n<\/tr>\n<tr>\n<td bgcolor=\"#99CCFF\">B_DLL<\/td>\n<td bgcolor=\"#99CCFF\">&#8230;<\/td>\n<td bgcolor=\"#99CCFF\">b.dll<\/td>\n<td bgcolor=\"#99CCFF\">&#8230;<\/td>\n<td bgcolor=\"#99CCFF\">20480<\/td>\n<td bgcolor=\"#99CCFF\">5<\/td>\n<\/tr>\n<\/table>\n<table border=\"0\" style=\"margin-bottom: 1em\">\n<caption>\n<p align=\"left\">Media table<\/p>\n<\/caption>\n<tr>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">DiskId<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">LastSequence<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">DiskPrompt<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">Cabinet<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">VolumeLabel<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">Source<\/font><\/th>\n<\/tr>\n<tr>\n<td bgcolor=\"#CCFFCC\">1<\/td>\n<td bgcolor=\"#CCFFCC\">2<\/td>\n<td bgcolor=\"#CCFFCC\">Disk 1<\/td>\n<td bgcolor=\"#CCFFCC\">AB.cab<\/td>\n<td bgcolor=\"#CCFFCC\">DISK1<\/td>\n<td bgcolor=\"#CCFFCC\">&nbsp;<\/td>\n<\/tr>\n<tr>\n<td bgcolor=\"#FFCCCC\">2<\/td>\n<td bgcolor=\"#FFCCCC\">4<\/td>\n<td bgcolor=\"#FFCCCC\">Disk 2<\/td>\n<td bgcolor=\"#FFCCCC\">#CD.cab<\/td>\n<td bgcolor=\"#FFCCCC\">DISK2<\/td>\n<td bgcolor=\"#FFCCCC\">&nbsp;<\/td>\n<\/tr>\n<tr>\n<td bgcolor=\"#99CCFF\">3<\/td>\n<td bgcolor=\"#99CCFF\">5<\/td>\n<td bgcolor=\"#99CCFF\">&nbsp;<\/td>\n<td bgcolor=\"#99CCFF\">#P1.cab<\/td>\n<td bgcolor=\"#99CCFF\">&nbsp;<\/td>\n<td bgcolor=\"#99CCFF\">MspSrc3<\/td>\n<\/tr>\n<\/table>\n<table border=\"0\" style=\"margin-bottom: 1em\">\n<caption>\n<p align=\"left\">PatchPackage table<\/p>\n<\/caption>\n<tr>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">PatchId<\/font><\/th>\n<th bgcolor=\"#808080\" align=\"left\"><font color=\"#FFFFFF\">Media_<\/font><\/th>\n<\/tr>\n<tr>\n<td bgcolor=\"#99CCFF\">{45F3433D-47C1-4AAF-9B4C-4FA759A02C0A}<\/td>\n<td bgcolor=\"#99CCFF\">3<\/td>\n<\/tr>\n<\/table>\n<p>Re-sequencing this file locates it in the the patch in the embedded stream\nnamed <i>P1.cab<\/i>. The attributes are changed to <code>msidbFileAttributesPatchAdded<\/code>\n(4096) + <code>msidbFileAttributesCompressed<\/code> (16384), the latter of which\nto override whatever the default Word Count is set for the <i>.msi<\/i> package\nbeing patched. The Word Count property value of the <i>.msp<\/i> file is used to\nidentify the minimum version of Windows Installer required to install the patch\nand does not specify compression. Prior to Windows Installer 2.0 you had to\nguarauntee uniqueness of file sequence numbers for both the installer package\nfor all patches, but starting with Windows Installer 2.0 you need only ensure\nthat file sequences numbers are correct for a given package since Windows\nInstaller 2.0 and newer will automatically adjust file sequence number as\nnecessary.<\/p>\n<p>When the transforms are applied from a patch and the files are re-sequenced,\na reinstall of the affected features or all of the product is performed as\ndocumented in\n<a href=\"http:\/\/blogs.msdn.com\/heaths\/archive\/2005\/09\/12\/464047.aspx\">How\nPatching Works<\/a>. The value in the Source column of the Media table for DiskId\n3 is used to identify the location of the <i>.msp<\/i> file in order to locate\nthe embedded cabinet.<\/p>\n<p>Do note that the default schema of the File and Media tables allow for a\nmaximum of 32,767 files including all changes made by any applicable patches. In\nthe last set of tables, Windows Installer would view the product as now having 5\nfiles. The reason is that the column data type is only a 2-byte signed integer.\nFor more information about how to author a package with more initial files or to\nallow for many more patches, read\n<a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/msi\/setup\/authoring_a_large_package.asp\">\nAuthoring a Large Package<\/a>.<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The File table in a Windows Installer package has a Sequence column that begins with 1. Besides determining in what order files are to be installed, this column serves another, relatively more important function: determining where the source files are located. In concert with the Media table, a range of sequence numbers identify in which [&hellip;]<\/p>\n","protected":false},"author":389,"featured_media":3843,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[17,20],"class_list":["post-2213","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-essentials","tag-installation"],"acf":[],"blog_post_summary":"<p>The File table in a Windows Installer package has a Sequence column that begins with 1. Besides determining in what order files are to be installed, this column serves another, relatively more important function: determining where the source files are located. In concert with the Media table, a range of sequence numbers identify in which [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/2213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/users\/389"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/comments?post=2213"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/2213\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/media\/3843"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/media?parent=2213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/categories?post=2213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/tags?post=2213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}