diff --git a/pw3270.cbp b/pw3270.cbp
index 9e9b764..44b573a 100644
--- a/pw3270.cbp
+++ b/pw3270.cbp
@@ -76,6 +76,10 @@
+
+
+
+
diff --git a/src/classlib/class.mak.in b/src/classlib/class.mak.in
index c51dc97..3fa88d6 100644
--- a/src/classlib/class.mak.in
+++ b/src/classlib/class.mak.in
@@ -27,7 +27,7 @@
CLASS_CFLAGS=@CFLAGS@ @DLL_CFLAGS@ @DBUS_CFLAGS@
CLASS_LIBS=@LIBICONV@ @DBUS_LIBS@
-CLASS_SRC=session.cc exception.cc local.cc remote.cc
+CLASS_SRC=session.cc exception.cc local.cc remote.cc module.cc
CLASS_DEBUG_OBJECTS=$(foreach SRC, $(basename $(CLASS_SRC)), $(OBJDBG)/classlib/$(SRC)@OBJEXT@)
CLASS_RELEASE_OBJECTS=$(foreach SRC, $(basename $(CLASS_SRC)), $(OBJRLS)/classlib/$(SRC)@OBJEXT@)
diff --git a/src/classlib/local.cc b/src/classlib/local.cc
index 5e76c2b..b1e1303 100644
--- a/src/classlib/local.cc
+++ b/src/classlib/local.cc
@@ -114,166 +114,11 @@
namespace PW3270_NAMESPACE
{
- class local : public session
+ class local : public session, private module
{
private:
- H3270 * hSession;
-
- #ifdef WIN32
-
- HMODULE hModule;
-
- int get_datadir(LPSTR datadir)
- {
- HKEY hKey = 0;
- unsigned long datalen = strlen(datadir);
-
- *datadir = 0;
-
- if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\pw3270",0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS)
- {
- unsigned long datatype; // #defined in winnt.h (predefined types 0-11)
- if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) datadir,&datalen) != ERROR_SUCCESS)
- *datadir = 0;
- RegCloseKey(hKey);
- }
-
- return *datadir;
- }
- #else
-
- void * hModule;
-
- #endif // WIN32
-
- /**
- * Dynamically load lib3270
- *
- * @return 0 if the library was loaded, -1 on error.
- *
- */
- int load3270(void)
- {
- #ifdef WIN32
- static const char *dllname = "lib3270.dll." PACKAGE_VERSION;
-
- HMODULE kernel;
- HANDLE cookie = NULL;
- DWORD rc;
- HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory);
- BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie);
- UINT errorMode;
- char datadir[4096];
- char buffer[4096];
-
- kernel = LoadLibrary("kernel32.dll");
- AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory");
- RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory");
-
- // Notify user in case of error loading protocol DLL
- // http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx
- errorMode = SetErrorMode(1);
-
- memset(datadir,' ',4095);
- datadir[4095] = 0;
-
- if(get_datadir(datadir))
- {
- trace("Datadir=[%s] AddDllDirectory=%p RemoveDllDirectory=%p\n",datadir,AddDllDirectory,RemoveDllDirectory);
-
- if(AddDllDirectory)
- {
- wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t));
- mbstowcs(path, datadir, 4095);
- cookie = AddDllDirectory(path);
- free(path);
- }
-
- #ifdef DEBUG
- snprintf(buffer,4096,"%s\\.bin\\Debug\\%s",datadir,dllname);
- #else
- snprintf(buffer,4096,"%s\\%s",datadir,dllname);
- #endif // DEBUG
-
- trace("Loading [%s] [%s]",buffer,datadir);
- hModule = LoadLibrary(buffer);
-
- trace("Module=%p rc=%d",hModule,(int) GetLastError());
-
- if(hModule == NULL)
- {
- // Enable DLL error popup and try again with full path
- SetErrorMode(0);
- hModule = LoadLibraryEx(buffer,NULL,LOAD_LIBRARY_SEARCH_DEFAULT_DIRS|LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
- }
-
- rc = GetLastError();
-
- trace("%s hModule=%p rc=%d",buffer,hModule,(int) rc);
- }
- else
- {
- hModule = LoadLibrary(dllname);
- rc = GetLastError();
- }
-
- SetErrorMode(errorMode);
-
- trace("%s hModule=%p rc=%d",dllname,hModule,(int) rc);
-
- if(cookie && RemoveDllDirectory)
- RemoveDllDirectory(cookie);
-
- if(kernel)
- FreeLibrary(kernel);
-
- if(hModule)
- return 0;
-
- throw exception("Can't load %s",dllname);
-
- #else
- dlerror();
-
- hModule = dlopen("lib3270.so." PACKAGE_VERSION, RTLD_NOW);
- if(hModule)
- return 0;
-
- throw exception("Can't load lib3270: %s",dlerror());
-
- #endif // WIN32
-
- return -1;
-
- }
-
- void * get_symbol(const char *name)
- {
-#ifdef WIN32
- void *symbol = (void *) GetProcAddress(hModule,name);
-
- if(symbol)
- return symbol;
-
- throw exception("Can't load symbol lib3270::%s",name);
-
-#else
- void *symbol;
-
- symbol = dlsym(hModule,name);
-
- if(symbol)
- return symbol;
-
- throw exception("Can't load symbol lib3270::%s dlerror was \"%s\"",name,dlerror());
-
-#endif // WIN32
-
- return NULL;
-
- }
-
+ H3270 * hSession;
// Lib3270 entry points
const char * (*_get_version)(void);
@@ -313,7 +158,7 @@
public:
- local()
+ local() throw(std::exception) : module("lib3270",PACKAGE_VERSION)
{
H3270 * (*lib3270_new)(const char *);
void (*set_log_handler)(void (*loghandler)(H3270 *, const char *, int, const char *, va_list));
@@ -367,17 +212,11 @@
};
-
- if(load3270())
- return;
-
- trace("hModule=%p",hModule);
-
for(unsigned int f = 0; f < (sizeof (call) / sizeof ((call)[0]));f++)
{
*call[f].entry = (void *) get_symbol(call[f].name);
if(!*call[f].entry)
- return;
+ throw exception("Can't find symbol %s",call[f].name);
}
// Get Session handle, setup base callbacks
@@ -400,12 +239,6 @@
}
catch(exception e) { }
- #ifdef WIN32
- FreeLibrary(hModule);
- #else
- dlclose(hModule);
- #endif // WIN32
-
}
bool is_connected(void)
@@ -599,7 +432,7 @@
};
- session * session::create_local(void)
+ session * session::create_local(void) throw (std::exception)
{
return new local();
}
diff --git a/src/classlib/module.cc b/src/classlib/module.cc
new file mode 100644
index 0000000..cc919a6
--- /dev/null
+++ b/src/classlib/module.cc
@@ -0,0 +1,215 @@
+/*
+ * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
+ * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
+ * aplicativos mainframe. Registro no INPI sob o nome G3270.
+ *
+ * Copyright (C) <2008>
+ *
+ * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
+ * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
+ * Free Software Foundation.
+ *
+ * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
+ * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
+ * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
+ * obter mais detalhes.
+ *
+ * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
+ * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
+ * St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Este programa está nomeado como module.cc e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
+ *
+ */
+
+#if defined WIN32
+
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx
+ #ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
+ #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000
+ #endif // LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
+
+ #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
+ #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100
+ #endif // LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
+
+ #include
+
+#else
+
+ #include
+
+#endif
+
+#include
+
+/*---[ Implement ]----------------------------------------------------------------------------------*/
+
+
+namespace PW3270_NAMESPACE
+{
+
+#ifdef WIN32
+ int module::get_datadir(LPSTR datadir)
+ {
+ HKEY hKey = 0;
+ unsigned long datalen = strlen(datadir);
+
+ *datadir = 0;
+
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\pw3270",0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS)
+ {
+ unsigned long datatype; // #defined in winnt.h (predefined types 0-11)
+ if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) datadir,&datalen) != ERROR_SUCCESS)
+ *datadir = 0;
+ RegCloseKey(hKey);
+ }
+
+ return *datadir;
+ }
+#endif // WIN32
+
+ module::module(const char *name, const char *version) throw (std::exception)
+ {
+ string dllname = name;
+
+#ifdef WIN32
+
+ dllname += ".dll";
+ if(version)
+ {
+ dllname += ".";
+ dllname += version;
+ }
+
+ HMODULE kernel;
+ HANDLE cookie = NULL;
+ DWORD rc;
+ HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory);
+ BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie);
+ UINT errorMode;
+ char datadir[4096];
+ char buffer[4096];
+
+ kernel = LoadLibrary("kernel32.dll");
+ AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory");
+ RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory");
+
+ // Notify user in case of error loading protocol DLL
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx
+ errorMode = SetErrorMode(1);
+
+ memset(datadir,' ',4095);
+ datadir[4095] = 0;
+
+ if(get_datadir(datadir))
+ {
+ trace("Datadir=[%s] AddDllDirectory=%p RemoveDllDirectory=%p\n",datadir,AddDllDirectory,RemoveDllDirectory);
+
+ if(AddDllDirectory)
+ {
+ wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t));
+ mbstowcs(path, datadir, 4095);
+ cookie = AddDllDirectory(path);
+ free(path);
+ }
+
+#ifdef DEBUG
+ snprintf(buffer,4096,"%s\\.bin\\Debug\\%s",datadir,dllname.c_str());
+#else
+ snprintf(buffer,4096,"%s\\%s",datadir,dllname.c_str());
+#endif // DEBUG
+
+ trace("Loading [%s] [%s]",buffer,datadir);
+ hModule = LoadLibrary(buffer);
+
+ trace("Module=%p rc=%d",hModule,(int) GetLastError());
+
+ if(hModule == NULL)
+ {
+ // Enable DLL error popup and try again with full path
+ SetErrorMode(0);
+ hModule = LoadLibraryEx(buffer,NULL,LOAD_LIBRARY_SEARCH_DEFAULT_DIRS|LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
+ }
+
+ rc = GetLastError();
+
+ trace("%s hModule=%p rc=%d",buffer,hModule,(int) rc);
+ }
+ else
+ {
+ hModule = LoadLibrary(dllname);
+ rc = GetLastError();
+ }
+
+ SetErrorMode(errorMode);
+
+ trace("%s hModule=%p rc=%d",dllname,hModule,(int) rc);
+
+ if(cookie && RemoveDllDirectory)
+ RemoveDllDirectory(cookie);
+
+ if(kernel)
+ FreeLibrary(kernel);
+
+ if(!hModule)
+ throw exception("Can't load %s",dllname.c_str());
+
+#else
+ dllname += ".so";
+ if(version)
+ {
+ dllname += ".";
+ dllname += version;
+ }
+
+ dlerror();
+
+ hModule = dlopen(dllname.c_str(), RTLD_NOW);
+ if(!hModule)
+ throw exception("Can't load lib3270: %s",dllname.c_str());
+
+#endif // WIN32
+
+
+ }
+
+ module::~module()
+ {
+#ifdef WIN32
+ FreeLibrary(hModule);
+#else
+ dlclose(hModule);
+#endif // WIN32
+ }
+
+
+ void * module::get_symbol(const char *name)
+ {
+ void *symbol;
+
+#ifdef WIN32
+
+ symbol = (void *) GetProcAddress(hModule,name);
+
+ if(!symbol)
+ throw exception("Can't load symbol %s",name);
+
+#else
+ symbol = dlsym(hModule,name);
+
+ if(!symbol)
+ throw exception("Can't load symbol %s dlerror was \"%s\"",name,dlerror());
+
+#endif // WIN32
+
+ return symbol;
+ }
+
+}
+
diff --git a/src/classlib/remote.cc b/src/classlib/remote.cc
index 9b3d12b..598dda2 100644
--- a/src/classlib/remote.cc
+++ b/src/classlib/remote.cc
@@ -398,7 +398,7 @@
}
#endif // HAVE_DBUS
- remote(const char *session)
+ remote(const char *session) throw (std::exception)
{
#if defined(WIN32)
static DWORD dwMode = PIPE_READMODE_MESSAGE;
@@ -499,27 +499,6 @@
Sleep(10);
}
}
- /*
- WIN32_FIND_DATA FindFileData;
-
- timer = time(0)+20;
- while(hPipe == INVALID_HANDLE_VALUE && time(0) < timer)
- {
- hPipe = FindFirstFile(buffer, &FindFileData);
- Sleep(10);
- }
-
- if(hPipe != INVALID_HANDLE_VALUE)
- {
- CloseHandle(hPipe);
- hPipe = CreateFile(buffer,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
- }
- else
- {
- throw exception(GetLastError(),"Timeout waiting for %s instance",PACKAGE_NAME);
- return;
- }
- */
if(hPipe == INVALID_HANDLE_VALUE)
{
@@ -1377,7 +1356,7 @@
};
- session * session::create_remote(const char *session)
+ session * session::create_remote(const char *session) throw (std::exception)
{
return new remote(session);
}
diff --git a/src/classlib/session.cc b/src/classlib/session.cc
index 542483e..0e2872d 100644
--- a/src/classlib/session.cc
+++ b/src/classlib/session.cc
@@ -96,7 +96,7 @@
}
// Factory methods and settings
- session * session::create(const char *name)
+ session * session::create(const char *name) throw (std::exception)
{
if(factory)
return factory(name);
diff --git a/src/include/pw3270/class.h b/src/include/pw3270/class.h
index 8c2d906..97af0d4 100644
--- a/src/include/pw3270/class.h
+++ b/src/include/pw3270/class.h
@@ -89,6 +89,32 @@
};
+#if defined (HAVE_GNUC_VISIBILITY)
+ class __attribute__((visibility("default"))) module
+#elif defined(WIN32)
+ class __declspec (dllexport) module
+#else
+ class module
+#endif
+ {
+ private:
+#ifdef WIN32
+ HMODULE hModule;
+ int get_datadir(LPSTR datadir);
+#else
+ void * hModule;
+
+#endif // WIN32
+
+ public:
+ module(const char *name, const char *version = NULL) throw (std::exception);
+ ~module();
+
+ void * get_symbol(const char *name);
+
+ };
+
+
#if defined (HAVE_GNUC_VISIBILITY)
class __attribute__((visibility("default"))) session
@@ -104,7 +130,7 @@
// Factory methods and settings
static session * start(const char *name = 0);
- static session * create(const char *name = 0);
+ static session * create(const char *name = 0) throw (std::exception);
static session * get_default(void);
static void set_plugin(session * (*factory)(const char *name));
@@ -221,8 +247,8 @@
static session * (*factory)(const char *name);
- static session * create_remote(const char *name);
- static session * create_local(void);
+ static session * create_remote(const char *name) throw (std::exception);
+ static session * create_local(void) throw (std::exception);
#ifdef HAVE_ICONV
iconv_t conv2Local;
--
libgit2 0.21.2