{"id":34883,"date":"2005-07-20T10:00:16","date_gmt":"2005-07-20T10:00:16","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/07\/20\/why-does-findfirstfile-find-short-names\/"},"modified":"2005-07-20T10:00:16","modified_gmt":"2005-07-20T10:00:16","slug":"why-does-findfirstfile-find-short-names","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050720-16\/?p=34883","title":{"rendered":"Why does FindFirstFile find short names?"},"content":{"rendered":"<p><a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/fileio\/base\/findfirstfile.asp\"> The <code>FindFirstFile<\/code> function<\/a> matches both the short and long names. This can produce somewhat surprising results. For example, if you ask for &#8220;*.htm&#8221;, this also gives you the file &#8220;x.html&#8221; since its short name is &#8220;X~1.HTM&#8221;.<\/p>\n<p> Why does it bother matching short names? Shouldn&#8217;t it match only long names? After all, only old 16-bit programs use short names. <\/p>\n<p> But that&#8217;s the problem: 16-bit programs use short names. <\/p>\n<p> Through a process known as <a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winprog\/winprog\/generic_thunks.asp\"> generic thunks<\/a>, a 16-bit program can load a 32-bit DLL and call into it. Windows&nbsp;95 and  the Windows 16-bit emulation layer in Windows&nbsp;NT rely heavily on generic thunks so that they don&#8217;t have to write two versions of everything. Instead, the 16-bit version just thunks up to the 32-bit version. <\/p>\n<p> Note, however, that this would mean that 32-bit DLLs would see two different views of the file system, depending on whether they are hosted from a 16-bit process or a 32-bit process. <\/p>\n<p> &#8220;Then make the <code>FindFirstFile<\/code> function check to see who its caller is and change its behavior accordingly,&#8221; doesn&#8217;t fly because <a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/01\/01\/47042.aspx\"> you can&#8217;t trust the return address<\/a>. <\/p>\n<p> Even if this problem were solved, you would still have the problem of 16\/32 interop across the process boundary. <\/p>\n<p> For example, suppose a 16-bit program calls <code>WinExec(\"notepad X~1.HTM\")<\/code>. The 32-bit Notepad program had better open the file X~1.HTM even though it&#8217;s a short name. What&#8217;s more, a common way to get properties of a file such as its last access time is to call <code>FindFirstFile<\/code> with the file name, since the <code>WIN32_FIND_DATA<\/code> structure returns that information as part of the find data. (Note: <code>GetFileAttributesEx<\/code> is a better choice, but that function is comparatively new.) If the <code>FindFirstFile<\/code> function did not work for short file names, then the above trick would fail for short names passed across the 16\/32 boundary. <\/p>\n<p> As another example, suppose the DLL saves the file name in a location external to the process, say a configuration file, the registry, or a shared memory block.  If a 16-bit program program calls into this DLL, it would pass short names, whereas if a 32-bit program calls into the DLL, it would pass long names.  If the file system functions returned only long names for 32-bit programs, then the copy of the DLL running in a 32-bit program would not be able to read the data written by the DLL running in a 16-bit program. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>The FindFirstFile function matches both the short and long names. This can produce somewhat surprising results. For example, if you ask for &#8220;*.htm&#8221;, this also gives you the file &#8220;x.html&#8221; since its short name is &#8220;X~1.HTM&#8221;. Why does it bother matching short names? Shouldn&#8217;t it match only long names? After all, only old 16-bit programs [&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-34883","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>The FindFirstFile function matches both the short and long names. This can produce somewhat surprising results. For example, if you ask for &#8220;*.htm&#8221;, this also gives you the file &#8220;x.html&#8221; since its short name is &#8220;X~1.HTM&#8221;. Why does it bother matching short names? Shouldn&#8217;t it match only long names? After all, only old 16-bit programs [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/34883","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=34883"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/34883\/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=34883"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=34883"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=34883"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}