internal IWbemServices GetIWbemServices() { // Lets start by assuming that we'll return the RCW that we already have IWbemServices localCopy = wbemServices; // Get an IUnknown for this apartment IntPtr pUnk = Marshal.GetIUnknownForObject(wbemServices); // Get an 'IUnknown RCW' for this apartment Object unknown = Marshal.GetObjectForIUnknown(pUnk); // Release the ref count on the IUnknwon Marshal.Release(pUnk); // See if we are in the same apartment as where the original IWbemServices lived // If we are in a different apartment, give the caller an RCW generated just for their // apartment, and set the proxy blanket appropriately if (!object.ReferenceEquals(unknown, wbemServices)) { // We need to set the proxy blanket on 'unknown' or else the QI for IWbemServices may // fail if we are running under a local user account. The QI has to be done by // someone who is a member of the 'Everyone' group on the target machine, or DCOM // won't let the call through. SecurityHandler securityHandler = GetSecurityHandler(); securityHandler.SecureIUnknown(unknown); // Now, we can QI and secure the IWbemServices localCopy = (IWbemServices)unknown; // We still need to bless the IWbemServices in this apartment securityHandler.Secure(localCopy); } return(localCopy); // STRANGE: Why does it still work if I return 'wbemServices'? }
internal IWbemServices GetIWbemServices() { IWbemServices wbemServices = this.wbemServices; IntPtr iUnknownForObject = Marshal.GetIUnknownForObject(this.wbemServices); object objectForIUnknown = Marshal.GetObjectForIUnknown(iUnknownForObject); Marshal.Release(iUnknownForObject); if (!object.ReferenceEquals(objectForIUnknown, this.wbemServices)) { SecurityHandler securityHandler = this.GetSecurityHandler(); securityHandler.SecureIUnknown(objectForIUnknown); wbemServices = (IWbemServices)objectForIUnknown; securityHandler.Secure(wbemServices); } return(wbemServices); }