{"id":3533,"date":"2013-08-12T07:00:00","date_gmt":"2013-08-12T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2013\/08\/12\/how-do-i-convert-a-synchronous-file-handle-into-an-asynchronous-one\/"},"modified":"2013-08-12T07:00:00","modified_gmt":"2013-08-12T07:00:00","slug":"how-do-i-convert-a-synchronous-file-handle-into-an-asynchronous-one","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130812-00\/?p=3533","title":{"rendered":"How do I convert a synchronous file handle into an asynchronous one?"},"content":{"rendered":"<p>\nSay you opened a file in synchronous mode,\nand then you realize that you want to issue asynchronous I\/O on it, too.\nOne way to do this is to call\n<code>Create&shy;File<\/code> a second time with the\n<code>FILE_FLAG_OVERLAPPED<\/code>,\nbut this requires you to know the file name,\nand the file name\nmay not be readily available to the function that\nwants to do the conversion,\nor it may not even be valid any longer if the file has\nbeen renamed in the meantime.\n<\/p>\n<p>\nEnter <code>Re&shy;Open&shy;File<\/code>.\nThis basically lets you do a <code>Create&shy;File<\/code>\nbased on another handle rather than a file name.\nIt differs from <code>Duplicate&shy;Handle<\/code> because\nit actually goes and opens the file again\n(as opposed to merely creating another reference to the same\nfile object in the kernel).\nThis means that you have the opportunity to choose new\nhandle attributes, like whether you want the handle\nto be synchronous or asynchronous.\n<\/p>\n<pre>\n#include &lt;windows.h&gt;\n#include &lt;stdio.h&gt;\nint __cdecl main(int, char **)\n{\n HANDLE h = CreateFile(\"test\", GENERIC_WRITE, FILE_SHARE_READ, NULL,\n                       CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);\n HANDLE h2 = ReOpenFile(h, GENERIC_READ, FILE_SHARE_READ |\n                        FILE_SHARE_WRITE, FILE_FLAG_OVERLAPPED);\n DWORD cbResult;\n WriteFile(h, \"!\", 1, &amp;cbResult, NULL);\n OVERLAPPED o = { 0 };\n o.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);\n char ch = 0;\n BOOL fRc = ReadFile(h2, &amp;ch, 1, &amp;cbResult, &amp;o);\n if (fRc) {\n  printf(\"read completed synchronously\\n\");\n } else if (GetLastError() == ERROR_IO_PENDING) {\n  printf(\"read proceeding asynchronously\\n\");\n } else {\n  printf(\"read failed\\n\");\n }\n GetOverlappedResult(h2, &amp;o, &amp;cbResult, TRUE);\n printf(\"Result was %c\\n\", ch);\n CloseHandle(o.hEvent);\n CloseHandle(h2);\n CloseHandle(h);\n return 0;\n}\n<\/pre>\n<p>\nThe program opens a test file for writing,\nand then uses the\n<code>Re&shy;Open&shy;File<\/code> function to open the same file\nfor reading.\n(Since you are opening the file twice,\nbe careful to choose compatible sharing modes.)\nWe synchronously write an exclamation point to the file via the first handle,\nand then we asynchronously read it back with the second handle.\n<\/p>\n<p>\nIt&#8217;s really not that exciting.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Say you opened a file in synchronous mode, and then you realize that you want to issue asynchronous I\/O on it, too. One way to do this is to call Create&shy;File a second time with the FILE_FLAG_OVERLAPPED, but this requires you to know the file name, and the file name may not be readily available [&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-3533","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Say you opened a file in synchronous mode, and then you realize that you want to issue asynchronous I\/O on it, too. One way to do this is to call Create&shy;File a second time with the FILE_FLAG_OVERLAPPED, but this requires you to know the file name, and the file name may not be readily available [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/3533","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=3533"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/3533\/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=3533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=3533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=3533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}