{"id":109634,"date":"2024-04-11T07:00:00","date_gmt":"2024-04-11T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=109634"},"modified":"2024-04-06T08:47:43","modified_gmt":"2024-04-06T15:47:43","slug":"20240411-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20240411-00\/?p=109634","title":{"rendered":"Why do <CODE>STANDARD_<WBR>RIGHTS_<WBR>READ<\/CODE>, <CODE>STANDARD_<WBR>RIGHTS_<WBR>WRITE<\/CODE>, and <CODE>STANDARD_<WBR>RIGHTS_<WBR>EXECUTE<\/CODE> have the same values?"},"content":{"rendered":"<p>Windows defines values for the access rights <code>STANDARD_<wbr \/>RIGHTS_<wbr \/>READ<\/code>, <code>STANDARD_<wbr \/>RIGHTS_<wbr \/>WRITE<\/code>, and <code>STANDARD_<wbr \/>RIGHTS_<wbr \/>EXECUTE<\/code>. But if you look at their definitions, they are all defined to be the same thing, namely, <code>READ_<wbr \/>CONTROL<\/code>. How can this possibly make sense? Certainly read, write, and execute rights should be different, shouldn&#8217;t they?<\/p>\n<p>They should, but that&#8217;s not what the <code>STANDARD_<wbr \/>RIGHTS_<wbr \/>*<\/code> values are for.<\/p>\n<p>What these values are trying to say is &#8220;Every securable object should include <code>STANDARD_<wbr \/>RIGHTS_<wbr \/>READ<\/code> in their generic read access mask, <code>STANDARD_<wbr \/>RIGHTS_<wbr \/>WRITE<\/code> in their generic write access mask, and <code>STANDARD_<wbr \/>RIGHTS_<wbr \/>EXECUTE<\/code> in their generic execute access mask.&#8221; Confusingly, <code>STANDARD_<wbr \/>RIGHTS_<wbr \/>ALL<\/code> is just a mask of all the standard rights, not the &#8220;mask that must be present in the generic all access mask.&#8221; It is <code>STANDARD_<wbr \/>RIGHTS_<wbr \/>REQUIRED<\/code> that you have to put in your generic all access mask.<\/p>\n<p>For example, the file access rights are defined as<\/p>\n<pre>#define FILE_GENERIC_READ         (STANDARD_RIGHTS_READ     |\\\r\n                                   FILE_READ_DATA           |\\\r\n                                   FILE_READ_ATTRIBUTES     |\\\r\n                                   FILE_READ_EA             |\\\r\n                                   SYNCHRONIZE)\r\n\r\n\r\n#define FILE_GENERIC_WRITE        (STANDARD_RIGHTS_WRITE    |\\\r\n                                   FILE_WRITE_DATA          |\\\r\n                                   FILE_WRITE_ATTRIBUTES    |\\\r\n                                   FILE_WRITE_EA            |\\\r\n                                   FILE_APPEND_DATA         |\\\r\n                                   SYNCHRONIZE)\r\n\r\n\r\n#define FILE_GENERIC_EXECUTE      (STANDARD_RIGHTS_EXECUTE  |\\\r\n                                   FILE_READ_ATTRIBUTES     |\\\r\n                                   FILE_EXECUTE             |\\\r\n                                   SYNCHRONIZE)\r\n\r\n#define FILE_ALL_ACCESS           (STANDARD_RIGHTS_REQUIRED |\\\r\n                                   SYNCHRONIZE              |\\\r\n                                   0x1FF)\r\n\r\nconst GENERIC_MAPPING FileGenericMapping =\r\n{\r\n    FILE_GENERIC_READ,\r\n    FILE_GENERIC_WRITE,\r\n    FILE_GENERIC_EXECUTE,\r\n    FILE_ALL_ACCESS,\r\n};\r\n<\/pre>\n<p>The &#8220;generic read&#8221; file access includes <code>STANDARD_<wbr \/>RIGHTS_<wbr \/>READ<\/code>, plus any other read rights specific to files. Similarly for &#8220;write&#8221;, &#8220;execute&#8221;, and &#8220;all&#8221; access.<\/p>\n<p>Now, it so happens that the only mandatory access right for read, write, and execute is <code>READ_<wbr \/>CONTROL<\/code>, so that&#8217;s why all three of the macros expand to the same underlying value.<\/p>\n<p>But you weren&#8217;t supposed to care about that. Just include the corresponding standard rights in each of the four levels of access, and you&#8217;re all set.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Don&#8217;t they mean different things?<\/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-109634","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Don&#8217;t they mean different things?<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/109634","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=109634"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/109634\/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=109634"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=109634"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=109634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}