{"id":28653,"date":"2006-12-20T10:00:15","date_gmt":"2006-12-20T10:00:15","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2006\/12\/20\/the-evolution-of-version-resources-16-bit-version-resources\/"},"modified":"2006-12-20T10:00:15","modified_gmt":"2006-12-20T10:00:15","slug":"the-evolution-of-version-resources-16-bit-version-resources","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20061220-15\/?p=28653","title":{"rendered":"The evolution of version resources &#8211; 16-bit version resources"},"content":{"rendered":"<p>\nI return to the extremely sporadic series on resources\nwith a description of the version resource.\nYou don&#8217;t need to know how version resources are\nformatted internally;\nyou should just use the version resource manipulation functions\n<code>GetFileVersionInfo<\/code>,\n<code>VerQueryValue<\/code>, and their friends.\nI&#8217;m providing this information merely for its historical significance.\n<\/p>\n<p>\nVersion resources can be viewed as a serialized tree structure.\nEach node of the tree has a name and associated data\n(either binary or text),\nand each node can have zero or more child nodes.\nThe root node is always named <code>VS_VERSION_INFO<\/code> and\nis a binary node consisting of a <code>VS_FIXEDFILEINFO<\/code>\nstructure.\nBeyond that, you can call your nodes anything you want and\ngive them any kind of data you want.\nBut if you want other people to understand your version information,\nyou&#8217;d be best off following the conventions I describe below.\nActually, since people seem to prefer diagrams to words,\nI&#8217;ll give you a diagram:\n<\/p>\n<table>\n<tr>\n<td COLSPAN=\"4\"><code>VS_VERSION_INFO<\/code><\/td>\n<td><code>VS_FIXEDFILEINFO<\/code> structure (binary)<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\" STYLE=\"width: 1em\"><\/td>\n<td COLSPAN=\"3\"><code>StringFileInfo<\/code><\/td>\n<td>(no data)<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\" STYLE=\"width: 1em\"><\/td>\n<td COLSPAN=\"2\"><code>xxxxyyyy<\/code><\/td>\n<td>(no data)<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\" STYLE=\"width: 1em\"><\/td>\n<td COLSPAN=\"1\"><code>CompanyName<\/code><\/td>\n<td>string for xxxxyyyy<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><code>FileDescription<\/code><\/td>\n<td>string for xxxxyyyy<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><code>FileVersion<\/code><\/td>\n<td>string for xxxxyyyy<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><code>...<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\" STYLE=\"width: 1em\"><\/td>\n<td COLSPAN=\"2\"><code>zzzzwwww<\/code><\/td>\n<td>(no data)<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\" STYLE=\"width: 1em\"><\/td>\n<td COLSPAN=\"1\"><code>CompanyName<\/code><\/td>\n<td>string for zzzzwwww<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><code>FileDescription<\/code><\/td>\n<td>string for zzzzwwww<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><code>FileVersion<\/code><\/td>\n<td>string for zzzzwwww<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\"><code>...<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\" STYLE=\"width: 1em\"><\/td>\n<td COLSPAN=\"3\"><code>VarFileInfo<\/code><\/td>\n<td>(no data)<\/td>\n<\/tr>\n<tr>\n<td COLSPAN=\"1\"><\/td>\n<td COLSPAN=\"1\" STYLE=\"width: 1em\"><\/td>\n<td COLSPAN=\"2\"><code>Translation<\/code><\/td>\n<td>array of locale\/codepage pairs (binary, variable-size)<\/td>\n<\/tr>\n<\/table>\n<p>\nThe child nodes can appear in any order, and the strings\nlike <code>CompanyName<\/code> are all optional.\n<code>VarFileInfo\\Translation<\/code>, however, is mandatory\n(by convention).\n<\/p>\n<p>\nIf you&#8217;ve used <code>VerQueryValue<\/code>, you know that the\nbinary data stored under\n<code>VarFileInfo\\Translation<\/code> consists of a variable-length\narray of locale\/codepage pairs, each of which in turn corresponds\nto a child of the <code>StringfileInfo<\/code> node.\nI&#8217;m not going to go into what each of the strings means and how\nthe local\/codepage pairs turn into child nodes of <code>StringFileInfo<\/code>;\nI&#8217;ll leave you to research that on your own (assuming you don&#8217;t\nalready know).\n<\/p>\n<p>\nHow does this tree get stored into a resource?\nIt&#8217;s actually quite simple.\nEach node is stored in a structure which takes the following\nform (in pseudo-C):\n<\/p>\n<pre>\nstruct VERSIONNODE {\n  WORD  cbNode;\n  WORD  cbData;\n  CHAR  szName[];\n  BYTE  rgbPadding1[]; \/\/ DWORD alignment\n  BYTE  rgbData[cbData];\n  BYTE  rgbPadding2[]; \/\/ DWORD alignment\n  VERSIONNODE rgvnChildren[];\n};\n<\/pre>\n<p>\nIn words, each version node begins with a 16-bit value\ndescribing the size of the nodes in bytes (including its children),\nfollowed by a 16-bit value that specifies how many bytes\nof data (either binary or text) are associated with the node.\n(If the node contains text data, the count includes the null terminator.)\nNext comes the null-terminated name of the node\nand padding bytes to bring us back into <code>DWORD<\/code>\nalignment.\nAfter the key name (and optional padding) comes the data,\nagain followed by padding bytes to bring us back\ninto <code>DWORD<\/code> alignment.\nFinally, after all the node information come its children.\n<\/p>\n<p>\nSince each of the children might themselves have children,\nyou can see how the tree structure &#8220;flattens&#8221; into this\nserialized format.\nTo move from one node to its next sibling, you skip ahead\nby <code>cbNode<\/code> bytes.\nTo move from a node to its first child, you skip over\nthe key name and associated data.\n<\/p>\n<p>\nLet&#8217;s take a look at the resources for the 16-bit\n<code>shell.dll<\/code> to see how this all fits together.\n<\/p>\n<pre>\n0000  E4 01 34 00 56 53 5F 56-45 52 53 49 4F 4E 5F 49  ..4.VS_VERSION_I\n0010  4E 46 4F 00 BD 04 EF FE-00 00 01 00 0A 00 03 00  NFO.............\n0020  67 00 00 00 0A 00 03 00-67 00 00 00 3F 00 00 00  g.......g...?...\n0030  0A 00 00 00 01 00 01 00-02 00 00 00 00 00 00 00  ................\n0040  00 00 00 00 00 00 00 00-78 01 00 00 53 74 72 69  ........x...Stri\n0050  6E 67 46 69 6C 65 49 6E-66 6F 00 00 64 01 00 00  ngFileInfo..d...\n0060  30 34 30 39 30 34 45 34-00 00 00 00 27 00 17 00  040904E4....'...\n0070  43 6F 6D 70 61 6E 79 4E-61 6D 65 00 4D 69 63 72  CompanyName.Micr\n0080  6F 73 6F 66 74 20 43 6F-72 70 6F 72 61 74 69 6F  osoft Corporatio\n0090  6E 00 00 00 2A 00 16 00-46 69 6C 65 44 65 73 63  n...*...FileDesc\n00A0  72 69 70 74 69 6F 6E 00-57 69 6E 64 6F 77 73 20  ription.Windows\n00B0  53 68 65 6C 6C 20 6C 69-62 72 61 72 79 00 00 00  Shell library...\n00C0  16 00 06 00 46 69 6C 65-56 65 72 73 69 6F 6E 00  ....FileVersion.\n00D0  33 2E 31 30 00 00 00 00-1A 00 06 00 49 6E 74 65  3.10........Inte\n00E0  72 6E 61 6C 4E 61 6D 65-00 00 00 00 53 48 45 4C  rnalName....SHEL\n00F0  4C 00 00 00 3B 00 27 00-4C 65 67 61 6C 43 6F 70  L...;.'.LegalCop\n0100  79 72 69 67 68 74 00 00-43 6F 70 79 72 69 67 68  yright..Copyrigh\n0110  74 20 A9 20 4D 69 63 72-6F 73 6F 66 74 20 43 6F  t . Microsoft Co\n0120  72 70 2E 20 31 39 38 31-2D 31 39 39 36 00 00 00  rp. 1981-1996...\n0130  22 00 0A 00 4F 72 69 67-69 6E 61 6C 46 69 6C 65  \"...OriginalFile\n0140  6E 61 6D 65 00 00 00 00-53 48 45 4C 4C 2E 44 4C  name....SHELL.DL\n0150  4C 00 00 00 39 00 29 00-50 72 6F 64 75 63 74 4E  L...9.).ProductN\n0160  61 6D 65 00 4D 69 63 72-6F 73 6F 66 74 AE 20 57  ame.Microsoft. W\n0170  69 6E 64 6F 77 73 28 54-4D 29 20 4F 70 65 72 61  indows(TM) Opera\n0180  74 69 6E 67 20 53 79 73-74 65 6D 00 00 00 00 00  ting System.....\n0190  1A 00 06 00 50 72 6F 64-75 63 74 56 65 72 73 69  ....ProductVersi\n01A0  6F 6E 00 00 33 2E 31 30-00 00 00 00 14 00 04 00  on..3.10........\n01B0  57 4F 57 20 56 65 72 73-69 6F 6E 00 34 2E 30 00  WOW Version.4.0.\n01C0  24 00 00 00 56 61 72 46-69 6C 65 49 6E 66 6F 00  $...VarFileInfo.\n01D0  14 00 04 00 54 72 61 6E-73 6C 61 74 69 6F 6E 00  ....Translation.\n01E0  09 04 E4 04                                      ....\n<\/pre>\n<p>\nWe start with the root node.\n<\/p>\n<pre>\n0000  E4 01         \/\/ cbNode (node ends at 0x0000 + 0x01E4 = 0x01E4)\n0002  34 00         \/\/ cbData = sizeof(VS_FIXEDFILEINFO)\n0004  56 53 5F 56 45 52 53 49 4F 4E 5F 49 4E 46 4F 00\n                    \/\/ \"VS_VERSION_INFO\" + null terminator\n<\/pre>\n<p>\nNotice that the size of the root node equals the size of\nthe entire version resource.\nThis is to be expected, of course, because the version resource\nis merely a serialization of the resource tree diagram.\n<\/p>\n<p>Since the string name (plus null terminator) happens to come out\nto an exact multiple of four bytes, there is no need for padding\nbetween the name and the binary data, which takes the form of a\n<code>VS_FIXEDFILEINFO<\/code>:\n<\/p>\n<pre>\n0014  BD 04 EF FE   \/\/ dwSignature\n0018  00 00 01 00   \/\/ dwStrucVersion\n001C  0A 00 03 00   \/\/ dwFileVersionMS = 3.10\n0020  67 00 00 00   \/\/ dwFileVersionLS = 0.103\n0024  0A 00 03 00   \/\/ dwProductVersionMS = 3.10\n0028  67 00 00 00   \/\/ dwProductVersionLS = 0.103\n002C  3F 00 00 00   \/\/ dwFileFlagsMask\n0030  0A 00 00 00   \/\/ dwFileFlags\n0034  01 00 01 00   \/\/ dwFileOS = VOS_DOS_WINDOWS16\n0038  02 00 00 00   \/\/ dwFileType = VFT_DLL\n003C  00 00 00 00   \/\/ dwFileSubtype\n0040  00 00 00 00   \/\/ dwFileDateMS\n0044  00 00 00 00   \/\/ dwFileDateLS\n<\/pre>\n<p>\nThe structure is also a multiple of 4 bytes in length,\nso no padding is necessary between the data and the child nodes.\n<\/p>\n<pre>\n0048  78 01         \/\/ cbNode (node ends at 0x0048 + 0x0178 = 0x01C0)\n004A  00 00         \/\/ cbData (no data)\n004C  53 74 72 69 6E 67 46 69 6C 65 49 6E 66 6F 00\n                    \/\/ \"StringFileInfo\" + null\n005B  00            \/\/ padding to restore alignment\n005C                \/\/ no data\n<\/pre>\n<p>\nThe first child is the <code>StringFileInfo<\/code>.\nIt has no data, so its own children come directly after\nthe name (and padding).\nAnd the children of <code>StringFileInfo<\/code>\nare the language nodes.\n<\/p>\n<pre>\n005C  64 01         \/\/ cbNode (node ends at 0x005C + 0x0164 = 0x01C0)\n005E  00 00         \/\/ cbData (no data)\n0060  30 34 30 39 30 34 45 34 00\n                    \/\/ \"040904E4\" + null terminator\n0069  00 00 00      \/\/ padding to restore alignment\n006C                \/\/ no data\n<\/pre>\n<p>\nThe children of the language node are the strings.\nThis is where all the goodies can be found.\n<\/p>\n<pre>\n006C  27 00         \/\/ cbNode (node ends at 0x006C + 0x0027 = 0x0093)\n006E  17 00         \/\/ cbData\n0070  43 6F 6D 70 61 6E 79 4E 61 6D 65 00\n                    \/\/ \"CompanyName\" + null terminator\n007C                \/\/ no padding needed\n007C  4D 69 63 72 6F 73 6F 66 74 20 43 6F\n      72 70 6F 72 61 74 69 6F 6E 00\n                    \/\/ \"Microsoft Corporation\" + null terminator\n0091  00 00 00      \/\/ padding to restore alignment\n<\/pre>\n<p>\nNotice that the padding bytes\nare not counted in the <code>cbData<\/code>.\nIn fact, the padding bytes at the end of the data don&#8217;t\neven count towards the <code>cbNode<\/code>.\nThis is a leaf node since we already reach the end of the node\nonce we store the data.\nTherefore, the next node in the version resource is a sibling,\nnot a child.\n<\/p>\n<pre>\n0094  2A 00         \/\/ cbNode (node ends at 0x0094 + 0x002A = 0x00BE)\n0096  16 00         \/\/ cbData\n0098  46 69 6C 65 44 65 73 63 72 69 70 74 69 6F 6E 00\n                    \/\/ \"FileDescription\" + null terminator\n00A8                \/\/ no padding needed\n00A8  57 69 6E 64 6F 77 73 20 53 68 65 6C 6C 20 6C 69\n      62 72 61 72 79 00\n                    \/\/ \"Windows Shell library\" + null terminator\n00BE  00 00         \/\/ padding to restore alignment\n<\/pre>\n<p>\nAll of these nodes have no children since we run out of\nbytes in <code>cbNode<\/code> after representing the node&#8217;s\nname and data.\n<\/p>\n<pre>\n00C0  16 00         \/\/ cbNode (node ends at 0x00C0 + 0x0016 = 0x00D6)\n00C2  06 00         \/\/ cbData\n00C4  46 69 6C 65 56 65 72 73 69 6F 6E 00\n                    \/\/ \"FileVersion\" + null terminator\n00D0  33 2E 31 30 00\n                    \/\/ \"3.10\"\n00D5  00 00 00      \/\/ padding to restore alignment\n00D8  1A 00         \/\/ cbNode (node ends at 0x00D8 + 0x001A = 0x00F2)\n00DA  06 00         \/\/ cbData\n00DC  49 6E 74 65 72 6E 61 6C 4E 61 6D 65 00\n                    \/\/ \"InternalName\" + null terminator\n00E9  00 00 00      \/\/ padding to restore alignment\n00EC  53 48 45 4C 4C 00\n                    \/\/ \"SHELL\" + null terminator\n00F2  00 00         \/\/ padding to restore alignment\n00F4  3B 00         \/\/ cbNode (node ends at 0x00F4 + 0x003B = 0x12E)\n00F6  27 00\n00F8  4C 65 67 61 6C 43 6F 70 79 72 69 67 68 74 00\n                    \/\/ \"LegalCopyright\" + null terminator\n0107  00            \/\/ padding to restore alignment\n0108  43 6F 70 79 72 69 67 68 74 20 A9 20 4D 69 63 72\n      6F 73 6F 66 74 20 43 6F 72 70 2E 20 31 39 38 31\n      2D 31 39 39 36 00\n                    \/\/ \"Copyright &#xA9; Microsoft Corp. 1981-1996\"\n                    \/\/ + null terminator + another null terminator?\n012F  00            \/\/ padding to restore alignment\n<\/pre>\n<p>Wait a second, what&#8217;s that &#8220;another null terminator&#8221;?\nif you count the bytes, you&#8217;ll see that the <code>cbData<\/code>\nfor the <code>LegalCopyright<\/code> node counts not only the\nterminating null, but another bonus null after it.\nI suspect that somebody put an extra null terminator in the\nresource file by mistake:\n<\/p>\n<pre>\n    VALUE \"LegalCopyright\", \"Copyright\\251 Microsoft corp. 1981-1996\\0\"\n<\/pre>\n<p>\nFor whatever reason, there&#8217;s an extra null in there.\n<\/p>\n<pre>\n0130  22 00         \/\/ cbNode (node ends at 0x0130 + 0x0022 = 0x0152)\n0132  0A 00         \/\/ cbData\n0134  4F 72 69 67 69 6E 61 6C 46 69 6C 65 6E 61 6D 65 00\n                    \/\/ \"OriginalFilename\" + null terminator\n0145  00 00 00      \/\/ padding to restore alignment\n0148  53 48 45 4C 4C 2E 44 4C 4C 00\n                    \/\/ \"SHELL.DLL\" + null terminator\n0152  00 00         \/\/ padding to restore alignment\n0154  39 00         \/\/ cbNode (node ends at 0x0154 + 0x0039 = 0x018D)\n0156  29 00         \/\/ cbData\n0158  50 72 6F 64 75 63 74 4E 61 6D 65 00\n                    \/\/ \"ProductName\" + null terminator\n0164  4D 69 63 72 6F 73 6F 66 74 AE 20 57 69 6E 64 6F\n      77 73 28 54 4D 29 20 4F 70 65 72 61 74 69 6E 67\n      20 53 79 73 74 65 6D 00 00\n                    \/\/ \"Microsoft&#xAE; Windows(TM) \"\n                    \/\/ \"Operating System\" + null terminator\n                    \/\/ + another null terminator?\n018D  00 00 00      \/\/ padding to restore alignment\n<\/pre>\n<p>\nThere&#8217;s another of those extra null terminators. Go figure.\n<\/p>\n<pre>\n0190  1A 00         \/\/ cbNode (node ends at 0x0190 + 0x001A = 0x01AA)\n0192  06 00         \/\/ cbData\n0194  50 72 6F 64 75 63 74 56 65 72 73 69 6F 6E 00\n                    \/\/ \"ProductVersion\" + null terminator\n01A3  00            \/\/ padding to restore alignment\n01A4  33 2E 31 30 00 00\n                    \/\/ \"3.10\" + null terminator\n                    \/\/ + another null terminator?\n01AA  00 00         \/\/ padding to restore alignment\n01AC  14 00         \/\/ cbNode (node ends at 0x01AC + 0x0014 = 0x01C0)\n01AE  04 00         \/\/ cbData\n01B0  57 4F 57 20 56 65 72 73 69 6F 6E 00\n                    \/\/ \"WOW Version\"\n01BC                \/\/ no padding needed\n01BC  34 2E 30 00   \/\/ \"4.0\" + null terminator\n01C0                \/\/ no padding needed\n<\/pre>\n<p>\nOnce we reach offset <code>0x01C0<\/code>, we&#8217;re reached the\nend of not only the <code>WOW Version<\/code> node, but also\nthe end of the <code>040904E4<\/code> node and the\n<code>StringFileInfo<\/code> node.\nTherefore, the next node is a child of the root.\n<\/p>\n<pre>\n01C0  24 00         \/\/ cbNode (node ends at 0x01C0 + 0x0024 = 0x01E4)\n01C2  00 00         \/\/ cbData (no data)\n01C4  56 61 72 46 69 6C 65 49 6E 66 6F 00\n                    \/\/ \"VarFileInfo\" + null terminator\n01D0                \/\/ no padding needed\n01D0                \/\/ no data\n<\/pre>\n<p>\nSince we have not reached the end of the <code>VarFileInfo<\/code>\nnode, the data that comes next must be a child node.\n<\/p>\n<pre>\n01D0  14 00         \/\/ cbNode (noed ends at 0x01D0 + 0x0014 = 0x01E4)\n01D4  04 00         \/\/ cbData\n01D6  54 72 61 6E 73 6C 61 74 69 6F 6E 00\n                    \/\/ \"Translation\" + null terminator\n01E0  09 04 E4 04   \/\/ 0x0409 = US English\n                    \/\/ 0x04E4 = 1252 = Western European\n01E4                \/\/ no padding needed\n<\/pre>\n<p>\nAnd once we&#8217;ve reached offset <code>0x01E4<\/code>, we&#8217;ve\nreached the end of the <code>Translation<\/code> node,\nthe <code>VarFileInfo<\/code> node, and the root node.\n<\/p>\n<p>\nThus, we have reconstructed the original version resource:\n<\/p>\n<pre>\nFILEVERSION    3,10,0,103\nPRODUCTVERSION 3,10,0,103\nFILEFLAGSMASK  VS_FFI_FILEFLAGSMASK\nFILEFLAGS      VS_FF_PRERELEASE | VS_FF_PRIVATEBUILD\nFILEOS         VOS_DOS_WINDOWS16\nFILETYPE       VFT_DLL\nFILESUBTYPE    VFT_UNKNOWN\nBEGIN\n BLOCK \"StringFileInfo\"\n BEGIN\n  BLOCK \"040904E4\"\n  BEGIN\n   VALUE \"CompanyName\", \"Microsoft Corporation\"\n   VALUE \"FileDescription\", \"Windows Shell library\"\n   VALUE \"FileVersion\", \"3.10\"\n   VALUE \"InternalName\", \"SHELL\"\n   VALUE \"LegalCopyright\", \"Copyright\\251 Microsoft corp. 1981-1996\\0\"\n   VALUE \"OriginalFilename\", \"SHELL.DLL\"\n   VALUE \"ProductName\", \"Microsoft\\256 Windows(TM) Operating System\\0\"\n   VALUE \"ProductVersion\", \"3.10\\0\"\n   VALUE \"WOW Version\", \"4.0\"\n  END\n END\n BLOCK \"VarFileInfo\"\n BEGIN\n  VALUE \"Translation\", 0x0409, 0x04E4\n END\nEND\n<\/pre>\n<p>\nNext time, we&#8217;ll look at how version resources are represented\nin 32-bit resources.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I return to the extremely sporadic series on resources with a description of the version resource. You don&#8217;t need to know how version resources are formatted internally; you should just use the version resource manipulation functions GetFileVersionInfo, VerQueryValue, and their friends. I&#8217;m providing this information merely for its historical significance. Version resources can be viewed [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[2],"class_list":["post-28653","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>I return to the extremely sporadic series on resources with a description of the version resource. You don&#8217;t need to know how version resources are formatted internally; you should just use the version resource manipulation functions GetFileVersionInfo, VerQueryValue, and their friends. I&#8217;m providing this information merely for its historical significance. Version resources can be viewed [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/28653","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=28653"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/28653\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=28653"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=28653"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=28653"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}