{"id":27453,"date":"2007-03-29T10:00:00","date_gmt":"2007-03-29T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/03\/29\/the-buffer-size-parameter-to-getfileversioninfo-is-the-size-of-your-buffer-no-really\/"},"modified":"2007-03-29T10:00:00","modified_gmt":"2007-03-29T10:00:00","slug":"the-buffer-size-parameter-to-getfileversioninfo-is-the-size-of-your-buffer-no-really","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20070329-00\/?p=27453\/","title":{"rendered":"The buffer size parameter to GetFileVersionInfo is the size of your buffer, no really"},"content":{"rendered":"<p>\nThe <code>GetFileVersionInfo<\/code> function takes a\npointer to a buffer (<code>lpData<\/code>) and a size\n(<code>dwLen<\/code>),\nand that size is the size of the buffer, in bytes.\n<\/p>\n<p>\nNo really, that&#8217;s what it is.\n<\/p>\n<p>\nThe application compatibility folks found one popular game\nwhich wasn&#8217;t quite sure what that <code>dwLen<\/code> parameter\nmeant.\nThe programmers must have thought it meant &#8220;The size of the version resources\nyou want to load&#8221; and called it like this (paraphrased):\n<\/p>\n<pre>\nvoid CheckFileVersion(LPCTSTR pszFile)\n{\n BYTE buffer[1024];\n DWORD dwHandle;\n DWORD dwLen = GetFileVersionInfoSize(pszFile, &amp;dwHandle);\n if (GetFileVersionInfo(pszFile, dwHandle, dwLen, buffer)) {\n  ...\n }\n}\n<\/pre>\n<p>\n&#8220;Gosh, the\n<code>GetFileVersionInfo<\/code> function wants to know how big\nthe version info is,\nso we need to call <code>GetFileVersionInfoSize<\/code> to find out!&#8221;\nthey must have thought.\n<\/p>\n<p>\nThis code worked great&#8230; for a while.\nIt was checking the file version of the video driver.\n(My guess is that they were trying to detect specific\nvideo drivers so they could work around bugs in them\nor take advantage of driver-specific features.)\nBut if you had a video driver whose version\nresource needed more than 1024 bytes of space,\nthe program crashed with stack corruption.\n<\/p>\n<p>\nI don&#8217;t know whether the Windows Vista\napplication compatibility folks decided\nthat it was worth fixing this program&#8217;s bug, since it occurred\neven on Windows&nbsp;XP.\nIf so decided, the fix would have been fairly straightforward.\nOnce the program was detected,\nwe would just have had to take the\nvalue the program passed as <code>dwLen<\/code> and modify it\naccording to the simple formula\n<\/p>\n<pre>\ndwLen = min(dwLen, 1024);\n<\/pre>\n<p>\nbefore doing the real work of loading the version information.\n<\/p>\n<p>\nFor those playing along at home, by the way, the correct\ncode would go something like this:\n<\/p>\n<pre>\nvoid CheckFileVersion(LPCTSTR pszFile)\n{\n DWORD dwHandle;\n DWORD dwLen = GetFileVersionInfoSize(pszFile, &amp;dwHandle);\n if (dwLen) {\n  BYTE *pBuffer = (BYTE*)malloc(dwLen);\n  if (pBuffer) {\n   if (GetFileVersionInfo(pszFile, dwHandle, dwLen, pBuffer)) {\n    ...\n   }\n   free(pBuffer);\n  }\n }\n}\n<\/pre>\n<p>\n(Use your favorite memory allocation technique instead of <code>malloc<\/code>\nand <code>free<\/code>.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The GetFileVersionInfo function takes a pointer to a buffer (lpData) and a size (dwLen), and that size is the size of the buffer, in bytes. No really, that&#8217;s what it is. The application compatibility folks found one popular game which wasn&#8217;t quite sure what that dwLen parameter meant. The programmers must have thought it meant [&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":[25],"class_list":["post-27453","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The GetFileVersionInfo function takes a pointer to a buffer (lpData) and a size (dwLen), and that size is the size of the buffer, in bytes. No really, that&#8217;s what it is. The application compatibility folks found one popular game which wasn&#8217;t quite sure what that dwLen parameter meant. The programmers must have thought it meant [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/27453","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=27453"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/27453\/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=27453"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=27453"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=27453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}