Code:
                         / FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / fx / src / xsp / System / Web / DataAccess / SqlConnectionHelper.cs / 3 / 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.
// Copyright (c) Microsoft Corporation. All rights reserved.
                         
                        
                        
                        
                    Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CodeCatchClause.cs
- ZipPackagePart.cs
- TextSelectionHelper.cs
- TreeViewAutomationPeer.cs
- DrawTreeNodeEventArgs.cs
- DBDataPermissionAttribute.cs
- UpDownEvent.cs
- Focus.cs
- FillErrorEventArgs.cs
- WebPartDisplayModeCollection.cs
- TraceSource.cs
- HMACMD5.cs
- Util.cs
- IgnoreFileBuildProvider.cs
- WebPartConnectionsConfigureVerb.cs
- SQLMembershipProvider.cs
- XmlSignatureProperties.cs
- XmlIlVisitor.cs
- SafeReadContext.cs
- WindowsFormsHostPropertyMap.cs
- Pens.cs
- StylusPointProperties.cs
- ConfigurationValidatorBase.cs
- WebSysDefaultValueAttribute.cs
- CodeGenerator.cs
- ApplicationTrust.cs
- DeclaredTypeValidatorAttribute.cs
- SchemaImporterExtensionElementCollection.cs
- HitTestFilterBehavior.cs
- GridViewSortEventArgs.cs
- SqlConnectionHelper.cs
- StylusCollection.cs
- FragmentQuery.cs
- RawStylusInputReport.cs
- CodeCatchClauseCollection.cs
- EventLog.cs
- BufferedGraphics.cs
- OleDbInfoMessageEvent.cs
- EmptyEnumerator.cs
- BinaryWriter.cs
- DecimalAnimationBase.cs
- DbProviderFactory.cs
- XMLSchema.cs
- MenuItem.cs
- PointAnimationClockResource.cs
- DataGridComboBoxColumn.cs
- ColumnMapProcessor.cs
- AutoGeneratedField.cs
- ConnectionOrientedTransportBindingElement.cs
- Utilities.cs
- Bold.cs
- ToolBarTray.cs
- Point4DConverter.cs
- WindowAutomationPeer.cs
- ValidatorCompatibilityHelper.cs
- ListBox.cs
- DataBinding.cs
- SignedInfo.cs
- FixedDocumentPaginator.cs
- ColorAnimationBase.cs
- InfoCardBaseException.cs
- Style.cs
- XmlSchemaInferenceException.cs
- GeometryCollection.cs
- BaseAsyncResult.cs
- ColorTransformHelper.cs
- Logging.cs
- LocatorPart.cs
- DocumentsTrace.cs
- GridViewUpdatedEventArgs.cs
- FlowDocumentScrollViewer.cs
- SystemTcpConnection.cs
- GeometryGroup.cs
- SystemPens.cs
- Pair.cs
- ThemeInfoAttribute.cs
- UnaryQueryOperator.cs
- ThreadPool.cs
- XslCompiledTransform.cs
- Descriptor.cs
- MembershipSection.cs
- CodeCatchClause.cs
- HebrewNumber.cs
- ComponentEvent.cs
- DataObjectMethodAttribute.cs
- TreeViewItemAutomationPeer.cs
- PropagatorResult.cs
- BevelBitmapEffect.cs
- PermissionToken.cs
- QuaternionIndependentAnimationStorage.cs
- ZeroOpNode.cs
- NaturalLanguageHyphenator.cs
- TraceHandler.cs
- CollectionEditor.cs
- _NegoStream.cs
- _emptywebproxy.cs
- Automation.cs
- BindingMemberInfo.cs
- OverloadGroupAttribute.cs
- VoiceObjectToken.cs