You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,95 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ADConnectionHelper.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Web.DataAccess
|
||||
{
|
||||
using System.Net;
|
||||
using System.Diagnostics;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Security;
|
||||
using System.DirectoryServices;
|
||||
using System.DirectoryServices.Protocols;
|
||||
|
||||
internal static class ActiveDirectoryConnectionHelper
|
||||
{
|
||||
|
||||
internal static DirectoryEntryHolder GetDirectoryEntry(DirectoryInformation directoryInfo, string objectDN, bool revertImpersonation)
|
||||
{
|
||||
Debug.Assert ((objectDN != null) && (objectDN.Length != 0));
|
||||
|
||||
//
|
||||
// Get the adspath and create a directory entry holder
|
||||
//
|
||||
DirectoryEntryHolder holder = new DirectoryEntryHolder(new DirectoryEntry (
|
||||
directoryInfo.GetADsPath(objectDN),
|
||||
directoryInfo.GetUsername(),
|
||||
directoryInfo.GetPassword(),
|
||||
directoryInfo.AuthenticationTypes));
|
||||
//
|
||||
// If revertImpersonation is true, we need to revert
|
||||
//
|
||||
holder.Open(null, revertImpersonation);
|
||||
return holder;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class DirectoryEntryHolder
|
||||
{
|
||||
private ImpersonationContext ctx = null;
|
||||
private bool opened;
|
||||
private DirectoryEntry entry;
|
||||
|
||||
internal DirectoryEntryHolder (DirectoryEntry entry)
|
||||
{
|
||||
Debug.Assert (entry != null);
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
internal void Open (HttpContext context, bool revertImpersonate)
|
||||
{
|
||||
if (opened)
|
||||
return; // Already opened
|
||||
|
||||
//
|
||||
// Revert client impersonation if required
|
||||
//
|
||||
if (revertImpersonate)
|
||||
{
|
||||
ctx = new ApplicationImpersonationContext();
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
opened = true; // Open worked!
|
||||
}
|
||||
|
||||
internal void Close ()
|
||||
{
|
||||
if (!opened) // Not open!
|
||||
return;
|
||||
|
||||
entry.Dispose();
|
||||
RestoreImpersonation();
|
||||
opened = false;
|
||||
}
|
||||
|
||||
internal void RestoreImpersonation() {
|
||||
// Restore impersonation
|
||||
if (ctx != null)
|
||||
{
|
||||
ctx.Undo();
|
||||
ctx = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal DirectoryEntry DirectoryEntry
|
||||
{
|
||||
get { return entry; }
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,359 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DataConnectionError.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Web.UI;
|
||||
[assembly:WebResource("add_permissions_for_users.gif", "image/gif")]
|
||||
[assembly:WebResource("properties_security_tab_w_user.gif", "image/gif")]
|
||||
[assembly:WebResource("properties_security_tab.gif", "image/gif")]
|
||||
|
||||
namespace System.Web.DataAccess
|
||||
{
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Globalization;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Data;
|
||||
using System.Data.OleDb;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Configuration;
|
||||
using System.Web.Util;
|
||||
using System.Security.Permissions;
|
||||
using System.Web.Hosting;
|
||||
using System.Security.Principal;
|
||||
using System.Web.UI;
|
||||
using System.Web.Handlers;
|
||||
using System.Web.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
internal enum DataConnectionErrorEnum
|
||||
{
|
||||
CanNotCreateDataDir,
|
||||
CanNotWriteToDataDir,
|
||||
CanNotWriteToDBFile
|
||||
}
|
||||
|
||||
internal static class DataConnectionHelper
|
||||
{
|
||||
internal static string GetCurrentName()
|
||||
{
|
||||
string userName = "NETWORK SERVICE";
|
||||
string domainName = "NT AUTHORITY";
|
||||
|
||||
IntPtr pSid = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
if( UnsafeNativeMethods.ConvertStringSidToSid( "S-1-5-20", out pSid ) != 0 &&
|
||||
pSid != IntPtr.Zero )
|
||||
{
|
||||
int userNameLen = 256;
|
||||
int domainNameLen = 256;
|
||||
int sidNameUse = 0;
|
||||
StringBuilder bufUserName = new StringBuilder( userNameLen );
|
||||
StringBuilder bufDomainName = new StringBuilder( domainNameLen );
|
||||
if( 0 != UnsafeNativeMethods.LookupAccountSid( null,
|
||||
pSid,
|
||||
bufUserName,
|
||||
ref userNameLen,
|
||||
bufDomainName,
|
||||
ref domainNameLen,
|
||||
ref sidNameUse ) )
|
||||
{
|
||||
userName = bufUserName.ToString();
|
||||
domainName = bufDomainName.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
WindowsIdentity id = WindowsIdentity.GetCurrent();
|
||||
if( id != null && id.Name != null )
|
||||
{
|
||||
if ( string.Compare( id.Name,
|
||||
domainName + @"\" + userName,
|
||||
StringComparison.OrdinalIgnoreCase ) == 0 )
|
||||
{
|
||||
return userName;
|
||||
}
|
||||
|
||||
return id.Name;
|
||||
}
|
||||
}
|
||||
catch {}
|
||||
finally
|
||||
{
|
||||
if( pSid != IntPtr.Zero )
|
||||
{
|
||||
UnsafeNativeMethods.LocalFree( pSid );
|
||||
}
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class DataConnectionErrorFormatter : ErrorFormatter
|
||||
{
|
||||
protected static NameValueCollection s_errMessages = new NameValueCollection();
|
||||
protected static object s_Lock = new object ();
|
||||
protected string _UserName;
|
||||
protected DataConnectionErrorEnum _Error;
|
||||
|
||||
protected override string ErrorTitle
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
protected override string Description
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
protected override string MiscSectionTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
return SR.GetString(SR.DataAccessError_MiscSectionTitle) ;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string MiscSectionContent
|
||||
{
|
||||
get
|
||||
{
|
||||
string url;
|
||||
int currentNumber = 1;
|
||||
string resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_1);
|
||||
string miscContent = "<ol>\n<li>" + resourceString + "</li>\n";
|
||||
|
||||
switch (_Error)
|
||||
{
|
||||
case DataConnectionErrorEnum.CanNotCreateDataDir:
|
||||
resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_2_CanNotCreateDataDir);
|
||||
miscContent += "<li>" + resourceString + "</li>\n";
|
||||
|
||||
resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_2);
|
||||
miscContent += "<li>" + resourceString + "</li>\n";
|
||||
break;
|
||||
|
||||
case DataConnectionErrorEnum.CanNotWriteToDataDir:
|
||||
resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_2);
|
||||
miscContent += "<li>" + resourceString + "</li>\n";
|
||||
break;
|
||||
|
||||
case DataConnectionErrorEnum.CanNotWriteToDBFile:
|
||||
resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_2_CanNotWriteToDBFile_a);
|
||||
miscContent += "<li>" + resourceString + "</li>\n";
|
||||
|
||||
resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_2_CanNotWriteToDBFile_b);
|
||||
miscContent += "<li>" + resourceString + "</li>\n";
|
||||
break;
|
||||
}
|
||||
resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_3);
|
||||
miscContent += "<li>" + resourceString + "<br></li>\n";
|
||||
|
||||
url = AssemblyResourceLoader.GetWebResourceUrl(typeof(Page), "properties_security_tab.gif", true);
|
||||
miscContent += "<br><br><IMG SRC=\"" + url + "\"><br><br><br>";
|
||||
|
||||
resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_ClickAdd);
|
||||
miscContent += "<li>" + resourceString + "</li>\n";
|
||||
|
||||
url = AssemblyResourceLoader.GetWebResourceUrl(typeof(Page), "add_permissions_for_users.gif", true);
|
||||
miscContent += "<br><br><IMG SRC=\"" + url + "\"><br><br>";
|
||||
|
||||
string four;
|
||||
if (!String.IsNullOrEmpty(_UserName))
|
||||
four = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_4, _UserName);
|
||||
else
|
||||
four = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_4_2);
|
||||
miscContent += "<li>" + four + "</li>\n";
|
||||
|
||||
resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_ClickOK);
|
||||
miscContent += "<li>" + resourceString + "</li>\n";
|
||||
|
||||
resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_5);
|
||||
miscContent += "<li>" + resourceString + "</li>\n";
|
||||
|
||||
url = AssemblyResourceLoader.GetWebResourceUrl(typeof(Page), "properties_security_tab_w_user.gif", true);
|
||||
miscContent += "<br><br><IMG SRC=\"" + url + "\"><br><br>";
|
||||
|
||||
resourceString = GetResourceStringAndSetAdaptiveNumberedText(ref currentNumber, SR.DataAccessError_MiscSection_ClickOK);
|
||||
miscContent += "<li>" + resourceString + "</li>\n";
|
||||
return miscContent;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string ColoredSquareTitle
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
protected override string ColoredSquareContent
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
protected override bool ShowSourceFileInfo
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
private string GetResourceStringAndSetAdaptiveNumberedText(ref int currentNumber, string resourceId) {
|
||||
string resourceString = SR.GetString(resourceId);
|
||||
SetAdaptiveNumberedText(ref currentNumber, resourceString);
|
||||
return resourceString;
|
||||
}
|
||||
|
||||
private string GetResourceStringAndSetAdaptiveNumberedText(ref int currentNumber, string resourceId, string parameter1) {
|
||||
string resourceString = SR.GetString(resourceId, parameter1);
|
||||
SetAdaptiveNumberedText(ref currentNumber, resourceString);
|
||||
return resourceString;
|
||||
}
|
||||
|
||||
private void SetAdaptiveNumberedText(ref int currentNumber, string resourceString) {
|
||||
string adaptiveText = currentNumber.ToString(CultureInfo.InvariantCulture) + " " + resourceString;
|
||||
AdaptiveMiscContent.Add(adaptiveText);
|
||||
currentNumber += 1;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class SqlExpressConnectionErrorFormatter : DataConnectionErrorFormatter
|
||||
{
|
||||
internal SqlExpressConnectionErrorFormatter(DataConnectionErrorEnum error)
|
||||
{
|
||||
_UserName = (HttpRuntime.HasUnmanagedPermission() ? DataConnectionHelper.GetCurrentName() : String.Empty);
|
||||
_Error = error;
|
||||
}
|
||||
|
||||
internal SqlExpressConnectionErrorFormatter(string userName, DataConnectionErrorEnum error)
|
||||
{
|
||||
_UserName = userName;
|
||||
_Error = error;
|
||||
}
|
||||
|
||||
protected override string ErrorTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
string resourceKey = null;
|
||||
|
||||
switch ( _Error )
|
||||
{
|
||||
case DataConnectionErrorEnum.CanNotCreateDataDir:
|
||||
resourceKey = SR.DataAccessError_CanNotCreateDataDir_Title;
|
||||
break;
|
||||
|
||||
case DataConnectionErrorEnum.CanNotWriteToDataDir:
|
||||
resourceKey = SR.SqlExpressError_CanNotWriteToDataDir_Title;
|
||||
break;
|
||||
|
||||
case DataConnectionErrorEnum.CanNotWriteToDBFile:
|
||||
resourceKey = SR.SqlExpressError_CanNotWriteToDbfFile_Title;
|
||||
break;
|
||||
}
|
||||
return SR.GetString (resourceKey);
|
||||
}
|
||||
}
|
||||
|
||||
protected override string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
string resourceKey1 = null;
|
||||
string resourceKey2 = null;
|
||||
|
||||
switch (_Error)
|
||||
{
|
||||
case DataConnectionErrorEnum.CanNotCreateDataDir:
|
||||
resourceKey1 = SR.DataAccessError_CanNotCreateDataDir_Description;
|
||||
resourceKey2 = SR.DataAccessError_CanNotCreateDataDir_Description_2;
|
||||
break;
|
||||
|
||||
case DataConnectionErrorEnum.CanNotWriteToDataDir:
|
||||
resourceKey1 = SR.SqlExpressError_CanNotWriteToDataDir_Description;
|
||||
resourceKey2 = SR.SqlExpressError_CanNotWriteToDataDir_Description_2;
|
||||
break;
|
||||
|
||||
case DataConnectionErrorEnum.CanNotWriteToDBFile:
|
||||
resourceKey1 = SR.SqlExpressError_CanNotWriteToDbfFile_Description;
|
||||
resourceKey2 = SR.SqlExpressError_CanNotWriteToDbfFile_Description_2;
|
||||
break;
|
||||
}
|
||||
string desc;
|
||||
if (!String.IsNullOrEmpty(_UserName))
|
||||
desc = SR.GetString (resourceKey1, _UserName);
|
||||
else
|
||||
desc = SR.GetString (resourceKey2);
|
||||
desc += " " + SR.GetString(SR.SqlExpressError_Description_1);
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class SqlExpressDBFileAutoCreationErrorFormatter : UnhandledErrorFormatter
|
||||
{
|
||||
static string s_errMessage = null;
|
||||
static object s_Lock = new object();
|
||||
|
||||
internal SqlExpressDBFileAutoCreationErrorFormatter( Exception exception ) : base( exception )
|
||||
{
|
||||
}
|
||||
protected override string MiscSectionTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
return SR.GetString(SR.SqlExpress_MDF_File_Auto_Creation_MiscSectionTitle) ;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string MiscSectionContent
|
||||
{
|
||||
get
|
||||
{
|
||||
return CustomErrorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
internal static string CustomErrorMessage
|
||||
{
|
||||
get
|
||||
{
|
||||
if( s_errMessage == null )
|
||||
{
|
||||
lock( s_Lock )
|
||||
{
|
||||
if( s_errMessage == null )
|
||||
{
|
||||
string resourceString;
|
||||
|
||||
resourceString = SR.GetString(SR.SqlExpress_MDF_File_Auto_Creation) ;
|
||||
s_errMessage += "<br><br><p>" + resourceString + "<br></p>\n";
|
||||
|
||||
s_errMessage += "<ol>\n";
|
||||
|
||||
resourceString = SR.GetString(SR.SqlExpress_MDF_File_Auto_Creation_1) ;
|
||||
s_errMessage += "<li>" + resourceString + "</li>\n";
|
||||
resourceString = SR.GetString(SR.SqlExpress_MDF_File_Auto_Creation_2) ;
|
||||
s_errMessage += "<li>" + resourceString + "</li>\n";
|
||||
resourceString = SR.GetString(SR.SqlExpress_MDF_File_Auto_Creation_3) ;
|
||||
s_errMessage += "<li>" + resourceString + "</li>\n";
|
||||
resourceString = SR.GetString(SR.SqlExpress_MDF_File_Auto_Creation_4) ;
|
||||
s_errMessage += "<li>" + resourceString + "</li>\n";
|
||||
s_errMessage += "</ol>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s_errMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,324 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SqlConnectionHelper.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Web.DataAccess {
|
||||
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration;
|
||||
using System.Configuration.Provider;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security.Permissions;
|
||||
using System.Threading;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Management;
|
||||
using System.Web.Util;
|
||||
|
||||
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 const string s_localDbName = "(LOCALDB)";
|
||||
private static object s_lock = new object();
|
||||
|
||||
internal static void EnsureNoUserInstance(string connectionString) {
|
||||
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString);
|
||||
if (builder.UserInstance) {
|
||||
throw new ProviderException(SR.GetString(SR.LocalDB_cannot_have_userinstance_flag));
|
||||
}
|
||||
}
|
||||
|
||||
internal static SqlConnectionHolder GetConnection(string connectionString, bool revertImpersonation) {
|
||||
string strTempConnection = connectionString.ToUpperInvariant();
|
||||
if (strTempConnection.Contains(s_strUpperDataDirWithToken)) {
|
||||
EnsureDBFile(connectionString);
|
||||
}
|
||||
|
||||
// Only block UserInstance for LocalDB connections
|
||||
if (strTempConnection.Contains(s_localDbName)) {
|
||||
EnsureNoUserInstance(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 <connectionStrings> 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 EnsureDBFile(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 = !connectionString.ToUpperInvariant().Contains(s_localDbName); // We don't require UserInstance=True for LocalDb
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user