{"id":110112,"date":"2024-08-08T07:00:00","date_gmt":"2024-08-08T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=110112"},"modified":"2024-08-08T09:22:22","modified_gmt":"2024-08-08T16:22:22","slug":"20240808-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20240808-00\/?p=110112","title":{"rendered":"Why do I get <CODE>E_<WBR>ACCESS&shy;DENIED<\/CODE> when trying to access my brokered Windows Runtime object?COM is double-checking the trust level."},"content":{"rendered":"<p>A customer implemented a Windows Runtime object but found that it didn&#8217;t work from the UWP app container, so they changed it from an in-process server to a brokered server by manifesting it as Partial\u00adTrust. They double-checked the registration by calling <code>Ro\u00adGet\u00adActivatable\u00adClass\u00adRegistration<\/code> and then asking for the <code>Registered\u00adTrust\u00adLevel<\/code>, and it did indeed report as <code>Partial\u00adTrust<\/code>, yet when they tried to create the object, they code <code>E_<wbr \/>ACCESS\u00adDENIED<\/code>. What is going on?<\/p>\n<p>COM is being cautious and watching out for people trying sneaky tricks in order to activate an object with the wrong trust level. When it obtains the activation factory or an object from that factory, it asks the factory or object for its <code>Trust\u00adLevel<\/code> directly, and if the answer disagrees with the manifest, then COM assumes that somebody is trying to pull a fast one, and it says, &#8220;The manifest declares one trust level, but when I ask the object, it claims to be a different trust level. I get a bad feeling from this, so I&#8217;m not going to let this one go through.&#8221;<\/p>\n<p>In this case, what this means is that when you converted your object from Base\u00adTrust to Partial\u00adTrust, you forgot to update the <code>GetTrustLevel()<\/code> method to return <code>Partial\u00adTrust<\/code>.<\/p>\n<p>If you implemented your object and object factory in C++\/WinRT, you need to override the default reported trust level of <code>Base\u00adTrust<\/code> with a custom trust level:<\/p>\n<pre>namespace winrt::Contoso::implementation\r\n{\r\n    struct Widget : WidgetT&lt;Widget&gt;\r\n    {\r\n        <span style=\"border: solid 1px currentcolor;\">auto GetTrustLevel() { return TrustLevel::PartialTrust; }<\/span>\r\n\r\n        \u27e6 remainder of class \u27e7\r\n    };\r\n}\r\n\r\nnamespace winrt::Contoso::factory_implementation\r\n{\r\n    struct Widget : WidgetT&lt;Widget&gt;\r\n    {\r\n        <span style=\"border: solid 1px currentcolor;\">auto GetTrustLevel() { return TrustLevel::PartialTrust; }<\/span>\r\n\r\n        \u27e6 remainder of class \u27e7\r\n    };\r\n}\r\n<\/pre>\n<p>If you implemented your objects in C++\/WRL, then you report your trust level in the <code>Inspectable\u00adClass<\/code> macro of your object type.<\/p>\n<pre>class Widget : public Microsoft::WRL::RuntimeClass&lt;\u27e6 whatever \u27e7&gt;\r\n{\r\n    InspectableClass(RuntimeClass_Contoso_Widget, <span style=\"border: solid 1px currentcolor;\">PartialTrust<\/span>);\r\n\r\n    \u27e6 remainder of class \u27e7\r\n};\r\n<\/pre>\n<p>The factory trust level takes its cue from the object trust level, so you don&#8217;t have to make any explicit changes to the factory.<\/p>\n<p>If you have a static class (so there are no objects from which the factory class can infer its trust level), you put the trust level in the second parameter to your existing <code>Inspectable\u00adClass\u00adStatic<\/code> macro:<\/p>\n<pre>class WidgetFactory : public Microsoft::WRL::AgileActivationFactory&lt;\u27e6 whatever \u27e7&gt;\r\n{\r\n    InspectableClassStatic(RuntimeClass_Contoso_Widget, <span style=\"border: solid 1px currentcolor;\">PartialTrust<\/span>);\r\n\r\n    \u27e6 remainder of class \u27e7\r\n};\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>COM is double-checking the trust level.<\/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-110112","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>COM is double-checking the trust level.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110112","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=110112"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110112\/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=110112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=110112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=110112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}