System.Data.SQLite
Check-in [621d22239e]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Start of work on improving the platform detection in the native library pre-loading code.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | preLoad
Files: files | file ages | folders
SHA1: 621d22239e46b78c5f24eb89bfff340f50b33922
User & Date: mistachkin 2012-04-02 17:58:46
Context
2012-04-03
03:18
Clarify comments and semantics of the process 'bitness' checking in the native library pre-loading code. Closed-Leaf check-in: 77969440cd user: mistachkin tags: preLoad
2012-04-02
17:58
Start of work on improving the platform detection in the native library pre-loading code. check-in: 621d22239e user: mistachkin tags: preLoad
2012-03-31
22:23
Minor enhancements to release archive verification tool. check-in: 377c46ce48 user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to System.Data.SQLite/UnsafeNativeMethods.cs.

    82     82         /// This lock is used to protect the static _SQLiteModule and
    83     83         /// processorArchitecturePlatforms fields, below.
    84     84         /// </summary>
    85     85         private static readonly object staticSyncRoot = new object();
    86     86   
    87     87         /////////////////////////////////////////////////////////////////////////
    88     88         /// <summary>
           89  +      /// This class represents the concept of a platform as understood by the
           90  +      /// native library pre-loading code.
           91  +      /// </summary>
           92  +      private sealed class Platform
           93  +      {
           94  +          #region Private Data
           95  +          private string name;
           96  +          private int bits;
           97  +          #endregion
           98  +
           99  +          /////////////////////////////////////////////////////////////////////
          100  +
          101  +          #region Public Constructors
          102  +          public Platform(
          103  +              string name,
          104  +              int bits
          105  +              )
          106  +          {
          107  +              this.name = name;
          108  +              this.bits = bits;
          109  +          }
          110  +          #endregion
          111  +
          112  +          /////////////////////////////////////////////////////////////////////
          113  +
          114  +          #region Public Properties
          115  +          /// <summary>
          116  +          /// The name of the platform.  This is used to help locate the
          117  +          /// native library to pre-load.
          118  +          /// </summary>
          119  +          public string Name
          120  +          {
          121  +              get { return name; }
          122  +          }
          123  +
          124  +          /////////////////////////////////////////////////////////////////////
          125  +
          126  +          /// <summary>
          127  +          /// The number of bits needed to represent memory addresses on this
          128  +          /// platform.
          129  +          /// </summary>
          130  +          public int Bits
          131  +          {
          132  +              get { return bits; }
          133  +          }
          134  +          #endregion
          135  +      }
          136  +
          137  +      /////////////////////////////////////////////////////////////////////////
          138  +      /// <summary>
    89    139         /// Stores the mappings between processor architecture names and platform
    90         -      /// names.
          140  +      /// names (and bits).
    91    141         /// </summary>
    92         -      private static Dictionary<string, string> processorArchitecturePlatforms;
          142  +      private static Dictionary<string, Platform> processorArchitecturePlatforms;
    93    143   
    94    144         /////////////////////////////////////////////////////////////////////////
    95    145         /// <summary>
    96    146         /// The native module handle for the native SQLite library or the value
    97    147         /// IntPtr.Zero.
    98    148         /// </summary>
    99    149         private static IntPtr _SQLiteModule = IntPtr.Zero;
................................................................................
   128    178                 //
   129    179                 // TODO: Make sure this list is updated if the supported
   130    180                 //       processor architecture names and/or platform names
   131    181                 //       changes.
   132    182                 //
   133    183                 if (processorArchitecturePlatforms == null)
   134    184                 {
          185  +                  //
          186  +                  // NOTE: Create the map of processor architecture names
          187  +                  //       to platform names using a case-insensitive string
          188  +                  //       comparer.
          189  +                  //
   135    190                     processorArchitecturePlatforms =
   136         -                      new Dictionary<string, string>();
          191  +                      new Dictionary<string, Platform>(
          192  +                          StringComparer.OrdinalIgnoreCase);
   137    193   
   138         -                  processorArchitecturePlatforms.Add("X86", "Win32");
   139         -                  processorArchitecturePlatforms.Add("AMD64", "x64");
   140         -                  processorArchitecturePlatforms.Add("IA64", "Itanium");
          194  +                  //
          195  +                  // NOTE: Setup the list of platform names associated with
          196  +                  //       the supported processor architectures.
          197  +                  //
          198  +                  processorArchitecturePlatforms.Add("X86",
          199  +                      new Platform("Win32", 32));
          200  +
          201  +                  processorArchitecturePlatforms.Add("AMD64",
          202  +                      new Platform("x64", 64));
          203  +
          204  +                  processorArchitecturePlatforms.Add("IA64",
          205  +                      new Platform("Itanium", 64));
   141    206                 }
   142    207   
   143    208                 //
   144    209                 // BUGBUG: What about other application domains?
   145    210                 //
   146    211                 if (_SQLiteModule == IntPtr.Zero)
   147    212                     _SQLiteModule = PreLoadSQLiteDll(null, null);
................................................................................
   233    298             }
   234    299   
   235    300             return fileName;
   236    301         }
   237    302   
   238    303         /////////////////////////////////////////////////////////////////////////
   239    304         /// <summary>
          305  +      /// Determines and then returns the number of bits used to represent
          306  +      /// memory addresses for the current process.
          307  +      /// </summary>
          308  +      /// <returns>
          309  +      /// The number of bits used to represent memory addresses for the
          310  +      /// current process or zero if this value cannot be determined.
          311  +      /// </returns>
          312  +      private static int GetProcessBits()
          313  +      {
          314  +          return IntPtr.Size * 8;
          315  +      }
          316  +
          317  +      /////////////////////////////////////////////////////////////////////////
          318  +      /// <summary>
   240    319         /// Queries and returns the processor architecture of the current
   241    320         /// process.
   242    321         /// </summary>
   243    322         /// <returns>
   244    323         /// The processor architecture of the current process -OR- null if it
   245    324         /// cannot be determined.  Always returns an empty string when running on
   246    325         /// the .NET Compact Framework.
   247    326         /// </returns>
   248    327         private static string GetProcessorArchitecture()
   249    328         {
   250    329   #if !PLATFORM_COMPACTFRAMEWORK
   251    330             //
   252         -          // BUGBUG: Will this always be reliable?
          331  +          // NOTE: If the "PreLoadSQLite_ProcessorArchitecture" environment
          332  +          //       variable is set, use it verbatim for the current processor
          333  +          //       architecture.
   253    334             //
   254         -          return Environment.GetEnvironmentVariable(PROCESSOR_ARCHITECTURE);
          335  +          string processorArchitecture = Environment.GetEnvironmentVariable(
          336  +              "PreLoadSQLite_ProcessorArchitecture");
          337  +
          338  +          if (processorArchitecture != null)
          339  +              return processorArchitecture;
          340  +
          341  +          //
          342  +          // BUGBUG: Will this always be reliable?  There seems to be some
          343  +          //         evidence that this is not necessarily 100% reliable on
          344  +          //         some 64-bit platforms for child processes started from
          345  +          //         a WoW64 process (e.g. the Visual Studio debugger).
          346  +          //
          347  +          processorArchitecture = Environment.GetEnvironmentVariable(
          348  +              PROCESSOR_ARCHITECTURE);
          349  +
          350  +          if (processorArchitecture != null)
          351  +          {
          352  +              if (processorArchitecturePlatforms == null)
          353  +                  return null;
          354  +
          355  +              Platform platform;
          356  +
          357  +              if (processorArchitecturePlatforms.TryGetValue(
          358  +                      processorArchitecture, out platform) &&
          359  +                  (platform != null) &&
          360  +                  (platform.Bits == GetProcessBits()))
          361  +              {
          362  +                  return processorArchitecture;
          363  +              }
          364  +          }
          365  +
          366  +          return null;
   255    367   #else
   256    368             //
   257    369             // BUGBUG: No way to determine this value on the .NET Compact
   258    370             //         Framework (running on Windows CE, etc).
   259    371             //
   260    372             return String.Empty;
   261    373   #endif
................................................................................
   280    392                 return null;
   281    393   
   282    394             lock (staticSyncRoot)
   283    395             {
   284    396                 if (processorArchitecturePlatforms == null)
   285    397                     return null;
   286    398   
   287         -              string platformName;
          399  +              Platform platform;
   288    400   
   289    401                 if (processorArchitecturePlatforms.TryGetValue(
   290         -                      processorArchitecture, out platformName))
          402  +                      processorArchitecture, out platform) &&
          403  +                  (platform != null))
   291    404                 {
   292         -                  return platformName;
   293         -              }
   294         -
   295         -              if (processorArchitecturePlatforms.TryGetValue(
   296         -#if !PLATFORM_COMPACTFRAMEWORK
   297         -                      processorArchitecture.ToUpperInvariant(),
   298         -#else
   299         -                      processorArchitecture.ToUpper(),
   300         -#endif
   301         -                      out platformName))
   302         -              {
   303         -                  return platformName;
          405  +                  return platform.Name;
   304    406                 }
   305    407             }
   306    408   
   307    409             return null;
   308    410         }
   309    411   
   310    412         /////////////////////////////////////////////////////////////////////////