Index: System.Data.SQLite/UnsafeNativeMethods.cs ================================================================== --- System.Data.SQLite/UnsafeNativeMethods.cs +++ System.Data.SQLite/UnsafeNativeMethods.cs @@ -84,14 +84,64 @@ /// private static readonly object staticSyncRoot = new object(); ///////////////////////////////////////////////////////////////////////// /// + /// This class represents the concept of a platform as understood by the + /// native library pre-loading code. + /// + private sealed class Platform + { + #region Private Data + private string name; + private int bits; + #endregion + + ///////////////////////////////////////////////////////////////////// + + #region Public Constructors + public Platform( + string name, + int bits + ) + { + this.name = name; + this.bits = bits; + } + #endregion + + ///////////////////////////////////////////////////////////////////// + + #region Public Properties + /// + /// The name of the platform. This is used to help locate the + /// native library to pre-load. + /// + public string Name + { + get { return name; } + } + + ///////////////////////////////////////////////////////////////////// + + /// + /// The number of bits needed to represent memory addresses on this + /// platform. + /// + public int Bits + { + get { return bits; } + } + #endregion + } + + ///////////////////////////////////////////////////////////////////////// + /// /// Stores the mappings between processor architecture names and platform - /// names. + /// names (and bits). /// - private static Dictionary processorArchitecturePlatforms; + private static Dictionary processorArchitecturePlatforms; ///////////////////////////////////////////////////////////////////////// /// /// The native module handle for the native SQLite library or the value /// IntPtr.Zero. @@ -130,16 +180,31 @@ // processor architecture names and/or platform names // changes. // if (processorArchitecturePlatforms == null) { + // + // NOTE: Create the map of processor architecture names + // to platform names using a case-insensitive string + // comparer. + // processorArchitecturePlatforms = - new Dictionary(); + new Dictionary( + StringComparer.OrdinalIgnoreCase); - processorArchitecturePlatforms.Add("X86", "Win32"); - processorArchitecturePlatforms.Add("AMD64", "x64"); - processorArchitecturePlatforms.Add("IA64", "Itanium"); + // + // NOTE: Setup the list of platform names associated with + // the supported processor architectures. + // + processorArchitecturePlatforms.Add("x86", + new Platform("Win32", 32)); + + processorArchitecturePlatforms.Add("AMD64", + new Platform("x64", 64)); + + processorArchitecturePlatforms.Add("IA64", + new Platform("Itanium", 64)); } // // BUGBUG: What about other application domains? // @@ -235,10 +300,29 @@ return fileName; } ///////////////////////////////////////////////////////////////////////// /// + /// Determines and then returns the number of bits used to represent + /// memory addresses for the current process. + /// + /// + /// The number of bits used to represent memory addresses for the + /// current process or zero if this value cannot be determined. + /// + private static int GetProcessBits() + { + // + // NOTE: The number of bits used to represent memory addresses for + // the current process is the size of an IntPtr (in bytes), + // multiplied by the number of bits per byte (8). + // + return IntPtr.Size * 8; + } + + ///////////////////////////////////////////////////////////////////////// + /// /// Queries and returns the processor architecture of the current /// process. /// /// /// The processor architecture of the current process -OR- null if it @@ -247,13 +331,48 @@ /// private static string GetProcessorArchitecture() { #if !PLATFORM_COMPACTFRAMEWORK // - // BUGBUG: Will this always be reliable? + // NOTE: If the "PreLoadSQLite_ProcessorArchitecture" environment + // variable is set, use it verbatim for the current processor + // architecture. + // + string processorArchitecture = Environment.GetEnvironmentVariable( + "PreLoadSQLite_ProcessorArchitecture"); + + if (processorArchitecture != null) + return processorArchitecture; + + // + // NOTE: We cannot sanity check the processor architecture value + // without the mappings between processor architecture names + // and platform bits; therefore, return null in that case. // - return Environment.GetEnvironmentVariable(PROCESSOR_ARCHITECTURE); + if (processorArchitecturePlatforms != null) + { + // + // BUGBUG: Will this always be reliable? + // + processorArchitecture = Environment.GetEnvironmentVariable( + PROCESSOR_ARCHITECTURE); + + if (processorArchitecture != null) + { + Platform platform; + + if (processorArchitecturePlatforms.TryGetValue( + processorArchitecture, out platform) && + (platform != null) && + (platform.Bits == GetProcessBits())) + { + return processorArchitecture; + } + } + } + + return null; #else // // BUGBUG: No way to determine this value on the .NET Compact // Framework (running on Windows CE, etc). // @@ -282,27 +401,17 @@ lock (staticSyncRoot) { if (processorArchitecturePlatforms == null) return null; - string platformName; - - if (processorArchitecturePlatforms.TryGetValue( - processorArchitecture, out platformName)) - { - return platformName; - } - - if (processorArchitecturePlatforms.TryGetValue( -#if !PLATFORM_COMPACTFRAMEWORK - processorArchitecture.ToUpperInvariant(), -#else - processorArchitecture.ToUpper(), -#endif - out platformName)) - { - return platformName; + Platform platform; + + if (processorArchitecturePlatforms.TryGetValue( + processorArchitecture, out platform) && + (platform != null)) + { + return platform.Name; } } return null; }