{"id":17893,"date":"2009-06-15T10:00:00","date_gmt":"2009-06-15T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2009\/06\/15\/why-do-some-file-operations-take-file-names-and-others-take-handles\/"},"modified":"2009-06-15T10:00:00","modified_gmt":"2009-06-15T10:00:00","slug":"why-do-some-file-operations-take-file-names-and-others-take-handles","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20090615-00\/?p=17893","title":{"rendered":"Why do some file operations take file names and others take handles?"},"content":{"rendered":"<p><P>\nCommenter\n<A HREF=\"http:\/\/users.csc.calpoly.edu\/~bfriesen\/\">\nBrian Friesen<\/A>\nasks\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/pages\/407234.aspx#599058\">\nwhy some functions (like <CODE>SetFileAttributes<\/CODE>)\ntake a file name, while others\n(like <CODE>SetFileTime<\/CODE>) take a handle<\/A>\nand why we can&#8217;t have two versions of every API, one for each pattern.\n<\/P>\n<P>\nSecond question first:\nNo need to wait for the kernel folks to write such a function;\nyou can already do it yourself!\n<\/P>\n<PRE>\n\/\/ Following &#8220;pidgin Hungarian&#8221; naming convention, which appears\n\/\/ to be dominant in &lt;winbase.h&gt;&#8230;\nBOOL SetFileTimesByNameW(LPCWSTR lpFileName,\n                         CONST FILETIME *lpCreationTime,\n                         CONST FILETIME *lpLastAccessTime,\n                         CONST FILETIME *lpLastWriteTime)\n{\n  BOOL fRc = FALSE;\n  HANDLE hFile = CreateFileW(lpFileName,\n                             FILE_WRITE_ATTRIBUTES,\n                             FILE_SHARE_READ | FILE_SHARE_WRITE |\n                             FILE_SHARE_DELETE,\n                             NULL, OPEN_EXISTING,\n                             FILE_ATTRIBUTE_NORMAL, NULL);\n  if (hFile != INVALID_HANDLE_VALUE) {\n    fRc = SetFileTime(hFile, lpCreationTime, lpLastAccessTime,\n                      lpLastWriteTime);\n    CloseHandle(hFile);\n  }\n  return fRc;\n}\n<\/PRE>\n<P>\nActually,\nthere wouldn&#8217;t be two versions of every API but three:\n(1)&nbsp;handle-based,\n(2)&nbsp;ANSI,\n(3)&nbsp;Unicode.\n(Unless you decide to follow the lead of the NLS team and simply\n<A HREF=\"http:\/\/blogs.msdn.com\/michkap\/archive\/2006\/10\/24\/867880.aspx\">\nstop adding new ANSI interfaces<\/A>,\nin which case you&#8217;re back to two.)\n<\/P>\n<P>\nBack to the first question:\nWhy are there some functions that take file names and some\nfunctions that take handles?\nBecause that&#8217;s how MS-DOS did it back in 1983!\nThe function to get file attributes took a file name,\nbut the function to modify the file times took a handle.\nThis convention carried over to Windows because\nWindows preserved the old MS-DOS calling convention for\nperforming disk operations, even though by Windows for Workgroups\nwas released in 1992,\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2007\/12\/24\/6849530.aspx\">\nyou weren&#8217;t really talking to MS-DOS any more<\/A>.\nAll that was left was the interface.\n<\/P>\n<P>\nThe NT team rewrote the operating system from scratch,\nand under the NT model, practically nothing was done by name.\nNearly everything was done by handle.\nFor example,\nto delete a file,\nyou opened a handle to it and set the &#8220;delete on close&#8221; attribute,\nand then you closed the handle.\n<\/P>\n<P>\nOf course, when NT became <I>Windows<\/I>&nbsp;NT,\nthey had to adapt their interface to the old Windows way of doing\nthings,\nalthough (whisper)\nunder the covers, they just open the file and perform the operation on the\nhandle,\nlike our wrapper function above does.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Commenter Brian Friesen asks why some functions (like SetFileAttributes) take a file name, while others (like SetFileTime) take a handle and why we can&#8217;t have two versions of every API, one for each pattern. Second question first: No need to wait for the kernel folks to write such a function; you can already do it [&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-17893","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>Commenter Brian Friesen asks why some functions (like SetFileAttributes) take a file name, while others (like SetFileTime) take a handle and why we can&#8217;t have two versions of every API, one for each pattern. Second question first: No need to wait for the kernel folks to write such a function; you can already do it [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/17893","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=17893"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/17893\/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=17893"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=17893"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=17893"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}