diff options
Diffstat (limited to 'src/libs/7zip/unix/CPP/Windows/DLL.cpp')
-rw-r--r-- | src/libs/7zip/unix/CPP/Windows/DLL.cpp | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/libs/7zip/unix/CPP/Windows/DLL.cpp b/src/libs/7zip/unix/CPP/Windows/DLL.cpp new file mode 100644 index 000000000..5f76cc5e2 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/DLL.cpp @@ -0,0 +1,193 @@ +// 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 { + +CLibrary::~CLibrary() +{ + Free(); +} + +bool CLibrary::Free() +{ +TRACEN((printf("CLibrary::Free(%p)\n",(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::LoadOperations(HMODULE newModule) +{ + if (newModule == NULL) + return false; + if(!Free()) + return false; + _module = newModule; + return true; +} + +bool CLibrary::Load(LPCTSTR lpLibFileName) +{ + 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(%ls) => %s\n",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; + + tmp = (int *)local_GetProcAddress(handler,"global_use_lstat"); + if (tmp) *tmp = global_use_lstat; + + // 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 + } + + return LoadOperations(handler); +} + +}} + |