RemoteWebConfigurationHost.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / Configuration / RemoteWebConfigurationHost.cs / 1305376 / RemoteWebConfigurationHost.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.Configuration { 
    using System.Collections; 
    using System.Configuration;
    using System.Configuration.Internal; 
    using System.Web;
    using System.Web.Util;
    using System.Security;
    using System.IO; 
    using System.Web.Hosting;
    using System.Runtime.InteropServices; 
    using System.Reflection; 
    using System.Collections.Specialized;
    using System.Xml; 
    using System.Security.Principal;
    using System.Threading;
    using System.Globalization;
    using System.Security.Permissions; 

    [SecurityPermission(SecurityAction.Demand, Unrestricted = true)] 
    internal sealed class RemoteWebConfigurationHost : DelegatingConfigHost 
    {
        private const string        KEY_MACHINE = "MACHINE"; 

        private static object       s_version = new object();

        private string              _Server; 
        private string              _Username;
        private string              _Domain; 
        private string              _Password; 
        private WindowsIdentity     _Identity;
 
        private Hashtable           _PathMap;   // configPath -> configFile
        private string              _ConfigPath;

        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        internal RemoteWebConfigurationHost() {} 
 
        public override void Init(IInternalConfigRoot configRoot, params object[] hostInitParams) {
            throw ExceptionUtil.UnexpectedError("RemoteWebConfigurationHost::Init"); 
        }

        public override void InitForConfiguration(ref string locationSubPath, out string configPath, out string locationConfigPath,
                        IInternalConfigRoot root, params object[] hostInitConfigurationParams) { 

 
            WebLevel                webLevel = (WebLevel)               hostInitConfigurationParams[0]; 
            // ConfigurationFileMap    fileMap = (ConfigurationFileMap)    hostInitConfigurationParams[1];
            string                  path = (string)                     hostInitConfigurationParams[2]; 
            string                  site = (string)                     hostInitConfigurationParams[3];

            if (locationSubPath == null) {
                locationSubPath = (string)                              hostInitConfigurationParams[4]; 
            }
 
            string                  server = (string)                   hostInitConfigurationParams[5]; 
            string                  userName = (string)                 hostInitConfigurationParams[6];
            string                  password = (string)                 hostInitConfigurationParams[7]; 
            IntPtr                  tokenHandle = (IntPtr)              hostInitConfigurationParams[8];

            configPath = null;
            locationConfigPath = null; 

            _Server = server; 
            _Username = GetUserNameFromFullName(userName); 
            _Domain = GetDomainFromFullName(userName);
            _Password = password; 
            _Identity = (tokenHandle == IntPtr.Zero) ? null : new WindowsIdentity(tokenHandle); //CreateWindowsIdentity(username, domain, password, tokenHandle);

            _PathMap = new Hashtable(StringComparer.OrdinalIgnoreCase);
 
#if !FEATURE_PAL // FEATURE_PAL does not have WindowsImpersonationContext, COM objects
            // 
            // Send the path arguments to the server for parsing, 
            // and retreive the normalized paths and path mapping
            // from config paths to file paths. 
            //
            string filePaths;
            try {
                WindowsImpersonationContext wiContext = (_Identity != null) ? _Identity.Impersonate() : null; 
                try {
                    IRemoteWebConfigurationHostServer remoteSrv = RemoteWebConfigurationHost.CreateRemoteObject(server, _Username, _Domain, password); //(IRemoteWebConfigurationHostServer) Activator.CreateInstance(type); 
                    try { 
                        filePaths = remoteSrv.GetFilePaths((int) webLevel, path, site, locationSubPath);
                    } finally { 
                        // Release COM objects
                        while (Marshal.ReleaseComObject(remoteSrv) > 0) {
                        }
                    } 
                } finally {
                    if (wiContext != null) 
                        wiContext.Undo(); 
                }
            } 
            catch {
                // Wrap finally clause with a try to avoid exception clauses being run
                // while the thread is impersonated.
                throw; 
            }
 
            if (filePaths == null) { 
                throw ExceptionUtil.UnexpectedError("RemoteWebConfigurationHost::InitForConfiguration");
            } 

            //
            // Format of filePaths:
            //      appPath < appSiteName < appSiteID < configPath < locationConfigPath [< configPath < fileName]+ 
            //
            string[] parts = filePaths.Split(RemoteWebConfigurationHostServer.FilePathsSeparatorParams); 
 
            if (parts.Length < 7 || (parts.Length - 5) % 2 != 0) {
                throw ExceptionUtil.UnexpectedError("RemoteWebConfigurationHost::InitForConfiguration"); 
            }

            // convert empty strings to nulls
            for (int i = 0; i < parts.Length; i++) { 
                if (parts[i].Length == 0) {
                    parts[i] = null; 
                } 
            }
 
            // get config paths
            string appPath = parts[0];
            string appSiteName = parts[1];
            string appSiteID = parts[2]; 
            configPath = parts[3];
            locationConfigPath = parts[4]; 
            _ConfigPath = configPath; 

            // Create a WebConfigurationFileMap to be used when we later initialize our delegating WebConfigurationHost 
            WebConfigurationFileMap configFileMap = new WebConfigurationFileMap();
            VirtualPath             appPathVirtualPath = VirtualPath.CreateAbsoluteAllowNull(appPath);

            configFileMap.Site = appSiteID; 

            // populate the configpath->physical path mapping 
            for (int i = 5; i < parts.Length; i += 2) { 
                string      configPathTemp = parts[i];
                string      physicalFilePath = parts[i+1]; 

                _PathMap.Add(configPathTemp, physicalFilePath);

                // Update the WebConfigurationFileMap 
                if (WebConfigurationHost.IsMachineConfigPath(configPathTemp)) {
                    configFileMap.MachineConfigFilename = physicalFilePath; 
                } 
                else {
                    string      vPathString; 
                    bool        isRootApp;

                    if (WebConfigurationHost.IsRootWebConfigPath(configPathTemp)) {
                        vPathString = null; 
                        isRootApp = false;
                    } 
                    else { 
                        VirtualPath vPath;
                        string      dummy; 

                        WebConfigurationHost.GetSiteIDAndVPathFromConfigPath(configPathTemp, out dummy, out vPath);
                        vPathString = VirtualPath.GetVirtualPathString(vPath);
                        isRootApp = (vPath == appPathVirtualPath); 
                    }
 
                    configFileMap.VirtualDirectories.Add(vPathString, 
                        new VirtualDirectoryMapping(Path.GetDirectoryName(physicalFilePath), isRootApp));
                } 
            }

#else // !FEATURE_PAL: set dummy config path
            string appPath = null; 
            _ConfigPath = configPath;
#endif // !FEATURE_PAL 
 
            // Delegate to a WebConfigurationHost for unhandled methods.
            WebConfigurationHost webConfigurationHost = new WebConfigurationHost(); 
            webConfigurationHost.Init(root, true, new UserMapPath(configFileMap, /*pathsAreLocal*/ false), null, appPath, appSiteName, appSiteID);
            Host = webConfigurationHost;
        }
 
        // config path support
        public override bool IsConfigRecordRequired(string configPath) { 
            // a record is required for every part of the config path 
            return configPath.Length <= _ConfigPath.Length;
        } 

        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        public override string GetStreamName(string configPath) 
        {
            return (string) _PathMap[configPath]; 
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        public override object GetStreamVersion(string streamName) {
#if FEATURE_PAL // FEATURE_PAL: singelton version
 	return s_version; 
#else
            // for now, assume it is the same 
            // return s_version; 
            bool exists;
            long size, createDate, lastWriteDate; 
            WindowsImpersonationContext wiContext = null;

            try {
                if (_Identity != null) { 
                    wiContext = _Identity.Impersonate();
                } 
 
                try {
                    ////////////////////////////////////////////////////////////////// 
                    // Step 3: Get the type and create the object on the remote server
                    IRemoteWebConfigurationHostServer remoteSrv = CreateRemoteObject(_Server, _Username, _Domain, _Password);
                    try {
                        ////////////////////////////////////////////////////////////////// 
                        // Step 4: Call the API
                        remoteSrv.GetFileDetails(streamName, out exists, out size, out createDate, out lastWriteDate); 
                    } 
                    finally {
                        while (Marshal.ReleaseComObject(remoteSrv) > 0) { } // release the COM object 
                    }
                }
                finally {
                    if (wiContext != null) { 
                        wiContext.Undo(); // revert impersonation
                    } 
                } 
            }
            catch { 
                // Wrap finally clause with a try to avoid exception clauses being run
                // while the thread is impersonated.
                throw;
            } 

            return new FileDetails(exists, size, DateTime.FromFileTimeUtc(createDate), DateTime.FromFileTimeUtc(lastWriteDate)); 
#endif // FEATURE_PAL 
        }
 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        public override Stream OpenStreamForRead(string streamName) {
            RemoteWebConfigurationHostStream rcs = new RemoteWebConfigurationHostStream(false, _Server, streamName, null, _Username, _Domain, _Password, _Identity); 
            if (rcs == null || rcs.Length < 1)
                return null; 
            return rcs; 
        }
 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        public override Stream OpenStreamForWrite(string streamName, string templateStreamName, ref object writeContext) {
            RemoteWebConfigurationHostStream rcs = new RemoteWebConfigurationHostStream(true, _Server, streamName, templateStreamName, _Username, _Domain, _Password, _Identity); 
            writeContext = rcs;
            return rcs; 
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        public override void DeleteStream(string StreamName)
        {
            // 
        }
 
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        public override void WriteCompleted(string streamName, bool success, object writeContext) 
        {
            if (success) {
                RemoteWebConfigurationHostStream rcs = (RemoteWebConfigurationHostStream)writeContext;
                rcs.FlushForWriteCompleted(); 
            }
        } 
 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        public override bool IsFile(string StreamName)
        {
            return false;
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////////// 
        public override bool PrefetchAll(string configPath, string StreamName)
        { 
            return true;
        }

        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        public override bool PrefetchSection(string sectionGroupName, string sectionName) 
        { 
            return true;
        } 

        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        public override void GetRestrictedPermissions(IInternalConfigRecord configRecord, out PermissionSet permissionSet, out bool isHostReady) { 
            WebConfigurationHost.StaticGetRestrictedPermissions(configRecord, out permissionSet, out isHostReady);
        } 
 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        public override bool IsRemote {
            get { return true; }
        }
 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        // Encrypt/decrypt support 
        public override string DecryptSection(string encryptedXmlString, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedConfigSection) {
            return CallEncryptOrDecrypt(false, encryptedXmlString, protectionProvider, protectedConfigSection); 
        }
        public override string EncryptSection(string clearTextXmlString, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedConfigSection) {
            return CallEncryptOrDecrypt(true, clearTextXmlString, protectionProvider, protectedConfigSection);
        } 

        private string CallEncryptOrDecrypt(bool doEncrypt, string xmlString, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedConfigSection) 
        { 
#if !FEATURE_PAL // FEATURE_PAL has no COM objects => no encryption
            // ROTORTODO: COM Objects are not implemented. 
            // CORIOLISTODO: COM Objects are not implemented.
            ProviderSettings                   ps;
            NameValueCollection                nvc;
            string  []                         paramKeys; 
            string  []                         paramValues;
            string                             returnString = null; 
            string                             typeName; 
            WindowsImpersonationContext        wiContext = null;
 
            ////////////////////////////////////////////////////////////
            // Step 1: Create list of parameters for the protection provider
            typeName = protectionProvider.GetType().AssemblyQualifiedName;
            ps = protectedConfigSection.Providers[protectionProvider.Name]; 
            if (ps == null)
                throw ExceptionUtil.ParameterInvalid("protectionProvider"); 
 
            nvc = ps.Parameters;
            if (nvc == null) 
                nvc = new NameValueCollection();

            paramKeys = nvc.AllKeys;
            paramValues = new string[paramKeys.Length]; 
            for(int iter = 0; iter 0) { } // release the COM object
                    } 
                } finally { 
                    if (wiContext != null)
                        wiContext.Undo(); // revert impersonation 
                }
            }
            catch {
            } 

            return returnString; 
#else       // !FEATURE_PAL 
            throw new NotImplementedException("ROTORTODO");
#endif      // !FEATURE_PAL 
        }

        ///////////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////////// 
        private static string GetUserNameFromFullName(string fullUserName) {
            if (string.IsNullOrEmpty(fullUserName)) 
                return null; 
            if (fullUserName.Contains("@")) {
                return fullUserName; 
            }
            string[] splitted = fullUserName.Split(new char[] { '\\' });
            if (splitted.Length == 1)
                return fullUserName; 
            else
                return splitted[1]; 
        } 
        private static string GetDomainFromFullName(string fullUserName) {
            if (string.IsNullOrEmpty(fullUserName)) 
                return null;
            if (fullUserName.Contains("@"))
                return null;
            string[] splitted = fullUserName.Split(new char[] { '\\' }); 
            if (splitted.Length == 1)
                return "."; 
            return splitted[0]; 
        }
 
        // impersonation support: create an identity from credentials
#if OLD_WAY
        private static WindowsIdentity CreateWindowsIdentity(string userName, string password, IntPtr tokenHandle) {
 
            //////////////////////////////////////////////////////////////////
            // Step 0: Most common case: check if no credentials are supplied 
            if (string.IsNullOrEmpty(userName) && tokenHandle == IntPtr.Zero && string.IsNullOrEmpty(password)) 
                return null;
 
            //////////////////////////////////////////////////////////////////
            // Step 1: Make sure that either username & password OR token is supplied
            if ((string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password)) || (!string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(password)))
                throw ExceptionUtil.ParameterNullOrEmpty("password"); 

            if (!string.IsNullOrEmpty(userName) && tokenHandle != IntPtr.Zero) 
                throw ExceptionUtil.ParameterInvalid("tokenHandle"); 

            ////////////////////////////////////////////////////////////////// 
            // Step 2: Create token if not supplied
            if (!string.IsNullOrEmpty(userName))
                tokenHandle = CreateUserToken(userName, password);
 
            //////////////////////////////////////////////////////////////////
            // Step 3: Create a windows identity from the token 
            WindowsIdentity wi = new WindowsIdentity(tokenHandle); 

            if (!string.IsNullOrEmpty(userName) && tokenHandle != IntPtr.Zero) // Close the handle if we created it. 
                UnsafeNativeMethods.CloseHandle(tokenHandle);
            return wi;
        }
 
        private static IntPtr CreateUserToken(string fullUserName, string password) {
            string userName, domain; 
            if (fullUserName.Contains("@")) { 
                userName = fullUserName;
                domain = null; 
            } else {
                string[] splitted = fullUserName.Split(new char[] { '\\' });
                if (splitted.Length == 1) {
                    userName = fullUserName; 
                    domain = ".";
                } else { 
                    userName = splitted[1]; 
                    domain = splitted[0];
                } 
            }
            //This parameter causes LogonUser to create a primary token.
            const int LOGON32_PROVIDER_DEFAULT        = 0;
            const int LOGON32_LOGON_INTERACTIVE       = 2; 
            const int LOGON32_LOGON_NETWORK           = 3;
            const int LOGON32_LOGON_BATCH             = 4; 
            const int LOGON32_LOGON_SERVICE           = 5; 
            const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
 
            int[] Logon32Values = new int[] { LOGON32_LOGON_INTERACTIVE, LOGON32_LOGON_BATCH, LOGON32_LOGON_SERVICE, LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_LOGON_NETWORK};

            IntPtr tokenHandle = IntPtr.Zero;
            int lastError = 0; 
            if (UnsafeNativeMethods.LogonUser(userName, domain, password, Logon32Values[0], LOGON32_PROVIDER_DEFAULT, ref tokenHandle) != 0)
                return tokenHandle; 
            lastError = Marshal.GetHRForLastWin32Error(); 
            for (int iter = 1; iter < Logon32Values.Length; iter++)
                if (UnsafeNativeMethods.LogonUser(userName, domain, password, Logon32Values[iter], LOGON32_PROVIDER_DEFAULT, ref tokenHandle) != 0) 
                    return tokenHandle;
            Marshal.ThrowExceptionForHR(lastError);
            return IntPtr.Zero;
        } 
#endif
        internal static IRemoteWebConfigurationHostServer CreateRemoteObject(string server, string username, string domain, string password) { 
 
#if !FEATURE_PAL // FEATURE_PAL has no COM objects
            try { 
                if (string.IsNullOrEmpty(username))
                    return CreateRemoteObjectUsingGetTypeFromCLSID(server);
                if (IntPtr.Size == 8)
                    return CreateRemoteObjectOn64BitPlatform(server, username, domain, password); 
                return CreateRemoteObjectOn32BitPlatform(server, username, domain, password);
            } catch (COMException ex) { 
                if ((uint)ex.ErrorCode == 0x80040154) 
                    throw new Exception(SR.GetString(SR.Make_sure_remote_server_is_enabled_for_config_access));
                throw; 
            }
        }
        private static IRemoteWebConfigurationHostServer CreateRemoteObjectUsingGetTypeFromCLSID(string server) {
            Type type = Type.GetTypeFromCLSID(typeof(RemoteWebConfigurationHostServer).GUID, server, true); 
            return (IRemoteWebConfigurationHostServer)Activator.CreateInstance(type);
        } 
 
        private static IRemoteWebConfigurationHostServer CreateRemoteObjectOn32BitPlatform(string server, string username, string domain, string password)
        { 
            MULTI_QI []     amqi            = new MULTI_QI[1];
            IntPtr          guidbuf         = IntPtr.Zero;
            COAUTHINFO      ca              = null;
            IntPtr          captr           = IntPtr.Zero; 
            COSERVERINFO    cs              = null;
            Guid            clsid           = typeof(RemoteWebConfigurationHostServer).GUID; 
            int             hr              = 0; 
            COAUTHIDENTITY  ci              = null;
            IntPtr          ciptr           = IntPtr.Zero; 

            try {
                guidbuf = Marshal.AllocCoTaskMem(16);
                Marshal.StructureToPtr(typeof(IRemoteWebConfigurationHostServer).GUID, guidbuf, false); 
                amqi[0] = new MULTI_QI(guidbuf);
 
                ci = new COAUTHIDENTITY(username, domain, password); 
                ciptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(ci));
                Marshal.StructureToPtr(ci, ciptr, false); 

                ca = new COAUTHINFO(RpcAuthent.WinNT, RpcAuthor.None, null, /*RpcLevel.Connect*/ RpcLevel.Default, RpcImpers.Impersonate, ciptr);
                captr = Marshal.AllocCoTaskMem(Marshal.SizeOf(ca));
                Marshal.StructureToPtr(ca, captr, false); 

                cs = new COSERVERINFO(server, captr); 
                hr = UnsafeNativeMethods.CoCreateInstanceEx(ref clsid, IntPtr.Zero, (int)ClsCtx.RemoteServer, cs, 1, amqi); 
                if ((uint)hr == 0x80040154)
                        throw new Exception(SR.GetString(SR.Make_sure_remote_server_is_enabled_for_config_access)); 
                if (hr < 0)
                    Marshal.ThrowExceptionForHR(hr);
                if (amqi[0].hr < 0)
                    Marshal.ThrowExceptionForHR(amqi[0].hr); 
                hr = UnsafeNativeMethods.CoSetProxyBlanket(amqi[0].pItf, RpcAuthent.WinNT, RpcAuthor.None, null, /*RpcLevel.Connect*/ RpcLevel.Default, RpcImpers.Impersonate, ciptr, 0);
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr); 
                return (IRemoteWebConfigurationHostServer)Marshal.GetObjectForIUnknown(amqi[0].pItf);
            } finally { 
                if (amqi[0].pItf != IntPtr.Zero)
                {
                    Marshal.Release(amqi[0].pItf);
                    amqi[0].pItf = IntPtr.Zero; 
                }
                amqi[0].piid = IntPtr.Zero; 
                if (captr != IntPtr.Zero) { 
                    Marshal.DestroyStructure(captr, typeof(COAUTHINFO));
                    Marshal.FreeCoTaskMem(captr); 
                }
                if (ciptr != IntPtr.Zero) {
                    Marshal.DestroyStructure(ciptr, typeof(COAUTHIDENTITY));
                    Marshal.FreeCoTaskMem(ciptr); 
                }
                if (guidbuf != IntPtr.Zero) 
                    Marshal.FreeCoTaskMem(guidbuf); 
            }
#else // !FEATURE_PAL 
            throw new NotSupportedException();
#endif // !FEATURE_PAL
        }
 
        private static IRemoteWebConfigurationHostServer CreateRemoteObjectOn64BitPlatform(string server, string username, string domain, string password)
        { 
            MULTI_QI_X64[]      amqi            = new MULTI_QI_X64[1]; 
            IntPtr              guidbuf         = IntPtr.Zero;
            COAUTHINFO_X64      ca              = null; 
            IntPtr              captr           = IntPtr.Zero;
            COSERVERINFO_X64    cs              = null;
            Guid                clsid           = typeof(RemoteWebConfigurationHostServer).GUID;
            int                 hr              = 0; 
            COAUTHIDENTITY_X64  ci              = null;
            IntPtr              ciptr           = IntPtr.Zero; 
 
            try {
                guidbuf = Marshal.AllocCoTaskMem(16); 
                Marshal.StructureToPtr(typeof(IRemoteWebConfigurationHostServer).GUID, guidbuf, false);
                amqi[0] = new MULTI_QI_X64(guidbuf);

                ci = new COAUTHIDENTITY_X64(username, domain, password); 
                ciptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(ci));
                Marshal.StructureToPtr(ci, ciptr, false); 
 
                ca = new COAUTHINFO_X64(RpcAuthent.WinNT, RpcAuthor.None, null, /*RpcLevel.Connect*/ RpcLevel.Default, RpcImpers.Impersonate, ciptr);
                captr = Marshal.AllocCoTaskMem(Marshal.SizeOf(ca)); 
                Marshal.StructureToPtr(ca, captr, false);

                cs = new COSERVERINFO_X64(server, captr);
                hr = UnsafeNativeMethods.CoCreateInstanceEx(ref clsid, IntPtr.Zero, (int)ClsCtx.RemoteServer, cs, 1, amqi); 
                if ((uint)hr == 0x80040154)
                    throw new Exception(SR.GetString(SR.Make_sure_remote_server_is_enabled_for_config_access)); 
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr);
                if (amqi[0].hr < 0) 
                    Marshal.ThrowExceptionForHR(amqi[0].hr);
                hr = UnsafeNativeMethods.CoSetProxyBlanket(amqi[0].pItf, RpcAuthent.WinNT, RpcAuthor.None, null, /*RpcLevel.Connect*/ RpcLevel.Default, RpcImpers.Impersonate, ciptr, 0);
                if (hr < 0)
                    Marshal.ThrowExceptionForHR(hr); 
                return (IRemoteWebConfigurationHostServer)Marshal.GetObjectForIUnknown(amqi[0].pItf);
            } finally { 
                if (amqi[0].pItf != IntPtr.Zero) { 
                    Marshal.Release(amqi[0].pItf);
                    amqi[0].pItf = IntPtr.Zero; 
                }
                amqi[0].piid = IntPtr.Zero;
                if (captr != IntPtr.Zero) {
                    Marshal.DestroyStructure(captr, typeof(COAUTHINFO_X64)); 
                    Marshal.FreeCoTaskMem(captr);
                } 
                if (ciptr != IntPtr.Zero) { 
                    Marshal.DestroyStructure(ciptr, typeof(COAUTHIDENTITY_X64));
                    Marshal.FreeCoTaskMem(ciptr); 
                }
                if (guidbuf != IntPtr.Zero)
                    Marshal.FreeCoTaskMem(guidbuf);
            } 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.Configuration { 
    using System.Collections; 
    using System.Configuration;
    using System.Configuration.Internal; 
    using System.Web;
    using System.Web.Util;
    using System.Security;
    using System.IO; 
    using System.Web.Hosting;
    using System.Runtime.InteropServices; 
    using System.Reflection; 
    using System.Collections.Specialized;
    using System.Xml; 
    using System.Security.Principal;
    using System.Threading;
    using System.Globalization;
    using System.Security.Permissions; 

    [SecurityPermission(SecurityAction.Demand, Unrestricted = true)] 
    internal sealed class RemoteWebConfigurationHost : DelegatingConfigHost 
    {
        private const string        KEY_MACHINE = "MACHINE"; 

        private static object       s_version = new object();

        private string              _Server; 
        private string              _Username;
        private string              _Domain; 
        private string              _Password; 
        private WindowsIdentity     _Identity;
 
        private Hashtable           _PathMap;   // configPath -> configFile
        private string              _ConfigPath;

        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        internal RemoteWebConfigurationHost() {} 
 
        public override void Init(IInternalConfigRoot configRoot, params object[] hostInitParams) {
            throw ExceptionUtil.UnexpectedError("RemoteWebConfigurationHost::Init"); 
        }

        public override void InitForConfiguration(ref string locationSubPath, out string configPath, out string locationConfigPath,
                        IInternalConfigRoot root, params object[] hostInitConfigurationParams) { 

 
            WebLevel                webLevel = (WebLevel)               hostInitConfigurationParams[0]; 
            // ConfigurationFileMap    fileMap = (ConfigurationFileMap)    hostInitConfigurationParams[1];
            string                  path = (string)                     hostInitConfigurationParams[2]; 
            string                  site = (string)                     hostInitConfigurationParams[3];

            if (locationSubPath == null) {
                locationSubPath = (string)                              hostInitConfigurationParams[4]; 
            }
 
            string                  server = (string)                   hostInitConfigurationParams[5]; 
            string                  userName = (string)                 hostInitConfigurationParams[6];
            string                  password = (string)                 hostInitConfigurationParams[7]; 
            IntPtr                  tokenHandle = (IntPtr)              hostInitConfigurationParams[8];

            configPath = null;
            locationConfigPath = null; 

            _Server = server; 
            _Username = GetUserNameFromFullName(userName); 
            _Domain = GetDomainFromFullName(userName);
            _Password = password; 
            _Identity = (tokenHandle == IntPtr.Zero) ? null : new WindowsIdentity(tokenHandle); //CreateWindowsIdentity(username, domain, password, tokenHandle);

            _PathMap = new Hashtable(StringComparer.OrdinalIgnoreCase);
 
#if !FEATURE_PAL // FEATURE_PAL does not have WindowsImpersonationContext, COM objects
            // 
            // Send the path arguments to the server for parsing, 
            // and retreive the normalized paths and path mapping
            // from config paths to file paths. 
            //
            string filePaths;
            try {
                WindowsImpersonationContext wiContext = (_Identity != null) ? _Identity.Impersonate() : null; 
                try {
                    IRemoteWebConfigurationHostServer remoteSrv = RemoteWebConfigurationHost.CreateRemoteObject(server, _Username, _Domain, password); //(IRemoteWebConfigurationHostServer) Activator.CreateInstance(type); 
                    try { 
                        filePaths = remoteSrv.GetFilePaths((int) webLevel, path, site, locationSubPath);
                    } finally { 
                        // Release COM objects
                        while (Marshal.ReleaseComObject(remoteSrv) > 0) {
                        }
                    } 
                } finally {
                    if (wiContext != null) 
                        wiContext.Undo(); 
                }
            } 
            catch {
                // Wrap finally clause with a try to avoid exception clauses being run
                // while the thread is impersonated.
                throw; 
            }
 
            if (filePaths == null) { 
                throw ExceptionUtil.UnexpectedError("RemoteWebConfigurationHost::InitForConfiguration");
            } 

            //
            // Format of filePaths:
            //      appPath < appSiteName < appSiteID < configPath < locationConfigPath [< configPath < fileName]+ 
            //
            string[] parts = filePaths.Split(RemoteWebConfigurationHostServer.FilePathsSeparatorParams); 
 
            if (parts.Length < 7 || (parts.Length - 5) % 2 != 0) {
                throw ExceptionUtil.UnexpectedError("RemoteWebConfigurationHost::InitForConfiguration"); 
            }

            // convert empty strings to nulls
            for (int i = 0; i < parts.Length; i++) { 
                if (parts[i].Length == 0) {
                    parts[i] = null; 
                } 
            }
 
            // get config paths
            string appPath = parts[0];
            string appSiteName = parts[1];
            string appSiteID = parts[2]; 
            configPath = parts[3];
            locationConfigPath = parts[4]; 
            _ConfigPath = configPath; 

            // Create a WebConfigurationFileMap to be used when we later initialize our delegating WebConfigurationHost 
            WebConfigurationFileMap configFileMap = new WebConfigurationFileMap();
            VirtualPath             appPathVirtualPath = VirtualPath.CreateAbsoluteAllowNull(appPath);

            configFileMap.Site = appSiteID; 

            // populate the configpath->physical path mapping 
            for (int i = 5; i < parts.Length; i += 2) { 
                string      configPathTemp = parts[i];
                string      physicalFilePath = parts[i+1]; 

                _PathMap.Add(configPathTemp, physicalFilePath);

                // Update the WebConfigurationFileMap 
                if (WebConfigurationHost.IsMachineConfigPath(configPathTemp)) {
                    configFileMap.MachineConfigFilename = physicalFilePath; 
                } 
                else {
                    string      vPathString; 
                    bool        isRootApp;

                    if (WebConfigurationHost.IsRootWebConfigPath(configPathTemp)) {
                        vPathString = null; 
                        isRootApp = false;
                    } 
                    else { 
                        VirtualPath vPath;
                        string      dummy; 

                        WebConfigurationHost.GetSiteIDAndVPathFromConfigPath(configPathTemp, out dummy, out vPath);
                        vPathString = VirtualPath.GetVirtualPathString(vPath);
                        isRootApp = (vPath == appPathVirtualPath); 
                    }
 
                    configFileMap.VirtualDirectories.Add(vPathString, 
                        new VirtualDirectoryMapping(Path.GetDirectoryName(physicalFilePath), isRootApp));
                } 
            }

#else // !FEATURE_PAL: set dummy config path
            string appPath = null; 
            _ConfigPath = configPath;
#endif // !FEATURE_PAL 
 
            // Delegate to a WebConfigurationHost for unhandled methods.
            WebConfigurationHost webConfigurationHost = new WebConfigurationHost(); 
            webConfigurationHost.Init(root, true, new UserMapPath(configFileMap, /*pathsAreLocal*/ false), null, appPath, appSiteName, appSiteID);
            Host = webConfigurationHost;
        }
 
        // config path support
        public override bool IsConfigRecordRequired(string configPath) { 
            // a record is required for every part of the config path 
            return configPath.Length <= _ConfigPath.Length;
        } 

        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        public override string GetStreamName(string configPath) 
        {
            return (string) _PathMap[configPath]; 
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        public override object GetStreamVersion(string streamName) {
#if FEATURE_PAL // FEATURE_PAL: singelton version
 	return s_version; 
#else
            // for now, assume it is the same 
            // return s_version; 
            bool exists;
            long size, createDate, lastWriteDate; 
            WindowsImpersonationContext wiContext = null;

            try {
                if (_Identity != null) { 
                    wiContext = _Identity.Impersonate();
                } 
 
                try {
                    ////////////////////////////////////////////////////////////////// 
                    // Step 3: Get the type and create the object on the remote server
                    IRemoteWebConfigurationHostServer remoteSrv = CreateRemoteObject(_Server, _Username, _Domain, _Password);
                    try {
                        ////////////////////////////////////////////////////////////////// 
                        // Step 4: Call the API
                        remoteSrv.GetFileDetails(streamName, out exists, out size, out createDate, out lastWriteDate); 
                    } 
                    finally {
                        while (Marshal.ReleaseComObject(remoteSrv) > 0) { } // release the COM object 
                    }
                }
                finally {
                    if (wiContext != null) { 
                        wiContext.Undo(); // revert impersonation
                    } 
                } 
            }
            catch { 
                // Wrap finally clause with a try to avoid exception clauses being run
                // while the thread is impersonated.
                throw;
            } 

            return new FileDetails(exists, size, DateTime.FromFileTimeUtc(createDate), DateTime.FromFileTimeUtc(lastWriteDate)); 
#endif // FEATURE_PAL 
        }
 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        public override Stream OpenStreamForRead(string streamName) {
            RemoteWebConfigurationHostStream rcs = new RemoteWebConfigurationHostStream(false, _Server, streamName, null, _Username, _Domain, _Password, _Identity); 
            if (rcs == null || rcs.Length < 1)
                return null; 
            return rcs; 
        }
 
        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        public override Stream OpenStreamForWrite(string streamName, string templateStreamName, ref object writeContext) {
            RemoteWebConfigurationHostStream rcs = new RemoteWebConfigurationHostStream(true, _Server, streamName, templateStreamName, _Username, _Domain, _Password, _Identity); 
            writeContext = rcs;
            return rcs; 
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        public override void DeleteStream(string StreamName)
        {
            // 
        }
 
        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        public override void WriteCompleted(string streamName, bool success, object writeContext) 
        {
            if (success) {
                RemoteWebConfigurationHostStream rcs = (RemoteWebConfigurationHostStream)writeContext;
                rcs.FlushForWriteCompleted(); 
            }
        } 
 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        public override bool IsFile(string StreamName)
        {
            return false;
        } 

        ///////////////////////////////////////////////////////////////////////////////// 
        ///////////////////////////////////////////////////////////////////////////////// 
        public override bool PrefetchAll(string configPath, string StreamName)
        { 
            return true;
        }

        ///////////////////////////////////////////////////////////////////////////////// 
        /////////////////////////////////////////////////////////////////////////////////
        public override bool PrefetchSection(string sectionGroupName, string sectionName) 
        { 
            return true;
        } 

        /////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////
        public override void GetRestrictedPermissions(IInternalConfigRecord configRecord, out PermissionSet permissionSet, out bool isHostReady) { 
            WebConfigurationHost.StaticGetRestrictedPermissions(configRecord, out permissionSet, out isHostReady);
        } 
 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        public override bool IsRemote {
            get { return true; }
        }
 
        /////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////// 
        // Encrypt/decrypt support 
        public override string DecryptSection(string encryptedXmlString, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedConfigSection) {
            return CallEncryptOrDecrypt(false, encryptedXmlString, protectionProvider, protectedConfigSection); 
        }
        public override string EncryptSection(string clearTextXmlString, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedConfigSection) {
            return CallEncryptOrDecrypt(true, clearTextXmlString, protectionProvider, protectedConfigSection);
        } 

        private string CallEncryptOrDecrypt(bool doEncrypt, string xmlString, ProtectedConfigurationProvider protectionProvider, ProtectedConfigurationSection protectedConfigSection) 
        { 
#if !FEATURE_PAL // FEATURE_PAL has no COM objects => no encryption
            // ROTORTODO: COM Objects are not implemented. 
            // CORIOLISTODO: COM Objects are not implemented.
            ProviderSettings                   ps;
            NameValueCollection                nvc;
            string  []                         paramKeys; 
            string  []                         paramValues;
            string                             returnString = null; 
            string                             typeName; 
            WindowsImpersonationContext        wiContext = null;
 
            ////////////////////////////////////////////////////////////
            // Step 1: Create list of parameters for the protection provider
            typeName = protectionProvider.GetType().AssemblyQualifiedName;
            ps = protectedConfigSection.Providers[protectionProvider.Name]; 
            if (ps == null)
                throw ExceptionUtil.ParameterInvalid("protectionProvider"); 
 
            nvc = ps.Parameters;
            if (nvc == null) 
                nvc = new NameValueCollection();

            paramKeys = nvc.AllKeys;
            paramValues = new string[paramKeys.Length]; 
            for(int iter = 0; iter 0) { } // release the COM object
                    } 
                } finally { 
                    if (wiContext != null)
                        wiContext.Undo(); // revert impersonation 
                }
            }
            catch {
            } 

            return returnString; 
#else       // !FEATURE_PAL 
            throw new NotImplementedException("ROTORTODO");
#endif      // !FEATURE_PAL 
        }

        ///////////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////////// 
        private static string GetUserNameFromFullName(string fullUserName) {
            if (string.IsNullOrEmpty(fullUserName)) 
                return null; 
            if (fullUserName.Contains("@")) {
                return fullUserName; 
            }
            string[] splitted = fullUserName.Split(new char[] { '\\' });
            if (splitted.Length == 1)
                return fullUserName; 
            else
                return splitted[1]; 
        } 
        private static string GetDomainFromFullName(string fullUserName) {
            if (string.IsNullOrEmpty(fullUserName)) 
                return null;
            if (fullUserName.Contains("@"))
                return null;
            string[] splitted = fullUserName.Split(new char[] { '\\' }); 
            if (splitted.Length == 1)
                return "."; 
            return splitted[0]; 
        }
 
        // impersonation support: create an identity from credentials
#if OLD_WAY
        private static WindowsIdentity CreateWindowsIdentity(string userName, string password, IntPtr tokenHandle) {
 
            //////////////////////////////////////////////////////////////////
            // Step 0: Most common case: check if no credentials are supplied 
            if (string.IsNullOrEmpty(userName) && tokenHandle == IntPtr.Zero && string.IsNullOrEmpty(password)) 
                return null;
 
            //////////////////////////////////////////////////////////////////
            // Step 1: Make sure that either username & password OR token is supplied
            if ((string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password)) || (!string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(password)))
                throw ExceptionUtil.ParameterNullOrEmpty("password"); 

            if (!string.IsNullOrEmpty(userName) && tokenHandle != IntPtr.Zero) 
                throw ExceptionUtil.ParameterInvalid("tokenHandle"); 

            ////////////////////////////////////////////////////////////////// 
            // Step 2: Create token if not supplied
            if (!string.IsNullOrEmpty(userName))
                tokenHandle = CreateUserToken(userName, password);
 
            //////////////////////////////////////////////////////////////////
            // Step 3: Create a windows identity from the token 
            WindowsIdentity wi = new WindowsIdentity(tokenHandle); 

            if (!string.IsNullOrEmpty(userName) && tokenHandle != IntPtr.Zero) // Close the handle if we created it. 
                UnsafeNativeMethods.CloseHandle(tokenHandle);
            return wi;
        }
 
        private static IntPtr CreateUserToken(string fullUserName, string password) {
            string userName, domain; 
            if (fullUserName.Contains("@")) { 
                userName = fullUserName;
                domain = null; 
            } else {
                string[] splitted = fullUserName.Split(new char[] { '\\' });
                if (splitted.Length == 1) {
                    userName = fullUserName; 
                    domain = ".";
                } else { 
                    userName = splitted[1]; 
                    domain = splitted[0];
                } 
            }
            //This parameter causes LogonUser to create a primary token.
            const int LOGON32_PROVIDER_DEFAULT        = 0;
            const int LOGON32_LOGON_INTERACTIVE       = 2; 
            const int LOGON32_LOGON_NETWORK           = 3;
            const int LOGON32_LOGON_BATCH             = 4; 
            const int LOGON32_LOGON_SERVICE           = 5; 
            const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
 
            int[] Logon32Values = new int[] { LOGON32_LOGON_INTERACTIVE, LOGON32_LOGON_BATCH, LOGON32_LOGON_SERVICE, LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_LOGON_NETWORK};

            IntPtr tokenHandle = IntPtr.Zero;
            int lastError = 0; 
            if (UnsafeNativeMethods.LogonUser(userName, domain, password, Logon32Values[0], LOGON32_PROVIDER_DEFAULT, ref tokenHandle) != 0)
                return tokenHandle; 
            lastError = Marshal.GetHRForLastWin32Error(); 
            for (int iter = 1; iter < Logon32Values.Length; iter++)
                if (UnsafeNativeMethods.LogonUser(userName, domain, password, Logon32Values[iter], LOGON32_PROVIDER_DEFAULT, ref tokenHandle) != 0) 
                    return tokenHandle;
            Marshal.ThrowExceptionForHR(lastError);
            return IntPtr.Zero;
        } 
#endif
        internal static IRemoteWebConfigurationHostServer CreateRemoteObject(string server, string username, string domain, string password) { 
 
#if !FEATURE_PAL // FEATURE_PAL has no COM objects
            try { 
                if (string.IsNullOrEmpty(username))
                    return CreateRemoteObjectUsingGetTypeFromCLSID(server);
                if (IntPtr.Size == 8)
                    return CreateRemoteObjectOn64BitPlatform(server, username, domain, password); 
                return CreateRemoteObjectOn32BitPlatform(server, username, domain, password);
            } catch (COMException ex) { 
                if ((uint)ex.ErrorCode == 0x80040154) 
                    throw new Exception(SR.GetString(SR.Make_sure_remote_server_is_enabled_for_config_access));
                throw; 
            }
        }
        private static IRemoteWebConfigurationHostServer CreateRemoteObjectUsingGetTypeFromCLSID(string server) {
            Type type = Type.GetTypeFromCLSID(typeof(RemoteWebConfigurationHostServer).GUID, server, true); 
            return (IRemoteWebConfigurationHostServer)Activator.CreateInstance(type);
        } 
 
        private static IRemoteWebConfigurationHostServer CreateRemoteObjectOn32BitPlatform(string server, string username, string domain, string password)
        { 
            MULTI_QI []     amqi            = new MULTI_QI[1];
            IntPtr          guidbuf         = IntPtr.Zero;
            COAUTHINFO      ca              = null;
            IntPtr          captr           = IntPtr.Zero; 
            COSERVERINFO    cs              = null;
            Guid            clsid           = typeof(RemoteWebConfigurationHostServer).GUID; 
            int             hr              = 0; 
            COAUTHIDENTITY  ci              = null;
            IntPtr          ciptr           = IntPtr.Zero; 

            try {
                guidbuf = Marshal.AllocCoTaskMem(16);
                Marshal.StructureToPtr(typeof(IRemoteWebConfigurationHostServer).GUID, guidbuf, false); 
                amqi[0] = new MULTI_QI(guidbuf);
 
                ci = new COAUTHIDENTITY(username, domain, password); 
                ciptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(ci));
                Marshal.StructureToPtr(ci, ciptr, false); 

                ca = new COAUTHINFO(RpcAuthent.WinNT, RpcAuthor.None, null, /*RpcLevel.Connect*/ RpcLevel.Default, RpcImpers.Impersonate, ciptr);
                captr = Marshal.AllocCoTaskMem(Marshal.SizeOf(ca));
                Marshal.StructureToPtr(ca, captr, false); 

                cs = new COSERVERINFO(server, captr); 
                hr = UnsafeNativeMethods.CoCreateInstanceEx(ref clsid, IntPtr.Zero, (int)ClsCtx.RemoteServer, cs, 1, amqi); 
                if ((uint)hr == 0x80040154)
                        throw new Exception(SR.GetString(SR.Make_sure_remote_server_is_enabled_for_config_access)); 
                if (hr < 0)
                    Marshal.ThrowExceptionForHR(hr);
                if (amqi[0].hr < 0)
                    Marshal.ThrowExceptionForHR(amqi[0].hr); 
                hr = UnsafeNativeMethods.CoSetProxyBlanket(amqi[0].pItf, RpcAuthent.WinNT, RpcAuthor.None, null, /*RpcLevel.Connect*/ RpcLevel.Default, RpcImpers.Impersonate, ciptr, 0);
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr); 
                return (IRemoteWebConfigurationHostServer)Marshal.GetObjectForIUnknown(amqi[0].pItf);
            } finally { 
                if (amqi[0].pItf != IntPtr.Zero)
                {
                    Marshal.Release(amqi[0].pItf);
                    amqi[0].pItf = IntPtr.Zero; 
                }
                amqi[0].piid = IntPtr.Zero; 
                if (captr != IntPtr.Zero) { 
                    Marshal.DestroyStructure(captr, typeof(COAUTHINFO));
                    Marshal.FreeCoTaskMem(captr); 
                }
                if (ciptr != IntPtr.Zero) {
                    Marshal.DestroyStructure(ciptr, typeof(COAUTHIDENTITY));
                    Marshal.FreeCoTaskMem(ciptr); 
                }
                if (guidbuf != IntPtr.Zero) 
                    Marshal.FreeCoTaskMem(guidbuf); 
            }
#else // !FEATURE_PAL 
            throw new NotSupportedException();
#endif // !FEATURE_PAL
        }
 
        private static IRemoteWebConfigurationHostServer CreateRemoteObjectOn64BitPlatform(string server, string username, string domain, string password)
        { 
            MULTI_QI_X64[]      amqi            = new MULTI_QI_X64[1]; 
            IntPtr              guidbuf         = IntPtr.Zero;
            COAUTHINFO_X64      ca              = null; 
            IntPtr              captr           = IntPtr.Zero;
            COSERVERINFO_X64    cs              = null;
            Guid                clsid           = typeof(RemoteWebConfigurationHostServer).GUID;
            int                 hr              = 0; 
            COAUTHIDENTITY_X64  ci              = null;
            IntPtr              ciptr           = IntPtr.Zero; 
 
            try {
                guidbuf = Marshal.AllocCoTaskMem(16); 
                Marshal.StructureToPtr(typeof(IRemoteWebConfigurationHostServer).GUID, guidbuf, false);
                amqi[0] = new MULTI_QI_X64(guidbuf);

                ci = new COAUTHIDENTITY_X64(username, domain, password); 
                ciptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(ci));
                Marshal.StructureToPtr(ci, ciptr, false); 
 
                ca = new COAUTHINFO_X64(RpcAuthent.WinNT, RpcAuthor.None, null, /*RpcLevel.Connect*/ RpcLevel.Default, RpcImpers.Impersonate, ciptr);
                captr = Marshal.AllocCoTaskMem(Marshal.SizeOf(ca)); 
                Marshal.StructureToPtr(ca, captr, false);

                cs = new COSERVERINFO_X64(server, captr);
                hr = UnsafeNativeMethods.CoCreateInstanceEx(ref clsid, IntPtr.Zero, (int)ClsCtx.RemoteServer, cs, 1, amqi); 
                if ((uint)hr == 0x80040154)
                    throw new Exception(SR.GetString(SR.Make_sure_remote_server_is_enabled_for_config_access)); 
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr);
                if (amqi[0].hr < 0) 
                    Marshal.ThrowExceptionForHR(amqi[0].hr);
                hr = UnsafeNativeMethods.CoSetProxyBlanket(amqi[0].pItf, RpcAuthent.WinNT, RpcAuthor.None, null, /*RpcLevel.Connect*/ RpcLevel.Default, RpcImpers.Impersonate, ciptr, 0);
                if (hr < 0)
                    Marshal.ThrowExceptionForHR(hr); 
                return (IRemoteWebConfigurationHostServer)Marshal.GetObjectForIUnknown(amqi[0].pItf);
            } finally { 
                if (amqi[0].pItf != IntPtr.Zero) { 
                    Marshal.Release(amqi[0].pItf);
                    amqi[0].pItf = IntPtr.Zero; 
                }
                amqi[0].piid = IntPtr.Zero;
                if (captr != IntPtr.Zero) {
                    Marshal.DestroyStructure(captr, typeof(COAUTHINFO_X64)); 
                    Marshal.FreeCoTaskMem(captr);
                } 
                if (ciptr != IntPtr.Zero) { 
                    Marshal.DestroyStructure(ciptr, typeof(COAUTHIDENTITY_X64));
                    Marshal.FreeCoTaskMem(ciptr); 
                }
                if (guidbuf != IntPtr.Zero)
                    Marshal.FreeCoTaskMem(guidbuf);
            } 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK