1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
// Windows/DLL.cpp
#include "StdAfx.h"
#ifdef __APPLE_CC__
#include <mach-o/dyld.h>
#elif ENV_BEOS
#include <kernel/image.h>
#include <Path.h>
#else
#define UINT64 DLL_UINT64 // HP-UX , dlfcn.h defines UINT64 but p7zip also defines UINT64
#include <dlfcn.h> // dlopen ...
#undef UINT64
#endif
#include "DLL.h"
#include "Defs.h"
#ifdef _UNICODE
#include "../Common/StringConvert.h"
#endif
#define NEED_NAME_WINDOWS_TO_UNIX
#include "myPrivate.h"
// #define TRACEN(u) u;
#define TRACEN(u) /* */
namespace NWindows {
namespace NDLL {
bool CLibrary::Free()
{
TRACEN((printf("CLibrary::Free(this=%p,%p)\n",(void *)this,(void *)_module)))
if (_module == 0)
return true;
#ifdef __APPLE_CC__
int ret = NSUnLinkModule ((NSModule)_module, 0);
#elif ENV_BEOS
int ret = unload_add_on((image_id)_module);
#else
int ret = dlclose(_module);
#endif
TRACEN((printf("CLibrary::Free dlclose(%p)=%d\n",(void *)_module,ret)))
if (ret != 0) return false;
_module = 0;
return true;
}
static FARPROC local_GetProcAddress(HMODULE module,LPCSTR lpProcName)
{
void *ptr = 0;
TRACEN((printf("local_GetProcAddress(%p,%s)\n",(void *)module,lpProcName)))
if (module) {
#ifdef __APPLE_CC__
char name[MAX_PATHNAME_LEN];
snprintf(name,sizeof(name),"_%s",lpProcName);
name[sizeof(name)-1] = 0;
TRACEN((printf("NSLookupSymbolInModule(%p,%s)\n",(void *)module,name)))
NSSymbol sym;
sym = NSLookupSymbolInModule((NSModule)module, name);
if (sym) {
ptr = NSAddressOfSymbol(sym);
} else {
ptr = 0;
}
#elif ENV_BEOS
if (get_image_symbol((image_id)module, lpProcName, B_SYMBOL_TYPE_TEXT, &ptr) != B_OK)
ptr = 0;
#else
ptr = dlsym (module, lpProcName);
#endif
TRACEN((printf("CLibrary::GetProc : dlsym(%p,%s)=%p\n",(void *)module,lpProcName,ptr)))
}
return (FARPROC)ptr;
}
FARPROC CLibrary::GetProc(LPCSTR lpProcName) const
{
TRACEN((printf("CLibrary::GetProc(%p,%s)\n",(void *)_module,lpProcName)))
return local_GetProcAddress(_module,lpProcName);
}
bool CLibrary::Load(LPCTSTR lpLibFileName)
{
if(!Free())
return false;
void *handler = 0;
char name[MAX_PATHNAME_LEN+1];
#ifdef _UNICODE
AString name2 = UnicodeStringToMultiByte(lpLibFileName);
strcpy(name,nameWindowToUnix((const char *)name2));
#else
strcpy(name,nameWindowToUnix(lpLibFileName));
#endif
// replace ".dll" with ".so"
size_t len = strlen(name);
if ((len >=4) && (strcmp(name+len-4,".dll") == 0)) {
strcpy(name+len-4,".so");
}
TRACEN((printf("CLibrary::Load(this=%p,%ls) => %s\n",(void *)this,lpLibFileName,name)))
#ifdef __APPLE_CC__
NSObjectFileImage image;
NSObjectFileImageReturnCode nsret;
nsret = NSCreateObjectFileImageFromFile (name, &image);
if (nsret == NSObjectFileImageSuccess) {
TRACEN((printf("NSCreateObjectFileImageFromFile(%s) : OK\n",name)))
handler = (HMODULE)NSLinkModule(image,name,NSLINKMODULE_OPTION_RETURN_ON_ERROR
| NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW);
} else {
TRACEN((printf("NSCreateObjectFileImageFromFile(%s) : ERROR\n",name)))
}
#elif ENV_BEOS
// normalize path (remove things like "./", "..", etc..), otherwise it won't work
BPath p(name, NULL, true);
status_t err = B_OK;
image_id image = load_add_on(p.Path());
TRACEN((printf("load_add_on(%s)=%d\n",p.Path(),(int)image)))
if (image < 0) {
err = (image_id)handler;
handler = 0;
} else {
err = 0;
handler = (HMODULE)image;
}
#else
int options_dlopen = 0;
#ifdef RTLD_LOCAL
options_dlopen |= RTLD_LOCAL;
#endif
#ifdef RTLD_NOW
options_dlopen |= RTLD_NOW;
#endif
#ifdef RTLD_GROUP
#if ! (defined(hpux) || defined(__hpux))
options_dlopen |= RTLD_GROUP; // mainly for solaris but not for HPUX
#endif
#endif
TRACEN((printf("CLibrary::Load - dlopen(%s,0x%d)\n",name,options_dlopen)))
handler = dlopen(name,options_dlopen);
#endif // __APPLE_CC__
TRACEN((printf("CLibrary::Load(%s) => %p\n",name,handler)))
if (handler) {
// Call DllMain() like in Windows : useless now
// Propagate the value of global_use_utf16_conversion into the plugins
int *tmp = (int *)local_GetProcAddress(handler,"global_use_utf16_conversion");
if (tmp) *tmp = global_use_utf16_conversion;
#ifdef ENV_HAVE_LSTAT
tmp = (int *)local_GetProcAddress(handler,"global_use_lstat");
if (tmp) *tmp = global_use_lstat;
#endif
// test construtors calls
void (*fctTest)(void) = (void (*)(void))local_GetProcAddress(handler,"sync_TestConstructor");
if (fctTest) fctTest();
} else {
#ifdef __APPLE_CC__
NSLinkEditErrors c;
int num_err;
const char *file,*err;
NSLinkEditError(&c,&num_err,&file,&err);
printf("Can't load '%ls' (%s)\n", lpLibFileName,err);
#elif ENV_BEOS
printf("Can't load '%ls' (%s)\n", lpLibFileName,strerror(err));
#else
printf("Can't load '%ls' (%s)\n", lpLibFileName,dlerror());
#endif
}
_module = handler;
TRACEN((printf("CLibrary::Load(this=%p,%ls) => _module=%p\n",(void *)this,lpLibFileName,_module)))
return true;
}
}}
|