Move the shared-library loading routines into the OS portability layer,
thus enabling the os_win.c code to handle the character encoding
confusion of win95/nt/ce.  Ticket #2023. (CVS 3541)

FossilOrigin-Name: a1bcc6de578992b28924c1cf974ea58251454e2d
diff --git a/src/loadext.c b/src/loadext.c
index 083bd94..095dbcc 100644
--- a/src/loadext.c
+++ b/src/loadext.c
@@ -218,38 +218,6 @@
 };
 
 /*
-** The windows implementation of shared-library loaders
-*/
-#if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__)
-# include <windows.h>
-# define SQLITE_LIBRARY_TYPE     HANDLE
-# ifdef _WIN32_WCE
-    static HANDLE loadLibraryUtf8(const char *z){
-      WCHAR zWide[MAX_PATH];
-      MultiByteToWideChar(CP_ACP,0,z,-1,zWide,MAX_PATH);
-      return LoadLibrary(zWide);
-    }
-#   define SQLITE_OPEN_LIBRARY(A)  loadLibraryUtf8(A)
-#   define SQLITE_FIND_SYMBOL(A,B) GetProcAddressA(A,B)
-# else
-#   define SQLITE_OPEN_LIBRARY(A)  LoadLibrary(A)
-#   define SQLITE_FIND_SYMBOL(A,B) GetProcAddress(A,B)
-# endif
-# define SQLITE_CLOSE_LIBRARY(A) FreeLibrary(A)
-#endif /* windows */
-
-/*
-** The unix implementation of shared-library loaders
-*/
-#if defined(HAVE_DLOPEN) && !defined(SQLITE_LIBRARY_TYPE)
-# include <dlfcn.h>
-# define SQLITE_LIBRARY_TYPE     void*
-# define SQLITE_OPEN_LIBRARY(A)  dlopen(A, RTLD_NOW | RTLD_GLOBAL)
-# define SQLITE_FIND_SYMBOL(A,B) dlsym(A,B)
-# define SQLITE_CLOSE_LIBRARY(A) dlclose(A)
-#endif
-
-/*
 ** Attempt to load an SQLite extension library contained in the file
 ** zFile.  The entry point is zProc.  zProc may be 0 in which case a
 ** default entry point name (sqlite3_extension_init) is used.  Use
@@ -267,11 +235,10 @@
   const char *zProc,    /* Entry point.  Use "sqlite3_extension_init" if 0 */
   char **pzErrMsg       /* Put error message here if not 0 */
 ){
-#ifdef SQLITE_LIBRARY_TYPE
-  SQLITE_LIBRARY_TYPE handle;
+  void *handle;
   int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
   char *zErrmsg = 0;
-  SQLITE_LIBRARY_TYPE *aHandle;
+  void **aHandle;
 
   /* Ticket #1863.  To avoid a creating security problems for older
   ** applications that relink against newer versions of SQLite, the
@@ -290,7 +257,7 @@
     zProc = "sqlite3_extension_init";
   }
 
-  handle = SQLITE_OPEN_LIBRARY(zFile);
+  handle = sqlite3OsDlopen(zFile);
   if( handle==0 ){
     if( pzErrMsg ){
       *pzErrMsg = sqlite3_mprintf("unable to open shared library [%s]", zFile);
@@ -298,20 +265,20 @@
     return SQLITE_ERROR;
   }
   xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
-                   SQLITE_FIND_SYMBOL(handle, zProc);
+                   sqlite3OsDlsym(handle, zProc);
   if( xInit==0 ){
     if( pzErrMsg ){
        *pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]",
                                    zProc, zFile);
     }
-    SQLITE_CLOSE_LIBRARY(handle);
+    sqlite3OsDlclose(handle);
     return SQLITE_ERROR;
   }else if( xInit(db, &zErrmsg, &sqlite3_apis) ){
     if( pzErrMsg ){
       *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
     }
     sqlite3_free(zErrmsg);
-    SQLITE_CLOSE_LIBRARY(handle);
+    sqlite3OsDlclose(handle);
     return SQLITE_ERROR;
   }
 
@@ -327,14 +294,8 @@
   sqliteFree(db->aExtension);
   db->aExtension = aHandle;
 
-  ((SQLITE_LIBRARY_TYPE*)db->aExtension)[db->nExtension-1] = handle;
+  db->aExtension[db->nExtension-1] = handle;
   return SQLITE_OK;
-#else
-  if( pzErrMsg ){
-    *pzErrMsg = sqlite3_mprintf("extension loading is disabled");
-  }
-  return SQLITE_ERROR;
-#endif
 }
 
 /*
@@ -342,13 +303,11 @@
 ** to clean up loaded extensions
 */
 void sqlite3CloseExtensions(sqlite3 *db){
-#ifdef SQLITE_LIBRARY_TYPE
   int i;
   for(i=0; i<db->nExtension; i++){
-    SQLITE_CLOSE_LIBRARY(((SQLITE_LIBRARY_TYPE*)db->aExtension)[i]);
+    sqlite3OsDlclose(db->aExtension[i]);
   }
   sqliteFree(db->aExtension);
-#endif
 }
 
 /*
diff --git a/src/os.h b/src/os.h
index 182cf99..0fe7b15 100644
--- a/src/os.h
+++ b/src/os.h
@@ -122,6 +122,9 @@
 #define sqlite3OsRealloc            sqlite3GenericRealloc
 #define sqlite3OsFree               sqlite3GenericFree
 #define sqlite3OsAllocationSize     sqlite3GenericAllocationSize
+#define sqlite3OsDlopen             sqlite3UnixDlopen
+#define sqlite3OsDlsym              sqlite3UnixDlsym
+#define sqlite3OsDlclose            sqlite3UnixDlclose
 #endif
 #if OS_WIN
 #define sqlite3OsOpenReadWrite      sqlite3WinOpenReadWrite
@@ -144,6 +147,9 @@
 #define sqlite3OsRealloc            sqlite3GenericRealloc
 #define sqlite3OsFree               sqlite3GenericFree
 #define sqlite3OsAllocationSize     sqlite3GenericAllocationSize
+#define sqlite3OsDlopen             sqlite3WinDlopen
+#define sqlite3OsDlsym              sqlite3WinDlsym
+#define sqlite3OsDlclose            sqlite3WinDlclose
 #endif
 #if OS_OS2
 #define sqlite3OsOpenReadWrite      sqlite3Os2OpenReadWrite
@@ -166,6 +172,9 @@
 #define sqlite3OsRealloc            sqlite3GenericRealloc
 #define sqlite3OsFree               sqlite3GenericFree
 #define sqlite3OsAllocationSize     sqlite3GenericAllocationSize
+#define sqlite3OsDlopen             sqlite3Os2Dlopen
+#define sqlite3OsDlsym              sqlite3Os2Dlsym
+#define sqlite3OsDlclose            sqlite3Os2Dlclose
 #endif
 
 
@@ -349,6 +358,9 @@
 void *sqlite3OsRealloc(void *, int);
 void sqlite3OsFree(void *);
 int sqlite3OsAllocationSize(void *);
+void *sqlite3OsDlopen(const char*);
+void *sqlite3OsDlsym(void*, const char*);
+int sqlite3OsDlclose(void*);
 
 /*
 ** If the SQLITE_ENABLE_REDEF_IO macro is defined, then the OS-layer
@@ -393,16 +405,26 @@
   void *(*xRealloc)(void *, int);
   void (*xFree)(void *);
   int (*xAllocationSize)(void *);
+
+  void *(*xDlopen)(const char*);
+  void *(*xDlsym)(void*, const char*);
+  int (*xDlclose)(void*);
 };
 
 /* Macro used to comment out routines that do not exists when there is
-** no disk I/O 
+** no disk I/O or extension loading
 */
 #ifdef SQLITE_OMIT_DISKIO
 # define IF_DISKIO(X)  0
 #else
 # define IF_DISKIO(X)  X
 #endif
+#ifdef SQLITE_OMIT_LOAD_EXTENSION
+# define IF_DLOPEN(X)  0
+#else
+# define IF_DLOPEN(X)  X
+#endif
+
 
 #ifdef _SQLITE_OS_C_
   /*
@@ -428,7 +450,10 @@
     sqlite3OsMalloc,
     sqlite3OsRealloc,
     sqlite3OsFree,
-    sqlite3OsAllocationSize
+    sqlite3OsAllocationSize,
+    IF_DLOPEN( sqlite3OsDlopen ),
+    IF_DLOPEN( sqlite3OsDlsym ),
+    IF_DLOPEN( sqlite3OsDlclose ),
   };
 #else
   /*
diff --git a/src/os_os2.c b/src/os_os2.c
index bdb31b8..999ac08 100644
--- a/src/os_os2.c
+++ b/src/os_os2.c
@@ -768,6 +768,23 @@
 ** with other miscellanous aspects of the operating system interface
 ****************************************************************************/
 
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+/*
+** Interfaces for opening a shared library, finding entry points
+** within the shared library, and closing the shared library.
+*/
+void *sqlite3Os2Dlopen(const char *zFilename){
+  return 0;
+}
+void *sqlite3Os2Dlsym(void *pHandle, const char *zSymbol){
+  return 0;
+}
+int sqlite3Os2Dlclose(void *pHandle){
+  return 0;
+}
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
+
+
 /*
 ** Get information to seed the random number generator.  The seed
 ** is written into the buffer zBuf[256].  The calling function must
diff --git a/src/os_unix.c b/src/os_unix.c
index 08c0191..046faf1 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -2581,6 +2581,23 @@
 ****************************************************************************/
 
 
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+/*
+** Interfaces for opening a shared library, finding entry points
+** within the shared library, and closing the shared library.
+*/
+#include <dlfcn.h>
+void *sqlite3UnixDlopen(const char *zFilename){
+  return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
+}
+void *sqlite3UnixDlsym(void *pHandle, const char *zSymbol){
+  return dlsym(pHandle, zSymbol);
+}
+int sqlite3UnixDlclose(void *pHandle){
+  return dlclose(pHandle);
+}
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
+
 /*
 ** Get information to seed the random number generator.  The seed
 ** is written into the buffer zBuf[256].  The calling function must
diff --git a/src/os_win.c b/src/os_win.c
index a7cdba2..c191f96 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -1498,6 +1498,38 @@
 ** with other miscellanous aspects of the operating system interface
 ****************************************************************************/
 
+#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
+/*
+** Interfaces for opening a shared library, finding entry points
+** within the shared library, and closing the shared library.
+*/
+void *sqlite3WinDlopen(const char *zFilename){
+  HANDLE h;
+  void *zConverted = convertUtf8Filename(zFilename);
+  if( zConverted==0 ){
+    return 0;
+  }
+  if( isNT() ){
+    h = LoadLibraryW(zConverted);
+  }else{
+#if OS_WINCE
+    return SQLITE_NOMEM;
+#else
+    h = LoadLibraryA(zConverted);
+#endif
+  }
+  sqliteFree(zConverted);
+  return (void*)h;
+  
+}
+void *sqlite3WinDlsym(void *pHandle, const char *zSymbol){
+  return GetProcAddress((HANDLE)pHandle, zSymbol);
+}
+int sqlite3WinDlclose(void *pHandle){
+  return FreeLibrary((HANDLE)pHandle);
+}
+#endif /* !SQLITE_OMIT_LOAD_EXTENSION */
+
 /*
 ** Get information to seed the random number generator.  The seed
 ** is written into the buffer zBuf[256].  The calling function must
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b000f0a..7a3002d 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.531 2006/12/16 16:25:16 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.532 2006/12/21 01:29:23 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -463,7 +463,7 @@
     u8 busy;                    /* TRUE if currently initializing */
   } init;
   int nExtension;               /* Number of loaded extensions */
-  void *aExtension;             /* Array of shared libraray handles */
+  void **aExtension;            /* Array of shared libraray handles */
   struct Vdbe *pVdbe;           /* List of active virtual machines */
   int activeVdbeCnt;            /* Number of vdbes currently executing */
   void (*xTrace)(void*,const char*);        /* Trace function */