SqlConnectionHelper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / DataAccess / SqlConnectionHelper.cs / 1305376 / SqlConnectionHelper.cs

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

namespace System.Web.DataAccess { 
 
    using System;
    using System.Globalization; 
    using System.Data.SqlClient;
    using System.Configuration;
    using System.Collections.Specialized;
    using System.Web.Util; 
    using System.Web.Hosting;
    using System.Web.Configuration; 
    using System.Security.Permissions; 
    using System.IO;
    using System.Web.Management; 
    using System.Threading;
    using System.Configuration.Provider;
    using System.Diagnostics;
    using System.Data; 

    ///  
    ///  
    internal static class SqlConnectionHelper
    { 
        internal const string s_strDataDir                 = "DataDirectory";
        internal const string s_strUpperDataDirWithToken   = "|DATADIRECTORY|";
        internal const string s_strSqlExprFileExt          = ".MDF";
        internal const string s_strUpperUserInstance       = "USER INSTANCE"; 
        private static object s_lock = new object();
 
        ///  
        /// 
        internal static SqlConnectionHolder GetConnection ( string connectionString, bool revertImpersonation) 
        {
            string strTempConnection = connectionString.ToUpperInvariant();
            if (strTempConnection.Contains(s_strUpperDataDirWithToken))
                EnsureSqlExpressDBFile( connectionString ); 

            SqlConnectionHolder holder = new SqlConnectionHolder(connectionString); 
            bool closeConn = true; 
            try
            { 
                try
                {
                    holder.Open(null, revertImpersonation);
                    closeConn = false; 
                }
                finally 
                { 
                    if (closeConn)
                    { 
                        holder.Close();
                        holder = null;
                    }
                } 
            }
            catch 
            { 
                throw;
            } 
            return holder;
        }

        ///  
        /// 
        internal static string GetConnectionString (string specifiedConnectionString, bool lookupConnectionString, bool appLevel) 
        { 
            System.Web.Util.Debug.Assert((specifiedConnectionString != null) && (specifiedConnectionString.Length != 0));
            if (specifiedConnectionString == null || specifiedConnectionString.Length < 1) 
                return null;

            string connectionString = null;
 
            /////////////////////////////////////////
            // Step 1: Check  config section for this connection string 
            if (lookupConnectionString) 
            {
                RuntimeConfig config = (appLevel) ? RuntimeConfig.GetAppConfig() : RuntimeConfig.GetConfig(); 
                ConnectionStringSettings connObj = config.ConnectionStrings.ConnectionStrings[specifiedConnectionString];
                if (connObj != null)
                    connectionString = connObj.ConnectionString;
 
                if (connectionString == null)
                    return null; 
 
                //HandlerBase.CheckAndReadRegistryValue (ref connectionString, true);
            } 
            else
            {
                connectionString = specifiedConnectionString;
            } 

            return connectionString; 
        } 

        [PermissionSet(SecurityAction.Assert, Unrestricted = true)] 
        internal static string GetDataDirectory()
        {
            if (HostingEnvironment.IsHosted)
                return Path.Combine(HttpRuntime.AppDomainAppPath, HttpRuntime.DataDirectoryName); 

            string dataDir = AppDomain.CurrentDomain.GetData(s_strDataDir) as string; 
            if( string.IsNullOrEmpty(dataDir)) 
            {
                string          appPath = null; 

#if !FEATURE_PAL // FEATURE_PAL does not support ProcessModule
                Process         p   = Process.GetCurrentProcess();
                ProcessModule   pm  = ( p != null ? p.MainModule : null ); 
                string          exeName = ( pm != null ? pm.FileName : null);
 
                if (!string.IsNullOrEmpty(exeName)) 
                    appPath = Path.GetDirectoryName( exeName );
#endif // !FEATURE_PAL 

                if (string.IsNullOrEmpty(appPath))
                    appPath = Environment.CurrentDirectory;
 
                dataDir = Path.Combine(appPath, HttpRuntime.DataDirectoryName);
                AppDomain.CurrentDomain.SetData(s_strDataDir, dataDir, new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dataDir)); 
            } 

            return dataDir; 
        }

        /////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////// 

        private static void EnsureSqlExpressDBFile(string connectionString) 
        { 
            string   partialFileName   = null;
            string   fullFileName      = null; 
            string   dataDir           = GetDataDirectory();
            bool     lookingForDataDir = true;
            bool     lookingForDB      = true;
            string[] splitedConnStr    = connectionString.Split(new char[] {';'}, StringSplitOptions.RemoveEmptyEntries); 
            bool     lookingForUserInstance = true;
            bool     lookingForTimeout = true; 
 
            foreach( string str in splitedConnStr )
            { 
                string strUpper = str.ToUpper(CultureInfo.InvariantCulture).Trim();

                if (lookingForDataDir && strUpper.Contains(s_strUpperDataDirWithToken))
                { 
                    lookingForDataDir = false;
 
                    // Replace the AttachDBFilename part with "Pooling=false" 
                    connectionString = connectionString.Replace(str, "Pooling=false");
 
                    // Extract the filenames
                    int startPos = strUpper.IndexOf(s_strUpperDataDirWithToken, StringComparison.Ordinal) + s_strUpperDataDirWithToken.Length;
                    partialFileName = strUpper.Substring(startPos).Trim();
                    while(partialFileName.StartsWith("\\", StringComparison.Ordinal)) 
                        partialFileName = partialFileName.Substring(1);
                    if (partialFileName.Contains("..")) // don't allow it to traverse-up 
                        partialFileName = null; 
                    else
                        fullFileName = Path.Combine(dataDir, partialFileName); 
                    if (!lookingForDB)
                        break; // done
                }
                else if (lookingForDB && (strUpper.StartsWith( "INITIAL CATALOG", StringComparison.Ordinal ) || strUpper.StartsWith( "DATABASE", StringComparison.Ordinal ))) 
                {
                    lookingForDB = false; 
                    connectionString = connectionString.Replace(str, "Database=master" ); 
                    if (!lookingForDataDir)
                        break; // done 
                }
                else if (lookingForUserInstance && strUpper.StartsWith(s_strUpperUserInstance, StringComparison.Ordinal))
                {
                    lookingForUserInstance = false; 
                    int pos = strUpper.IndexOf('=');
                    if (pos < 0) 
                        return; 
                    string strTemp = strUpper.Substring(pos + 1).Trim();
                    if (strTemp != "TRUE") 
                        return;
                } else if (lookingForTimeout && strUpper.StartsWith("CONNECT TIMEOUT", StringComparison.Ordinal)) {
                    lookingForTimeout = false;
                } 
            }
            if (lookingForUserInstance) 
                return; 

            if (fullFileName == null) 
                throw new ProviderException(SR.GetString(SR.SqlExpress_file_not_found_in_connection_string));

            if (File.Exists(fullFileName))
                return; 

            if (!HttpRuntime.HasAspNetHostingPermission(AspNetHostingPermissionLevel.High)) 
                throw new ProviderException(SR.GetString(SR.Provider_can_not_create_file_in_this_trust_level)); 

            if (!connectionString.Contains("Database=master")) 
                connectionString += ";Database=master";
            if (lookingForTimeout)
                connectionString += ";Connect Timeout=45";
            using (new ApplicationImpersonationContext()) 
                lock (s_lock)
                    if (!File.Exists(fullFileName)) 
                        CreateMdfFile(fullFileName, dataDir, connectionString); 
        }
 
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
        private static void CreateMdfFile(string fullFileName, string dataDir, string connectionString) 
        {
            bool          creatingDir     = false; 
            string        databaseName    = null; 
            HttpContext   context         = HttpContext.Current;
            string        tempFileName    = null; 

            try {
                if (!Directory.Exists(dataDir)) {
                    creatingDir = true; 
                    Directory.CreateDirectory( dataDir );
                    creatingDir = false; 
                    try  { 
                        if(context != null )
                            HttpRuntime.RestrictIISFolders(context); 
                    } catch {}
                }

                fullFileName = fullFileName.ToUpper(CultureInfo.InvariantCulture); 
                char [] strippedFileNameChars = Path.GetFileNameWithoutExtension(fullFileName).ToCharArray();
                for (int iter = 0; iter < strippedFileNameChars.Length; iter++) 
                    if (!char.IsLetterOrDigit(strippedFileNameChars[iter])) 
                        strippedFileNameChars[iter] = '_';
                string strippedFileName = new string(strippedFileNameChars); 
                if (strippedFileName.Length > 30)
                    databaseName = strippedFileName.Substring(0, 30) + "_" + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
                else
                    databaseName = strippedFileName + "_" + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); 

                tempFileName = Path.Combine(Path.GetDirectoryName(fullFileName), strippedFileName + "_TMP" + s_strSqlExprFileExt); 
 
                // Auto create the temporary database
                SqlServices.Install( databaseName, tempFileName, connectionString ); 
                DetachDB(databaseName, connectionString);
                try {
                    File.Move(tempFileName, fullFileName);
                } catch { 
                    if (!File.Exists(fullFileName)) {
                        File.Copy(tempFileName, fullFileName); 
                        try { 
                            File.Delete(tempFileName);
                        } catch{} 
                    }
                }
                try {
                    File.Delete(tempFileName.Replace("_TMP.MDF", "_TMP_log.LDF")); 
                } catch { }
            }  catch( Exception e ) { 
                if (context == null || context.IsCustomErrorEnabled) 
                    throw;
                HttpException httpExec = new HttpException(e.Message, e); 
                if (e is UnauthorizedAccessException)
                    httpExec.SetFormatter(new SqlExpressConnectionErrorFormatter(creatingDir ? DataConnectionErrorEnum.CanNotCreateDataDir : DataConnectionErrorEnum.CanNotWriteToDataDir));
                else
                    httpExec.SetFormatter(new SqlExpressDBFileAutoCreationErrorFormatter(e)); 
                throw httpExec;
            } 
        } 
        private static void DetachDB(string databaseName, string connectionString)
        { 
            SqlConnection connection = new SqlConnection(connectionString);
            try {
                connection.Open();
                SqlCommand command = new SqlCommand("USE master", connection); 
                command.ExecuteNonQuery();
                command = new SqlCommand("sp_detach_db", connection); 
                command.CommandType = CommandType.StoredProcedure; 
                command.Parameters.AddWithValue("@dbname", databaseName);
                command.Parameters.AddWithValue("@skipchecks", "true"); 
                command.ExecuteNonQuery();
            } catch {
            } finally {
                connection.Close(); 
            }
        } 
    } 
    //////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////// 
    //////////////////////////////////////////////////////////////////////
    internal sealed class SqlConnectionHolder
    {
        internal SqlConnection     _Connection; 
        private bool               _Opened;
 
        internal SqlConnection Connection 
        {
            get{ return _Connection; } 
        }

        //////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////// 
        internal SqlConnectionHolder ( string connectionString )
        { 
            try 
            {
                _Connection = new SqlConnection( connectionString ); 
                System.Web.Util.Debug.Assert( _Connection != null );
            }
            catch( ArgumentException e )
            { 
                throw new ArgumentException(SR.GetString(SR.SqlError_Connection_String), "connectionString", e);
            } 
        } 

        ////////////////////////////////////////////////////////////////////////////// 
        //////////////////////////////////////////////////////////////////////////////
        internal void Open (HttpContext context, bool revertImpersonate)
        {
            if (_Opened) 
                return; // Already opened
 
            if (revertImpersonate) { 
                using (new ApplicationImpersonationContext()) {
                    Connection.Open(); 
                }
            }
            else {
                Connection.Open(); 
            }
 
            _Opened = true; // Open worked! 
        }
 
        //////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////////////
        internal void Close ()
        { 
            if (!_Opened) // Not open!
                return; 
            // Close connection 
            Connection.Close ();
            _Opened = false; 
        }
    }
}
 

// 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