Commit 31726505bb0642617967d879814dcfd35d080169

Authored by perry.werneck@gmail.com
1 parent 2452cbb5

Iniciando implementação de carga dinâmica da jvm

pw3270.cbp
... ... @@ -76,6 +76,10 @@
76 76 <Unit filename="src/classlib/class.mak.in" />
77 77 <Unit filename="src/classlib/exception.cc" />
78 78 <Unit filename="src/classlib/local.cc" />
  79 + <Unit filename="src/classlib/module.cc">
  80 + <Option target="Debug" />
  81 + <Option target="Release" />
  82 + </Unit>
79 83 <Unit filename="src/classlib/remote.cc" />
80 84 <Unit filename="src/classlib/session.cc" />
81 85 <Unit filename="src/classlib/testprogram.cc" />
... ...
src/classlib/class.mak.in
... ... @@ -27,7 +27,7 @@
27 27 CLASS_CFLAGS=@CFLAGS@ @DLL_CFLAGS@ @DBUS_CFLAGS@
28 28 CLASS_LIBS=@LIBICONV@ @DBUS_LIBS@
29 29  
30   -CLASS_SRC=session.cc exception.cc local.cc remote.cc
  30 +CLASS_SRC=session.cc exception.cc local.cc remote.cc module.cc
31 31  
32 32 CLASS_DEBUG_OBJECTS=$(foreach SRC, $(basename $(CLASS_SRC)), $(OBJDBG)/classlib/$(SRC)@OBJEXT@)
33 33 CLASS_RELEASE_OBJECTS=$(foreach SRC, $(basename $(CLASS_SRC)), $(OBJRLS)/classlib/$(SRC)@OBJEXT@)
... ...
src/classlib/local.cc
... ... @@ -114,166 +114,11 @@
114 114 namespace PW3270_NAMESPACE
115 115 {
116 116  
117   - class local : public session
  117 + class local : public session, private module
118 118 {
119 119 private:
120 120  
121   - H3270 * hSession;
122   -
123   - #ifdef WIN32
124   -
125   - HMODULE hModule;
126   -
127   - int get_datadir(LPSTR datadir)
128   - {
129   - HKEY hKey = 0;
130   - unsigned long datalen = strlen(datadir);
131   -
132   - *datadir = 0;
133   -
134   - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\pw3270",0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS)
135   - {
136   - unsigned long datatype; // #defined in winnt.h (predefined types 0-11)
137   - if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) datadir,&datalen) != ERROR_SUCCESS)
138   - *datadir = 0;
139   - RegCloseKey(hKey);
140   - }
141   -
142   - return *datadir;
143   - }
144   - #else
145   -
146   - void * hModule;
147   -
148   - #endif // WIN32
149   -
150   - /**
151   - * Dynamically load lib3270
152   - *
153   - * @return 0 if the library was loaded, -1 on error.
154   - *
155   - */
156   - int load3270(void)
157   - {
158   - #ifdef WIN32
159   - static const char *dllname = "lib3270.dll." PACKAGE_VERSION;
160   -
161   - HMODULE kernel;
162   - HANDLE cookie = NULL;
163   - DWORD rc;
164   - HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory);
165   - BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie);
166   - UINT errorMode;
167   - char datadir[4096];
168   - char buffer[4096];
169   -
170   - kernel = LoadLibrary("kernel32.dll");
171   - AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory");
172   - RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory");
173   -
174   - // Notify user in case of error loading protocol DLL
175   - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx
176   - errorMode = SetErrorMode(1);
177   -
178   - memset(datadir,' ',4095);
179   - datadir[4095] = 0;
180   -
181   - if(get_datadir(datadir))
182   - {
183   - trace("Datadir=[%s] AddDllDirectory=%p RemoveDllDirectory=%p\n",datadir,AddDllDirectory,RemoveDllDirectory);
184   -
185   - if(AddDllDirectory)
186   - {
187   - wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t));
188   - mbstowcs(path, datadir, 4095);
189   - cookie = AddDllDirectory(path);
190   - free(path);
191   - }
192   -
193   - #ifdef DEBUG
194   - snprintf(buffer,4096,"%s\\.bin\\Debug\\%s",datadir,dllname);
195   - #else
196   - snprintf(buffer,4096,"%s\\%s",datadir,dllname);
197   - #endif // DEBUG
198   -
199   - trace("Loading [%s] [%s]",buffer,datadir);
200   - hModule = LoadLibrary(buffer);
201   -
202   - trace("Module=%p rc=%d",hModule,(int) GetLastError());
203   -
204   - if(hModule == NULL)
205   - {
206   - // Enable DLL error popup and try again with full path
207   - SetErrorMode(0);
208   - hModule = LoadLibraryEx(buffer,NULL,LOAD_LIBRARY_SEARCH_DEFAULT_DIRS|LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
209   - }
210   -
211   - rc = GetLastError();
212   -
213   - trace("%s hModule=%p rc=%d",buffer,hModule,(int) rc);
214   - }
215   - else
216   - {
217   - hModule = LoadLibrary(dllname);
218   - rc = GetLastError();
219   - }
220   -
221   - SetErrorMode(errorMode);
222   -
223   - trace("%s hModule=%p rc=%d",dllname,hModule,(int) rc);
224   -
225   - if(cookie && RemoveDllDirectory)
226   - RemoveDllDirectory(cookie);
227   -
228   - if(kernel)
229   - FreeLibrary(kernel);
230   -
231   - if(hModule)
232   - return 0;
233   -
234   - throw exception("Can't load %s",dllname);
235   -
236   - #else
237   - dlerror();
238   -
239   - hModule = dlopen("lib3270.so." PACKAGE_VERSION, RTLD_NOW);
240   - if(hModule)
241   - return 0;
242   -
243   - throw exception("Can't load lib3270: %s",dlerror());
244   -
245   - #endif // WIN32
246   -
247   - return -1;
248   -
249   - }
250   -
251   - void * get_symbol(const char *name)
252   - {
253   -#ifdef WIN32
254   - void *symbol = (void *) GetProcAddress(hModule,name);
255   -
256   - if(symbol)
257   - return symbol;
258   -
259   - throw exception("Can't load symbol lib3270::%s",name);
260   -
261   -#else
262   - void *symbol;
263   -
264   - symbol = dlsym(hModule,name);
265   -
266   - if(symbol)
267   - return symbol;
268   -
269   - throw exception("Can't load symbol lib3270::%s dlerror was \"%s\"",name,dlerror());
270   -
271   -#endif // WIN32
272   -
273   - return NULL;
274   -
275   - }
276   -
  121 + H3270 * hSession;
277 122  
278 123 // Lib3270 entry points
279 124 const char * (*_get_version)(void);
... ... @@ -313,7 +158,7 @@
313 158  
314 159 public:
315 160  
316   - local()
  161 + local() throw(std::exception) : module("lib3270",PACKAGE_VERSION)
317 162 {
318 163 H3270 * (*lib3270_new)(const char *);
319 164 void (*set_log_handler)(void (*loghandler)(H3270 *, const char *, int, const char *, va_list));
... ... @@ -367,17 +212,11 @@
367 212  
368 213 };
369 214  
370   -
371   - if(load3270())
372   - return;
373   -
374   - trace("hModule=%p",hModule);
375   -
376 215 for(unsigned int f = 0; f < (sizeof (call) / sizeof ((call)[0]));f++)
377 216 {
378 217 *call[f].entry = (void *) get_symbol(call[f].name);
379 218 if(!*call[f].entry)
380   - return;
  219 + throw exception("Can't find symbol %s",call[f].name);
381 220 }
382 221  
383 222 // Get Session handle, setup base callbacks
... ... @@ -400,12 +239,6 @@
400 239 }
401 240 catch(exception e) { }
402 241  
403   - #ifdef WIN32
404   - FreeLibrary(hModule);
405   - #else
406   - dlclose(hModule);
407   - #endif // WIN32
408   -
409 242 }
410 243  
411 244 bool is_connected(void)
... ... @@ -599,7 +432,7 @@
599 432  
600 433 };
601 434  
602   - session * session::create_local(void)
  435 + session * session::create_local(void) throw (std::exception)
603 436 {
604 437 return new local();
605 438 }
... ...
src/classlib/module.cc 0 → 100644
... ... @@ -0,0 +1,215 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como module.cc e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +#if defined WIN32
  31 +
  32 + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx
  33 + #ifndef LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
  34 + #define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000
  35 + #endif // LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
  36 +
  37 + #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
  38 + #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100
  39 + #endif // LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
  40 +
  41 + #include <windows.h>
  42 +
  43 +#else
  44 +
  45 + #include <dlfcn.h>
  46 +
  47 +#endif
  48 +
  49 +#include <pw3270/class.h>
  50 +
  51 +/*---[ Implement ]----------------------------------------------------------------------------------*/
  52 +
  53 +
  54 +namespace PW3270_NAMESPACE
  55 +{
  56 +
  57 +#ifdef WIN32
  58 + int module::get_datadir(LPSTR datadir)
  59 + {
  60 + HKEY hKey = 0;
  61 + unsigned long datalen = strlen(datadir);
  62 +
  63 + *datadir = 0;
  64 +
  65 + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\pw3270",0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS)
  66 + {
  67 + unsigned long datatype; // #defined in winnt.h (predefined types 0-11)
  68 + if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) datadir,&datalen) != ERROR_SUCCESS)
  69 + *datadir = 0;
  70 + RegCloseKey(hKey);
  71 + }
  72 +
  73 + return *datadir;
  74 + }
  75 +#endif // WIN32
  76 +
  77 + module::module(const char *name, const char *version) throw (std::exception)
  78 + {
  79 + string dllname = name;
  80 +
  81 +#ifdef WIN32
  82 +
  83 + dllname += ".dll";
  84 + if(version)
  85 + {
  86 + dllname += ".";
  87 + dllname += version;
  88 + }
  89 +
  90 + HMODULE kernel;
  91 + HANDLE cookie = NULL;
  92 + DWORD rc;
  93 + HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory);
  94 + BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie);
  95 + UINT errorMode;
  96 + char datadir[4096];
  97 + char buffer[4096];
  98 +
  99 + kernel = LoadLibrary("kernel32.dll");
  100 + AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory");
  101 + RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory");
  102 +
  103 + // Notify user in case of error loading protocol DLL
  104 + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx
  105 + errorMode = SetErrorMode(1);
  106 +
  107 + memset(datadir,' ',4095);
  108 + datadir[4095] = 0;
  109 +
  110 + if(get_datadir(datadir))
  111 + {
  112 + trace("Datadir=[%s] AddDllDirectory=%p RemoveDllDirectory=%p\n",datadir,AddDllDirectory,RemoveDllDirectory);
  113 +
  114 + if(AddDllDirectory)
  115 + {
  116 + wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t));
  117 + mbstowcs(path, datadir, 4095);
  118 + cookie = AddDllDirectory(path);
  119 + free(path);
  120 + }
  121 +
  122 +#ifdef DEBUG
  123 + snprintf(buffer,4096,"%s\\.bin\\Debug\\%s",datadir,dllname.c_str());
  124 +#else
  125 + snprintf(buffer,4096,"%s\\%s",datadir,dllname.c_str());
  126 +#endif // DEBUG
  127 +
  128 + trace("Loading [%s] [%s]",buffer,datadir);
  129 + hModule = LoadLibrary(buffer);
  130 +
  131 + trace("Module=%p rc=%d",hModule,(int) GetLastError());
  132 +
  133 + if(hModule == NULL)
  134 + {
  135 + // Enable DLL error popup and try again with full path
  136 + SetErrorMode(0);
  137 + hModule = LoadLibraryEx(buffer,NULL,LOAD_LIBRARY_SEARCH_DEFAULT_DIRS|LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
  138 + }
  139 +
  140 + rc = GetLastError();
  141 +
  142 + trace("%s hModule=%p rc=%d",buffer,hModule,(int) rc);
  143 + }
  144 + else
  145 + {
  146 + hModule = LoadLibrary(dllname);
  147 + rc = GetLastError();
  148 + }
  149 +
  150 + SetErrorMode(errorMode);
  151 +
  152 + trace("%s hModule=%p rc=%d",dllname,hModule,(int) rc);
  153 +
  154 + if(cookie && RemoveDllDirectory)
  155 + RemoveDllDirectory(cookie);
  156 +
  157 + if(kernel)
  158 + FreeLibrary(kernel);
  159 +
  160 + if(!hModule)
  161 + throw exception("Can't load %s",dllname.c_str());
  162 +
  163 +#else
  164 + dllname += ".so";
  165 + if(version)
  166 + {
  167 + dllname += ".";
  168 + dllname += version;
  169 + }
  170 +
  171 + dlerror();
  172 +
  173 + hModule = dlopen(dllname.c_str(), RTLD_NOW);
  174 + if(!hModule)
  175 + throw exception("Can't load lib3270: %s",dllname.c_str());
  176 +
  177 +#endif // WIN32
  178 +
  179 +
  180 + }
  181 +
  182 + module::~module()
  183 + {
  184 +#ifdef WIN32
  185 + FreeLibrary(hModule);
  186 +#else
  187 + dlclose(hModule);
  188 +#endif // WIN32
  189 + }
  190 +
  191 +
  192 + void * module::get_symbol(const char *name)
  193 + {
  194 + void *symbol;
  195 +
  196 +#ifdef WIN32
  197 +
  198 + symbol = (void *) GetProcAddress(hModule,name);
  199 +
  200 + if(!symbol)
  201 + throw exception("Can't load symbol %s",name);
  202 +
  203 +#else
  204 + symbol = dlsym(hModule,name);
  205 +
  206 + if(!symbol)
  207 + throw exception("Can't load symbol %s dlerror was \"%s\"",name,dlerror());
  208 +
  209 +#endif // WIN32
  210 +
  211 + return symbol;
  212 + }
  213 +
  214 +}
  215 +
... ...
src/classlib/remote.cc
... ... @@ -398,7 +398,7 @@
398 398 }
399 399 #endif // HAVE_DBUS
400 400  
401   - remote(const char *session)
  401 + remote(const char *session) throw (std::exception)
402 402 {
403 403 #if defined(WIN32)
404 404 static DWORD dwMode = PIPE_READMODE_MESSAGE;
... ... @@ -499,27 +499,6 @@
499 499 Sleep(10);
500 500 }
501 501 }
502   - /*
503   - WIN32_FIND_DATA FindFileData;
504   -
505   - timer = time(0)+20;
506   - while(hPipe == INVALID_HANDLE_VALUE && time(0) < timer)
507   - {
508   - hPipe = FindFirstFile(buffer, &FindFileData);
509   - Sleep(10);
510   - }
511   -
512   - if(hPipe != INVALID_HANDLE_VALUE)
513   - {
514   - CloseHandle(hPipe);
515   - hPipe = CreateFile(buffer,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
516   - }
517   - else
518   - {
519   - throw exception(GetLastError(),"Timeout waiting for %s instance",PACKAGE_NAME);
520   - return;
521   - }
522   - */
523 502  
524 503 if(hPipe == INVALID_HANDLE_VALUE)
525 504 {
... ... @@ -1377,7 +1356,7 @@
1377 1356  
1378 1357 };
1379 1358  
1380   - session * session::create_remote(const char *session)
  1359 + session * session::create_remote(const char *session) throw (std::exception)
1381 1360 {
1382 1361 return new remote(session);
1383 1362 }
... ...
src/classlib/session.cc
... ... @@ -96,7 +96,7 @@
96 96 }
97 97  
98 98 // Factory methods and settings
99   - session * session::create(const char *name)
  99 + session * session::create(const char *name) throw (std::exception)
100 100 {
101 101 if(factory)
102 102 return factory(name);
... ...
src/include/pw3270/class.h
... ... @@ -89,6 +89,32 @@
89 89  
90 90 };
91 91  
  92 +#if defined (HAVE_GNUC_VISIBILITY)
  93 + class __attribute__((visibility("default"))) module
  94 +#elif defined(WIN32)
  95 + class __declspec (dllexport) module
  96 +#else
  97 + class module
  98 +#endif
  99 + {
  100 + private:
  101 +#ifdef WIN32
  102 + HMODULE hModule;
  103 + int get_datadir(LPSTR datadir);
  104 +#else
  105 + void * hModule;
  106 +
  107 +#endif // WIN32
  108 +
  109 + public:
  110 + module(const char *name, const char *version = NULL) throw (std::exception);
  111 + ~module();
  112 +
  113 + void * get_symbol(const char *name);
  114 +
  115 + };
  116 +
  117 +
92 118  
93 119 #if defined (HAVE_GNUC_VISIBILITY)
94 120 class __attribute__((visibility("default"))) session
... ... @@ -104,7 +130,7 @@
104 130  
105 131 // Factory methods and settings
106 132 static session * start(const char *name = 0);
107   - static session * create(const char *name = 0);
  133 + static session * create(const char *name = 0) throw (std::exception);
108 134 static session * get_default(void);
109 135 static void set_plugin(session * (*factory)(const char *name));
110 136  
... ... @@ -221,8 +247,8 @@
221 247  
222 248 static session * (*factory)(const char *name);
223 249  
224   - static session * create_remote(const char *name);
225   - static session * create_local(void);
  250 + static session * create_remote(const char *name) throw (std::exception);
  251 + static session * create_local(void) throw (std::exception);
226 252  
227 253 #ifdef HAVE_ICONV
228 254 iconv_t conv2Local;
... ...