{"id":35403,"date":"2005-06-07T11:03:34","date_gmt":"2005-06-07T11:03:34","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/06\/07\/answer-to-quick-puzzle-about-security-and-synchronization\/"},"modified":"2005-06-07T11:03:34","modified_gmt":"2005-06-07T11:03:34","slug":"answer-to-quick-puzzle-about-security-and-synchronization","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050607-34\/?p=35403","title":{"rendered":"Answer to quick puzzle about security and synchronization"},"content":{"rendered":"<p>\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/06\/06\/425611.aspx\">\nAs many people quickly figured out<\/a>, the reason why the\nthe <code>WaitForSingleObject<\/code> returns immediately\nis that the call is failing.\nThe reason is that the second process opened the handle\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dllproc\/base\/synchronization_object_security_and_access_rights.asp\">\nwith <code>EVENT_MODIFY_STATE<\/code> access<\/a>,\nwhich\ngrants permission to call\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dllproc\/base\/setevent.asp\">\nthe <code>SetEvent<\/code> function<\/a>,\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dllproc\/base\/resetevent.asp\">\nthe <code>ResetEvent<\/code> function<\/a>,\nand\n<a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/01\/05\/346888.aspx\">\nthe fatally flawed <code>PulseEvent<\/code> function<\/a>,\nbut it doesn&#8217;t include\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/secauthz\/security\/standard_access_rights.asp\">\n<code>SYNCHRONIZE<\/code> access<\/a>,\nwhich is necessary if you intend to synchronize on the object\n(<i>i.e.<\/i>, wait on it).\n<\/p>\n<p>\nThe fix is for Process&nbsp;B to ask for\n<code>SYNCHRONIZE<\/code> access instead of\n<code>EVENT_MODIFY_STATE<\/code>.\n<\/p>\n<p>\nThe fact that it&#8217;s happening in a second process is a red herring.\nYou can put this code in the same process and it will fail\/succeed\nin the same way:\n<\/p>\n<pre>\nHANDLE hEventA = CreateEvent(NULL, FALSE, TRUE, TEXT(\"MyNamedEvent\"));\nHANDLE hEventB = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT(\"MyNamedEvent\"));\nWaitForSingleObject(hEventB, INFINITE); \/\/ fails\n<\/pre>\n<p>\nIndeed, the fact that the object is named is a red herring.\nIt has nothing to do with named\/unnamed objects.\n<\/p>\n<pre>\nHANDLE hEventA = CreateEvent(NULL, FALSE, TRUE, NULL);\nHANDLE hEventB;\nDuplicateHandle(GetCurrentProcess(), hEventA,\n                GetCurrentProcess(), &amp;hEventB,\n                EVENT_MODIFY_STATE, FALSE, 0);\nWaitForSingleObject(hEventB, INFINITE); \/\/ fails\n<\/pre>\n<p>\nIn all three cases, the fix is to change\n<code>EVENT_MODIFY_STATE<\/code> to <code>SYNCHRONIZE<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As many people quickly figured out, the reason why the the WaitForSingleObject returns immediately is that the call is failing. The reason is that the second process opened the handle with EVENT_MODIFY_STATE access, which grants permission to call the SetEvent function, the ResetEvent function, and the fatally flawed PulseEvent function, but it doesn&#8217;t include SYNCHRONIZE [&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-35403","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>As many people quickly figured out, the reason why the the WaitForSingleObject returns immediately is that the call is failing. The reason is that the second process opened the handle with EVENT_MODIFY_STATE access, which grants permission to call the SetEvent function, the ResetEvent function, and the fatally flawed PulseEvent function, but it doesn&#8217;t include SYNCHRONIZE [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/35403","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=35403"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/35403\/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=35403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=35403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=35403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}