Commit 99d3b0ed02e0500d81855cbf12dd24983d02de78

Authored by Perry Werneck
1 parent 9f0e9f3d
Exists in master and in 1 other branch develop

Refactoring IPC plugin for windows.

hllapi.cbp
... ... @@ -44,6 +44,9 @@
44 44 <Option compilerVar="CC" />
45 45 </Unit>
46 46 <Unit filename="src/plugin/linux/service.h" />
  47 + <Unit filename="src/plugin/windows/main.c">
  48 + <Option compilerVar="CC" />
  49 + </Unit>
47 50 <Unit filename="src/testprogram/testprogram.c">
48 51 <Option compilerVar="CC" />
49 52 </Unit>
... ...
src/hllapi/pluginmain.c
... ... @@ -1,673 +0,0 @@
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. 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 pluginmain.c 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   - * Agradecimento:
29   - *
30   - * Hélio Passos
31   - *
32   - */
33   -
34   - #include "server.h"
35   -
36   -#ifdef _WIN32
37   - #include <windows.h>
38   -#else
39   - #error HLLAPI is designed for windows.
40   -#endif // _WIN32
41   -
42   - #include <pw3270/plugin.h>
43   - #include <v3270.h>
44   - #include <pw3270/ipcpackets.h>
45   - #include <lib3270/actions.h>
46   - #include <lib3270/charset.h>
47   -
48   -/*--[ Defines ]--------------------------------------------------------------------------------------*/
49   -
50   - #pragma pack(1)
51   -
52   - enum PIPE_STATE
53   - {
54   - PIPE_STATE_WAITING,
55   - PIPE_STATE_READ,
56   - PIPE_STATE_PENDING_READ,
57   - PIPE_STATE_UNDEFINED
58   - };
59   -
60   - typedef struct _pipe_source
61   - {
62   - GSource gsrc;
63   - HANDLE hPipe;
64   -
65   - enum PIPE_STATE state;
66   -
67   - OVERLAPPED overlap;
68   - unsigned char buffer[PIPE_BUFFER_LENGTH+1];
69   - } pipe_source;
70   -
71   - #pragma pack()
72   -
73   -
74   -/*--[ Globals ]--------------------------------------------------------------------------------------*/
75   -
76   -// static const gchar control_char = '@';
77   -
78   -/*--[ Implement ]------------------------------------------------------------------------------------*/
79   -
80   - static void IO_accept(pipe_source *source)
81   - {
82   - set_active(FALSE);
83   -
84   - if(ConnectNamedPipe(source->hPipe,&source->overlap))
85   - {
86   - popup_lasterror("%s",_( "Error in ConnectNamedPipe" ));
87   - return;
88   - }
89   -
90   - switch(GetLastError())
91   - {
92   - // The overlapped connection in progress.
93   - case ERROR_IO_PENDING:
94   - // trace("%s: ERROR_IO_PENDING",__FUNCTION__);
95   - source->state = PIPE_STATE_WAITING;
96   - break;
97   -
98   - // Client is already connected, so signal an event.
99   - case ERROR_PIPE_CONNECTED:
100   - trace("%s: ERROR_PIPE_CONNECTED",__FUNCTION__);
101   - set_active(TRUE);
102   - if(SetEvent(source->overlap.hEvent))
103   - break;
104   -
105   - // If an error occurs during the connect operation...
106   - default:
107   - popup_lasterror("%s", _( "ConnectNamedPipe failed" ));
108   - }
109   -
110   - }
111   -
112   - static gboolean IO_prepare(GSource *source, gint *timeout)
113   - {
114   - /*
115   - * Called before all the file descriptors are polled.
116   - * If the source can determine that it is ready here
117   - * (without waiting for the results of the poll() call)
118   - * it should return TRUE.
119   - *
120   - * It can also return a timeout_ value which should be the maximum
121   - * timeout (in milliseconds) which should be passed to the poll() call.
122   - * The actual timeout used will be -1 if all sources returned -1,
123   - * or it will be the minimum of all the timeout_ values
124   - * returned which were >= 0.
125   - *
126   - */
127   - if(WaitForSingleObject(((pipe_source *) source)->overlap.hEvent,0) == WAIT_OBJECT_0)
128   - return TRUE;
129   -
130   - *timeout = 10;
131   - return FALSE;
132   - }
133   -
134   - static gboolean IO_check(GSource *source)
135   - {
136   - /*
137   - * Called after all the file descriptors are polled.
138   - * The source should return TRUE if it is ready to be dispatched.
139   - * Note that some time may have passed since the previous prepare
140   - * function was called, so the source should be checked again here.
141   - *
142   - */
143   - if(WaitForSingleObject(((pipe_source *) source)->overlap.hEvent,0) == WAIT_OBJECT_0)
144   - return TRUE;
145   -
146   - return FALSE;
147   - }
148   -
149   - static void send_text(pipe_source *source, char *text)
150   - {
151   - struct hllapi_packet_text *pkt;
152   - DWORD szBlock;
153   - int f;
154   -
155   - if(text)
156   - {
157   - szBlock = sizeof(struct hllapi_packet_text)+strlen(text);
158   - pkt = (struct hllapi_packet_text *) g_malloc0(szBlock);
159   - pkt->packet_id = 0;
160   - strcpy(pkt->text,text);
161   - lib3270_free(text);
162   - }
163   - else
164   - {
165   - szBlock = sizeof(struct hllapi_packet_text);
166   - pkt = (struct hllapi_packet_text *) g_malloc0(szBlock);
167   - pkt->packet_id = errno ? errno : -1;
168   - }
169   -
170   - trace("szBlock=%d text=\"%s\"",szBlock, ( (struct hllapi_packet_text *) pkt)->text);
171   - for(f=0;f< (int) szBlock;f++)
172   - {
173   - trace("rsp(%d)= %d \"%s\"",f,* (((char *) pkt)+f),((char *) pkt)+f);
174   - }
175   -
176   - WriteFile(source->hPipe,pkt,szBlock,&szBlock,NULL);
177   -
178   - g_free(pkt);
179   - }
180   -
181   - static void send_result(pipe_source *source, int rc)
182   - {
183   - struct hllapi_packet_result pkt = { rc };
184   - DWORD wrote = sizeof(pkt);
185   - WriteFile(source->hPipe,&pkt,wrote,&wrote,NULL);
186   - }
187   -
188   - static int do_file_transfer(struct hllapi_packet_file_transfer * source)
189   - {
190   - /*
191   - const gchar * local = (const char *) source->text;
192   - const gchar * remote = (const char *) (local+strlen(local)+1);
193   -
194   - return v3270_transfer_file( v3270_get_default_widget(),
195   - (LIB3270_FT_OPTION) source->options,
196   - local,
197   - remote,
198   - source->lrecl,
199   - source->blksize,
200   - source->primspace,
201   - source->secspace,
202   - source->dft );
203   - */
204   - return EINVAL;
205   - }
206   -
207   - static void get_host(pipe_source *source) {
208   - send_text(source,strdup(lib3270_get_url(lib3270_get_default_session_handle())));
209   - }
210   -
211   - static void process_input(pipe_source *source, DWORD cbRead)
212   - {
213   - const struct hllapi_packet_query * query = ((struct hllapi_packet_query *) source->buffer);
214   -
215   - trace("%s id=%d",__FUNCTION__,query->packet_id);
216   -
217   - switch(query->packet_id)
218   - {
219   - case HLLAPI_PACKET_CONNECT:
220   - send_result(source,lib3270_reconnect( lib3270_get_default_session_handle(),
221   - ((struct hllapi_packet_connect *) source->buffer)->wait));
222   - break;
223   -
224   - case HLLAPI_PACKET_CONNECT_URL:
225   - send_result(source,lib3270_connect_url(lib3270_get_default_session_handle(),(const char *) (query+1),0));
226   - break;
227   -
228   - case HLLAPI_PACKET_SET_HOST:
229   - send_result(source,lib3270_set_url(lib3270_get_default_session_handle(),
230   - ((struct hllapi_packet_text *) source->buffer)->text));
231   - break;
232   -
233   - case HLLAPI_PACKET_GET_HOST:
234   - get_host(source);
235   - break;
236   -
237   - case HLLAPI_PACKET_DISCONNECT:
238   - send_result(source,lib3270_disconnect(lib3270_get_default_session_handle()));
239   - break;
240   -
241   - case HLLAPI_PACKET_IS_CONNECTED:
242   - send_result(source,lib3270_in_tn3270e(lib3270_get_default_session_handle()));
243   - break;
244   -
245   - case HLLAPI_PACKET_IS_READY:
246   - send_result(source,lib3270_is_ready(lib3270_get_default_session_handle()));
247   - break;
248   -
249   - case HLLAPI_PACKET_ENTER:
250   - send_result(source,lib3270_enter(lib3270_get_default_session_handle()));
251   - break;
252   -
253   - case HLLAPI_PACKET_PRINT:
254   - send_result(source,lib3270_print_all(lib3270_get_default_session_handle()));
255   - break;
256   -
257   - case HLLAPI_PACKET_ERASE:
258   - send_result(source,lib3270_erase(lib3270_get_default_session_handle()));
259   - break;
260   -
261   - case HLLAPI_PACKET_ERASE_EOF:
262   - send_result(source,lib3270_eraseeof(lib3270_get_default_session_handle()));
263   - break;
264   -
265   - case HLLAPI_PACKET_ERASE_EOL:
266   - send_result(source,lib3270_eraseeol(lib3270_get_default_session_handle()));
267   - break;
268   -
269   - case HLLAPI_PACKET_ERASE_INPUT:
270   - send_result(source,lib3270_eraseinput(lib3270_get_default_session_handle()));
271   - break;
272   -
273   - case HLLAPI_PACKET_PFKEY:
274   - send_result(source,lib3270_pfkey( lib3270_get_default_session_handle(),
275   - ((struct hllapi_packet_keycode *) source->buffer)->keycode));
276   - break;
277   -
278   - case HLLAPI_PACKET_PAKEY:
279   - send_result(source,lib3270_pakey( lib3270_get_default_session_handle(),
280   - ((struct hllapi_packet_keycode *) source->buffer)->keycode));
281   - break;
282   -
283   - case HLLAPI_PACKET_SET_CURSOR_POSITION:
284   - send_result(source,lib3270_set_cursor_position( lib3270_get_default_session_handle(),
285   - ((struct hllapi_packet_cursor *) source->buffer)->row,
286   - ((struct hllapi_packet_cursor *) source->buffer)->col));
287   - break;
288   -
289   - case HLLAPI_PACKET_SET_TEXT_AT:
290   - send_result(source,lib3270_set_text_at( lib3270_get_default_session_handle(),
291   - ((struct hllapi_packet_text_at *) source->buffer)->row,
292   - ((struct hllapi_packet_text_at *) source->buffer)->col,
293   - (unsigned char *) ((struct hllapi_packet_text_at *) source->buffer)->text));
294   - break;
295   -
296   - case HLLAPI_PACKET_GET_TEXT_AT:
297   - send_text(source,lib3270_get_string_at( lib3270_get_default_session_handle(),
298   - ((struct hllapi_packet_at *) source->buffer)->row,
299   - ((struct hllapi_packet_at *) source->buffer)->col,
300   - ((struct hllapi_packet_at *) source->buffer)->len,
301   - ((struct hllapi_packet_at *) source->buffer)->lf));
302   - break;
303   -
304   - case HLLAPI_PACKET_GET_TEXT_AT_OFFSET:
305   - send_text(source,lib3270_get_string_at_address( lib3270_get_default_session_handle(),
306   - ((struct hllapi_packet_query_offset *) source->buffer)->addr,
307   - ((struct hllapi_packet_query_offset *) source->buffer)->len,
308   - ((struct hllapi_packet_query_offset *) source->buffer)->lf));
309   - break;
310   -
311   - case HLLAPI_PACKET_CMP_TEXT_AT:
312   - send_result(source,lib3270_cmp_text_at( lib3270_get_default_session_handle(),
313   - ((struct hllapi_packet_text_at *) source->buffer)->row,
314   - ((struct hllapi_packet_text_at *) source->buffer)->col,
315   - ((struct hllapi_packet_text_at *) source->buffer)->text,
316   - ((struct hllapi_packet_text_at *) source->buffer)->lf));
317   - break;
318   -
319   - case HLLAPI_PACKET_INPUT_STRING:
320   - send_result(source,lib3270_input_string(lib3270_get_default_session_handle(),
321   - (unsigned char *) ((struct hllapi_packet_text *) source->buffer)->text));
322   - break;
323   -
324   - case HLLAPI_PACKET_EMULATE_INPUT:
325   - send_result(source,lib3270_emulate_input(lib3270_get_default_session_handle(),
326   - (const char *) ((struct hllapi_packet_emulate_input *) source->buffer)->text,
327   - (int) ((struct hllapi_packet_emulate_input *) source->buffer)->len,
328   - (int) ((struct hllapi_packet_emulate_input *) source->buffer)->pasting));
329   - break;
330   -
331   - case HLLAPI_PACKET_SET_CURSOR:
332   - send_result(source,lib3270_set_cursor_address(lib3270_get_default_session_handle(),
333   - ((struct hllapi_packet_addr *) source->buffer)->addr));
334   - break;
335   -
336   - case HLLAPI_PACKET_GET_CURSOR:
337   - send_result(source,lib3270_get_cursor_address(lib3270_get_default_session_handle()));
338   - break;
339   -
340   - case HLLAPI_PACKET_GET_WIDTH:
341   - send_result(source,lib3270_get_width(lib3270_get_default_session_handle()));
342   - break;
343   -
344   - case HLLAPI_PACKET_GET_HEIGHT:
345   - send_result(source,lib3270_get_height(lib3270_get_default_session_handle()));
346   - break;
347   -
348   - case HLLAPI_PACKET_GET_LENGTH:
349   - send_result(source,lib3270_get_length(lib3270_get_default_session_handle()));
350   - break;
351   -
352   - case HLLAPI_PACKET_GET_PROGRAM_MESSAGE:
353   - send_result(source,lib3270_get_program_message(lib3270_get_default_session_handle()));
354   - break;
355   -
356   - case HLLAPI_PACKET_GET_SSL_STATE:
357   - send_result(source,lib3270_get_secure(lib3270_get_default_session_handle()));
358   - break;
359   -
360   - case HLLAPI_PACKET_SET_UNLOCK_DELAY:
361   - lib3270_set_unlock_delay(lib3270_get_default_session_handle(),(unsigned short) ((struct hllapi_packet_set_int *) source->buffer)->value);
362   - send_result(source,0);
363   - break;
364   -
365   - case HLLAPI_PACKET_SET_TOGGLE:
366   - send_result(source,lib3270_set_toggle(lib3270_get_default_session_handle(),
367   - (LIB3270_TOGGLE) ((struct hllapi_packet_set *) source->buffer)->id,
368   - ((struct hllapi_packet_set *) source->buffer)->value));
369   - break;
370   -
371   - case HLLAPI_PACKET_FIELD_START:
372   - send_result(source,lib3270_get_field_start(lib3270_get_default_session_handle(),
373   - ((struct hllapi_packet_addr *) source->buffer)->addr));
374   - break;
375   -
376   -
377   - case HLLAPI_PACKET_FIELD_LEN:
378   - send_result(source,lib3270_get_field_len(lib3270_get_default_session_handle(),
379   - ((struct hllapi_packet_addr *) source->buffer)->addr));
380   - break;
381   -
382   - case HLLAPI_PACKET_NEXT_UNPROTECTED:
383   - send_result(source,lib3270_get_next_unprotected(lib3270_get_default_session_handle(),
384   - ((struct hllapi_packet_addr *) source->buffer)->addr));
385   - break;
386   -
387   - case HLLAPI_PACKET_IS_PROTECTED:
388   - send_result(source,lib3270_get_is_protected(lib3270_get_default_session_handle(),
389   - ((struct hllapi_packet_addr *) source->buffer)->addr));
390   - break;
391   -
392   - case HLLAPI_PACKET_IS_PROTECTED_AT:
393   - send_result(source,lib3270_get_is_protected_at( lib3270_get_default_session_handle(),
394   - ((struct hllapi_packet_query_at *) source->buffer)->row,
395   - ((struct hllapi_packet_query_at *) source->buffer)->col));
396   - break;
397   -
398   - case HLLAPI_PACKET_QUIT:
399   - gtk_main_quit();
400   - send_result(source,0);
401   - break;
402   -
403   - case HLLAPI_PACKET_SET_HOST_CHARSET:
404   - send_result(source,lib3270_set_host_charset( lib3270_get_default_session_handle(),
405   - (const char *) ((struct hllapi_packet_set_text *) source->buffer)->text));
406   - break;
407   -
408   - case HLLAPI_PACKET_ASC2EBC:
409   - send_text(source,(char *) lib3270_asc2ebc(
410   - lib3270_get_default_session_handle(),
411   - (unsigned char *) ((struct hllapi_packet_set_text *) source->buffer)->text,-1
412   - ));
413   - break;
414   -
415   - case HLLAPI_PACKET_EBC2ASC:
416   - send_text(source,(char *) lib3270_ebc2asc(
417   - lib3270_get_default_session_handle(),
418   - (unsigned char *) ((struct hllapi_packet_set_text *) source->buffer)->text,-1
419   - ));
420   - break;
421   -
422   - case HLLAPI_PACKET_FILE_TRANSFER:
423   - send_result(source,do_file_transfer((struct hllapi_packet_file_transfer *) source));
424   - break;
425   -
426   - case HLLAPI_PACKET_GET_HOST_CHARSET:
427   - trace("%s","HLLAPI_PACKET_GET_HOST_CHARSET");
428   - send_text(source,(char *) lib3270_get_host_charset(lib3270_get_default_session_handle()));
429   - break;
430   -
431   - case HLLAPI_PACKET_ACTION:
432   - send_result(source,lib3270_action(lib3270_get_default_session_handle(),
433   - (const char *) ((struct hllapi_packet_text *) source->buffer)->text));
434   - break;
435   -
436   -
437   - default:
438   - send_result(source, EINVAL);
439   - g_message("Invalid remote request (id=%d)",source->buffer[0]);
440   - }
441   -
442   - }
443   -
444   - static void read_input_pipe(pipe_source *source)
445   - {
446   - DWORD cbRead = 0;
447   -
448   - if(ReadFile(source->hPipe,source->buffer,PIPE_BUFFER_LENGTH,&cbRead,&source->overlap) && cbRead > 0)
449   - process_input(source,cbRead);
450   -
451   - // The read operation is still pending.
452   - switch(GetLastError())
453   - {
454   - case 0:
455   - break;
456   -
457   - case ERROR_IO_PENDING:
458   - // trace("%s: PIPE_STATE_PENDING_READ",__FUNCTION__);
459   - source->state = PIPE_STATE_PENDING_READ;
460   - break;
461   -
462   - case ERROR_PIPE_LISTENING:
463   - // trace("%s: ERROR_PIPE_LISTENING",__FUNCTION__);
464   - source->state = PIPE_STATE_READ;
465   - break;
466   -
467   - case ERROR_BROKEN_PIPE:
468   - trace("%s: ERROR_BROKEN_PIPE",__FUNCTION__);
469   -
470   - if(!DisconnectNamedPipe(source->hPipe))
471   - {
472   - set_active(FALSE);
473   - popup_lasterror("%s",_( "Error in DisconnectNamedPipe" ));
474   - }
475   - else
476   - {
477   - IO_accept(source);
478   - }
479   - break;
480   -
481   - case ERROR_PIPE_NOT_CONNECTED:
482   - trace("%s: ERROR_PIPE_NOT_CONNECTED",__FUNCTION__);
483   - set_active(FALSE);
484   - break;
485   -
486   - default:
487   - if(source->hPipe != INVALID_HANDLE_VALUE)
488   - popup_lasterror("%s",_( "Error receiving message from pipe" ) );
489   - }
490   -
491   - }
492   -
493   - static gboolean IO_dispatch(GSource *source, GSourceFunc callback, gpointer data)
494   - {
495   - /*
496   - * Called to dispatch the event source,
497   - * after it has returned TRUE in either its prepare or its check function.
498   - * The dispatch function is passed in a callback function and data.
499   - * The callback function may be NULL if the source was never connected
500   - * to a callback using g_source_set_callback(). The dispatch function
501   - * should call the callback function with user_data and whatever additional
502   - * parameters are needed for this type of event source.
503   - */
504   - BOOL fSuccess;
505   - DWORD cbRead = 0;
506   -// DWORD dwErr = 0;
507   -
508   - fSuccess = GetOverlappedResult(((pipe_source *) source)->hPipe,&((pipe_source *) source)->overlap,&cbRead,FALSE );
509   -
510   - // trace("%s: source=%p data=%p Result=%s cbRead=%d",__FUNCTION__,source,data,fSuccess ? "Success" : "Unsuccess",(int) cbRead);
511   -
512   - switch(((pipe_source *) source)->state)
513   - {
514   - case PIPE_STATE_WAITING:
515   - if(fSuccess)
516   - {
517   - trace("Pipe connected (cbRet=%d)",(int) cbRead);
518   - set_active(TRUE);
519   - ((pipe_source *) source)->state = PIPE_STATE_READ;
520   - }
521   - else
522   - {
523   - popup_lasterror("%s", _( "Pipe connection failed" ));
524   - }
525   - break;
526   -
527   - case PIPE_STATE_READ:
528   - // trace("Reading pipe (cbRead=%d)",(int) cbRead);
529   - read_input_pipe( (pipe_source *) source);
530   - break;
531   -
532   - case PIPE_STATE_PENDING_READ:
533   - if(fSuccess && cbRead > 0)
534   - process_input((pipe_source *) source,cbRead);
535   - ((pipe_source *) source)->state = PIPE_STATE_READ;
536   - break;
537   -
538   - case PIPE_STATE_UNDEFINED:
539   - break;
540   -
541   -//#ifdef DEBUG
542   -// default:
543   -// trace("%s: source=%p data=%p Unexpected mode %d",__FUNCTION__,source,data,((pipe_source *) source)->state);
544   -//#endif
545   - }
546   -
547   - return TRUE;
548   - }
549   -
550   - static void IO_finalize(GSource *source)
551   - {
552   -// trace("%s: source=%p",__FUNCTION__,source);
553   -
554   - if( ((pipe_source *) source)->hPipe != INVALID_HANDLE_VALUE)
555   - {
556   - CloseHandle(((pipe_source *) source)->hPipe);
557   - ((pipe_source *) source)->hPipe = INVALID_HANDLE_VALUE;
558   - }
559   -
560   - }
561   -
562   - static gboolean IO_closure(gpointer data)
563   - {
564   -// trace("%s: data=%p",__FUNCTION__,data);
565   - return 0;
566   - }
567   -
568   - void popup_lasterror(const gchar *fmt, ...)
569   - {
570   - char buffer[4096];
571   - va_list arg_ptr;
572   - int sz;
573   - DWORD errcode = GetLastError();
574   - char *ptr;
575   - LPVOID lpMsgBuf = 0;
576   -
577   - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
578   -
579   - for(ptr= (char *) lpMsgBuf;*ptr && *ptr != '\n';ptr++);
580   - *ptr = 0;
581   -
582   - va_start(arg_ptr, fmt);
583   - vsnprintf(buffer,4095,fmt,arg_ptr);
584   - va_end(arg_ptr);
585   -
586   - sz = strlen(buffer);
587   - snprintf(buffer+sz,4096-sz,": %s\n(rc=%d)",lpMsgBuf,(int) errcode);
588   -
589   - printf("%s\n",buffer);
590   -
591   -#ifdef DEBUG
592   - fprintf(stderr,"%s\n",buffer);
593   - fflush(stderr);
594   -#endif
595   -
596   - LocalFree(lpMsgBuf);
597   - }
598   -
599   - LIB3270_EXPORT int pw3270_plugin_start(GtkWidget *window, GtkWidget *terminal)
600   - {
601   - char id;
602   -
603   - for(id='A';id < 'Z';id++)
604   - {
605   - gchar * pipename = g_strdup_printf("\\\\.\\pipe\\%s_%c",pw3270_get_session_name(window),id);
606   - gchar * ptr;
607   - HANDLE hPipe;
608   -
609   - for(ptr=pipename;*ptr;ptr++)
610   - *ptr = g_ascii_tolower(*ptr);
611   -
612   - hPipe = CreateNamedPipe( TEXT(pipename), // pipe name
613   - PIPE_ACCESS_DUPLEX | // read/write access
614   - FILE_FLAG_OVERLAPPED, // overlapped mode
615   - PIPE_TYPE_MESSAGE | // pipe type
616   - PIPE_READMODE_MESSAGE | // pipe mode
617   - PIPE_WAIT, // blocking mode
618   - 1, // number of instances
619   - PIPE_BUFFER_LENGTH, // output buffer size
620   - PIPE_BUFFER_LENGTH, // input buffer size
621   - NMPWAIT_USE_DEFAULT_WAIT, // client time-out
622   - NULL); // default security attributes
623   -
624   - trace("%s = %p",pipename,hPipe);
625   - g_free(pipename);
626   -
627   - if(hPipe != INVALID_HANDLE_VALUE)
628   - {
629   - static GSourceFuncs pipe_source_funcs =
630   - {
631   - IO_prepare,
632   - IO_check,
633   - IO_dispatch,
634   - IO_finalize,
635   - IO_closure,
636   - NULL
637   - };
638   - pipe_source * source;
639   - gchar * session = g_strdup_printf("%s:%c",pw3270_get_session_name(window),id);
640   -
641   - pw3270_set_session_name(window,session);
642   - g_free(session);
643   -
644   - source = (pipe_source *) g_source_new(&pipe_source_funcs,sizeof(pipe_source));
645   -
646   - source->hPipe = hPipe;
647   - source->state = PIPE_STATE_WAITING;
648   - source->overlap.hEvent = CreateEvent( NULL,TRUE,TRUE,NULL);
649   -
650   - g_source_attach((GSource *) source,NULL);
651   - IO_accept(source);
652   -
653   - return 0;
654   - }
655   -
656   - }
657   -
658   - popup_lasterror( "%s", _( "Can´t create remote control pipe" ));
659   -
660   - return -1;
661   - }
662   -
663   - LIB3270_EXPORT int pw3270_plugin_stop(GtkWidget *window, GtkWidget *terminal)
664   - {
665   -
666   - return 0;
667   - }
668   -
669   - G_GNUC_INTERNAL void set_active(gboolean on)
670   - {
671   - trace("%s(%s)",__FUNCTION__,on ? "Active" : "Inactive");
672   - // v3270_set_script(v3270_get_default_widget(),'H');
673   - }
src/plugin/windows/main.c 0 → 100644
... ... @@ -0,0 +1,676 @@
  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. 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 - 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 + * Agradecimento:
  29 + *
  30 + * Hélio Passos
  31 + *
  32 + */
  33 +
  34 + #include "server.h"
  35 +
  36 +#ifdef _WIN32
  37 + #include <windows.h>
  38 +#else
  39 + #error HLLAPI is designed for windows.
  40 +#endif // _WIN32
  41 +
  42 + #include <pw3270/plugin.h>
  43 + #include <v3270.h>
  44 + #include <pw3270/ipcpackets.h>
  45 + #include <lib3270/actions.h>
  46 + #include <lib3270/charset.h>
  47 +
  48 +/*--[ Defines ]--------------------------------------------------------------------------------------*/
  49 +
  50 + #pragma pack(1)
  51 +
  52 + enum PIPE_STATE
  53 + {
  54 + PIPE_STATE_WAITING,
  55 + PIPE_STATE_READ,
  56 + PIPE_STATE_PENDING_READ,
  57 + PIPE_STATE_UNDEFINED
  58 + };
  59 +
  60 + typedef struct _pipe_source
  61 + {
  62 + GSource gsrc;
  63 + HANDLE hPipe;
  64 +
  65 + enum PIPE_STATE state;
  66 +
  67 + OVERLAPPED overlap;
  68 + unsigned char buffer[PIPE_BUFFER_LENGTH+1];
  69 + } pipe_source;
  70 +
  71 + #pragma pack()
  72 +
  73 +
  74 +/*--[ Globals ]--------------------------------------------------------------------------------------*/
  75 +
  76 +// static const gchar control_char = '@';
  77 +
  78 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  79 +
  80 + static void IO_accept(pipe_source *source)
  81 + {
  82 + set_active(FALSE);
  83 +
  84 + if(ConnectNamedPipe(source->hPipe,&source->overlap))
  85 + {
  86 + popup_lasterror("%s",_( "Error in ConnectNamedPipe" ));
  87 + return;
  88 + }
  89 +
  90 + switch(GetLastError())
  91 + {
  92 + // The overlapped connection in progress.
  93 + case ERROR_IO_PENDING:
  94 + // trace("%s: ERROR_IO_PENDING",__FUNCTION__);
  95 + source->state = PIPE_STATE_WAITING;
  96 + break;
  97 +
  98 + // Client is already connected, so signal an event.
  99 + case ERROR_PIPE_CONNECTED:
  100 + trace("%s: ERROR_PIPE_CONNECTED",__FUNCTION__);
  101 + set_active(TRUE);
  102 + if(SetEvent(source->overlap.hEvent))
  103 + break;
  104 +
  105 + // If an error occurs during the connect operation...
  106 + default:
  107 + popup_lasterror("%s", _( "ConnectNamedPipe failed" ));
  108 + }
  109 +
  110 + }
  111 +
  112 + static gboolean IO_prepare(GSource *source, gint *timeout)
  113 + {
  114 + /*
  115 + * Called before all the file descriptors are polled.
  116 + * If the source can determine that it is ready here
  117 + * (without waiting for the results of the poll() call)
  118 + * it should return TRUE.
  119 + *
  120 + * It can also return a timeout_ value which should be the maximum
  121 + * timeout (in milliseconds) which should be passed to the poll() call.
  122 + * The actual timeout used will be -1 if all sources returned -1,
  123 + * or it will be the minimum of all the timeout_ values
  124 + * returned which were >= 0.
  125 + *
  126 + */
  127 + if(WaitForSingleObject(((pipe_source *) source)->overlap.hEvent,0) == WAIT_OBJECT_0)
  128 + return TRUE;
  129 +
  130 + *timeout = 10;
  131 + return FALSE;
  132 + }
  133 +
  134 + static gboolean IO_check(GSource *source)
  135 + {
  136 + /*
  137 + * Called after all the file descriptors are polled.
  138 + * The source should return TRUE if it is ready to be dispatched.
  139 + * Note that some time may have passed since the previous prepare
  140 + * function was called, so the source should be checked again here.
  141 + *
  142 + */
  143 + if(WaitForSingleObject(((pipe_source *) source)->overlap.hEvent,0) == WAIT_OBJECT_0)
  144 + return TRUE;
  145 +
  146 + return FALSE;
  147 + }
  148 +
  149 + static void send_text(pipe_source *source, char *text)
  150 + {
  151 + struct hllapi_packet_text *pkt;
  152 + DWORD szBlock;
  153 + int f;
  154 +
  155 + if(text)
  156 + {
  157 + szBlock = sizeof(struct hllapi_packet_text)+strlen(text);
  158 + pkt = (struct hllapi_packet_text *) g_malloc0(szBlock);
  159 + pkt->packet_id = 0;
  160 + strcpy(pkt->text,text);
  161 + lib3270_free(text);
  162 + }
  163 + else
  164 + {
  165 + szBlock = sizeof(struct hllapi_packet_text);
  166 + pkt = (struct hllapi_packet_text *) g_malloc0(szBlock);
  167 + pkt->packet_id = errno ? errno : -1;
  168 + }
  169 +
  170 + trace("szBlock=%d text=\"%s\"",szBlock, ( (struct hllapi_packet_text *) pkt)->text);
  171 + for(f=0;f< (int) szBlock;f++)
  172 + {
  173 + trace("rsp(%d)= %d \"%s\"",f,* (((char *) pkt)+f),((char *) pkt)+f);
  174 + }
  175 +
  176 + WriteFile(source->hPipe,pkt,szBlock,&szBlock,NULL);
  177 +
  178 + g_free(pkt);
  179 + }
  180 +
  181 + static void send_result(pipe_source *source, int rc)
  182 + {
  183 + struct hllapi_packet_result pkt = { rc };
  184 + DWORD wrote = sizeof(pkt);
  185 + WriteFile(source->hPipe,&pkt,wrote,&wrote,NULL);
  186 + }
  187 +
  188 + static int do_file_transfer(struct hllapi_packet_file_transfer * source)
  189 + {
  190 + /*
  191 + const gchar * local = (const char *) source->text;
  192 + const gchar * remote = (const char *) (local+strlen(local)+1);
  193 +
  194 + return v3270_transfer_file( v3270_get_default_widget(),
  195 + (LIB3270_FT_OPTION) source->options,
  196 + local,
  197 + remote,
  198 + source->lrecl,
  199 + source->blksize,
  200 + source->primspace,
  201 + source->secspace,
  202 + source->dft );
  203 + */
  204 + return EINVAL;
  205 + }
  206 +
  207 + static void get_host(pipe_source *source) {
  208 + send_text(source,strdup(lib3270_get_url(lib3270_get_default_session_handle())));
  209 + }
  210 +
  211 + static void process_input(pipe_source *source, DWORD cbRead)
  212 + {
  213 + const struct hllapi_packet_query * query = ((struct hllapi_packet_query *) source->buffer);
  214 +
  215 + trace("%s id=%d",__FUNCTION__,query->packet_id);
  216 +
  217 + switch(query->packet_id)
  218 + {
  219 + case HLLAPI_PACKET_CONNECT:
  220 + send_result(source,lib3270_reconnect( lib3270_get_default_session_handle(),
  221 + ((struct hllapi_packet_connect *) source->buffer)->wait));
  222 + break;
  223 +
  224 + case HLLAPI_PACKET_CONNECT_URL:
  225 + send_result(source,lib3270_connect_url(lib3270_get_default_session_handle(),(const char *) (query+1),0));
  226 + break;
  227 +
  228 + case HLLAPI_PACKET_SET_HOST:
  229 + send_result(source,lib3270_set_url(lib3270_get_default_session_handle(),
  230 + ((struct hllapi_packet_text *) source->buffer)->text));
  231 + break;
  232 +
  233 + case HLLAPI_PACKET_GET_HOST:
  234 + get_host(source);
  235 + break;
  236 +
  237 + case HLLAPI_PACKET_DISCONNECT:
  238 + send_result(source,lib3270_disconnect(lib3270_get_default_session_handle()));
  239 + break;
  240 +
  241 + case HLLAPI_PACKET_IS_CONNECTED:
  242 + send_result(source,lib3270_in_tn3270e(lib3270_get_default_session_handle()));
  243 + break;
  244 +
  245 + case HLLAPI_PACKET_IS_READY:
  246 + send_result(source,lib3270_is_ready(lib3270_get_default_session_handle()));
  247 + break;
  248 +
  249 + case HLLAPI_PACKET_ENTER:
  250 + send_result(source,lib3270_enter(lib3270_get_default_session_handle()));
  251 + break;
  252 +
  253 + case HLLAPI_PACKET_PRINT:
  254 + send_result(source,lib3270_print_all(lib3270_get_default_session_handle()));
  255 + break;
  256 +
  257 + case HLLAPI_PACKET_ERASE:
  258 + send_result(source,lib3270_erase(lib3270_get_default_session_handle()));
  259 + break;
  260 +
  261 + case HLLAPI_PACKET_ERASE_EOF:
  262 + send_result(source,lib3270_eraseeof(lib3270_get_default_session_handle()));
  263 + break;
  264 +
  265 + case HLLAPI_PACKET_ERASE_EOL:
  266 + send_result(source,lib3270_eraseeol(lib3270_get_default_session_handle()));
  267 + break;
  268 +
  269 + case HLLAPI_PACKET_ERASE_INPUT:
  270 + send_result(source,lib3270_eraseinput(lib3270_get_default_session_handle()));
  271 + break;
  272 +
  273 + case HLLAPI_PACKET_PFKEY:
  274 + send_result(source,lib3270_pfkey( lib3270_get_default_session_handle(),
  275 + ((struct hllapi_packet_keycode *) source->buffer)->keycode));
  276 + break;
  277 +
  278 + case HLLAPI_PACKET_PAKEY:
  279 + send_result(source,lib3270_pakey( lib3270_get_default_session_handle(),
  280 + ((struct hllapi_packet_keycode *) source->buffer)->keycode));
  281 + break;
  282 +
  283 + case HLLAPI_PACKET_SET_CURSOR_POSITION:
  284 + send_result(source,lib3270_set_cursor_position( lib3270_get_default_session_handle(),
  285 + ((struct hllapi_packet_cursor *) source->buffer)->row,
  286 + ((struct hllapi_packet_cursor *) source->buffer)->col));
  287 + break;
  288 +
  289 + case HLLAPI_PACKET_SET_TEXT_AT:
  290 + send_result(source,lib3270_set_text_at( lib3270_get_default_session_handle(),
  291 + ((struct hllapi_packet_text_at *) source->buffer)->row,
  292 + ((struct hllapi_packet_text_at *) source->buffer)->col,
  293 + (unsigned char *) ((struct hllapi_packet_text_at *) source->buffer)->text));
  294 + break;
  295 +
  296 + case HLLAPI_PACKET_GET_TEXT_AT:
  297 + send_text(source,lib3270_get_string_at( lib3270_get_default_session_handle(),
  298 + ((struct hllapi_packet_at *) source->buffer)->row,
  299 + ((struct hllapi_packet_at *) source->buffer)->col,
  300 + ((struct hllapi_packet_at *) source->buffer)->len,
  301 + ((struct hllapi_packet_at *) source->buffer)->lf));
  302 + break;
  303 +
  304 + case HLLAPI_PACKET_GET_TEXT_AT_OFFSET:
  305 + send_text(source,lib3270_get_string_at_address( lib3270_get_default_session_handle(),
  306 + ((struct hllapi_packet_query_offset *) source->buffer)->addr,
  307 + ((struct hllapi_packet_query_offset *) source->buffer)->len,
  308 + ((struct hllapi_packet_query_offset *) source->buffer)->lf));
  309 + break;
  310 +
  311 + case HLLAPI_PACKET_CMP_TEXT_AT:
  312 + send_result(source,lib3270_cmp_text_at( lib3270_get_default_session_handle(),
  313 + ((struct hllapi_packet_text_at *) source->buffer)->row,
  314 + ((struct hllapi_packet_text_at *) source->buffer)->col,
  315 + ((struct hllapi_packet_text_at *) source->buffer)->text,
  316 + ((struct hllapi_packet_text_at *) source->buffer)->lf));
  317 + break;
  318 +
  319 + case HLLAPI_PACKET_INPUT_STRING:
  320 + send_result(source,lib3270_input_string(lib3270_get_default_session_handle(),
  321 + (unsigned char *) ((struct hllapi_packet_text *) source->buffer)->text));
  322 + break;
  323 +
  324 + case HLLAPI_PACKET_EMULATE_INPUT:
  325 + send_result(source,lib3270_emulate_input(lib3270_get_default_session_handle(),
  326 + (const char *) ((struct hllapi_packet_emulate_input *) source->buffer)->text,
  327 + (int) ((struct hllapi_packet_emulate_input *) source->buffer)->len,
  328 + (int) ((struct hllapi_packet_emulate_input *) source->buffer)->pasting));
  329 + break;
  330 +
  331 + case HLLAPI_PACKET_SET_CURSOR:
  332 + send_result(source,lib3270_set_cursor_address(lib3270_get_default_session_handle(),
  333 + ((struct hllapi_packet_addr *) source->buffer)->addr));
  334 + break;
  335 +
  336 + case HLLAPI_PACKET_GET_CURSOR:
  337 + send_result(source,lib3270_get_cursor_address(lib3270_get_default_session_handle()));
  338 + break;
  339 +
  340 + case HLLAPI_PACKET_GET_WIDTH:
  341 + send_result(source,lib3270_get_width(lib3270_get_default_session_handle()));
  342 + break;
  343 +
  344 + case HLLAPI_PACKET_GET_HEIGHT:
  345 + send_result(source,lib3270_get_height(lib3270_get_default_session_handle()));
  346 + break;
  347 +
  348 + case HLLAPI_PACKET_GET_LENGTH:
  349 + send_result(source,lib3270_get_length(lib3270_get_default_session_handle()));
  350 + break;
  351 +
  352 + case HLLAPI_PACKET_GET_PROGRAM_MESSAGE:
  353 + send_result(source,lib3270_get_program_message(lib3270_get_default_session_handle()));
  354 + break;
  355 +
  356 + case HLLAPI_PACKET_GET_SSL_STATE:
  357 + send_result(source,lib3270_get_secure(lib3270_get_default_session_handle()));
  358 + break;
  359 +
  360 + case HLLAPI_PACKET_SET_UNLOCK_DELAY:
  361 + lib3270_set_unlock_delay(lib3270_get_default_session_handle(),(unsigned short) ((struct hllapi_packet_set_int *) source->buffer)->value);
  362 + send_result(source,0);
  363 + break;
  364 +
  365 + case HLLAPI_PACKET_SET_TOGGLE:
  366 + send_result(source,lib3270_set_toggle(lib3270_get_default_session_handle(),
  367 + (LIB3270_TOGGLE) ((struct hllapi_packet_set *) source->buffer)->id,
  368 + ((struct hllapi_packet_set *) source->buffer)->value));
  369 + break;
  370 +
  371 + case HLLAPI_PACKET_FIELD_START:
  372 + send_result(source,lib3270_get_field_start(lib3270_get_default_session_handle(),
  373 + ((struct hllapi_packet_addr *) source->buffer)->addr));
  374 + break;
  375 +
  376 +
  377 + case HLLAPI_PACKET_FIELD_LEN:
  378 + send_result(source,lib3270_get_field_len(lib3270_get_default_session_handle(),
  379 + ((struct hllapi_packet_addr *) source->buffer)->addr));
  380 + break;
  381 +
  382 + case HLLAPI_PACKET_NEXT_UNPROTECTED:
  383 + send_result(source,lib3270_get_next_unprotected(lib3270_get_default_session_handle(),
  384 + ((struct hllapi_packet_addr *) source->buffer)->addr));
  385 + break;
  386 +
  387 + case HLLAPI_PACKET_IS_PROTECTED:
  388 + send_result(source,lib3270_get_is_protected(lib3270_get_default_session_handle(),
  389 + ((struct hllapi_packet_addr *) source->buffer)->addr));
  390 + break;
  391 +
  392 + case HLLAPI_PACKET_IS_PROTECTED_AT:
  393 + send_result(source,lib3270_get_is_protected_at( lib3270_get_default_session_handle(),
  394 + ((struct hllapi_packet_query_at *) source->buffer)->row,
  395 + ((struct hllapi_packet_query_at *) source->buffer)->col));
  396 + break;
  397 +
  398 + case HLLAPI_PACKET_QUIT:
  399 + gtk_main_quit();
  400 + send_result(source,0);
  401 + break;
  402 +
  403 + case HLLAPI_PACKET_SET_HOST_CHARSET:
  404 + send_result(source,lib3270_set_host_charset( lib3270_get_default_session_handle(),
  405 + (const char *) ((struct hllapi_packet_set_text *) source->buffer)->text));
  406 + break;
  407 +
  408 + case HLLAPI_PACKET_ASC2EBC:
  409 + send_text(source,(char *) lib3270_asc2ebc(
  410 + lib3270_get_default_session_handle(),
  411 + (unsigned char *) ((struct hllapi_packet_set_text *) source->buffer)->text,-1
  412 + ));
  413 + break;
  414 +
  415 + case HLLAPI_PACKET_EBC2ASC:
  416 + send_text(source,(char *) lib3270_ebc2asc(
  417 + lib3270_get_default_session_handle(),
  418 + (unsigned char *) ((struct hllapi_packet_set_text *) source->buffer)->text,-1
  419 + ));
  420 + break;
  421 +
  422 + case HLLAPI_PACKET_FILE_TRANSFER:
  423 + send_result(source,do_file_transfer((struct hllapi_packet_file_transfer *) source));
  424 + break;
  425 +
  426 + case HLLAPI_PACKET_GET_HOST_CHARSET:
  427 + trace("%s","HLLAPI_PACKET_GET_HOST_CHARSET");
  428 + send_text(source,(char *) lib3270_get_host_charset(lib3270_get_default_session_handle()));
  429 + break;
  430 +
  431 + case HLLAPI_PACKET_ACTION:
  432 + send_result(source,lib3270_action(lib3270_get_default_session_handle(),
  433 + (const char *) ((struct hllapi_packet_text *) source->buffer)->text));
  434 + break;
  435 +
  436 +
  437 + default:
  438 + send_result(source, EINVAL);
  439 + g_message("Invalid remote request (id=%d)",source->buffer[0]);
  440 + }
  441 +
  442 + }
  443 +
  444 + static void read_input_pipe(pipe_source *source)
  445 + {
  446 + DWORD cbRead = 0;
  447 +
  448 + if(ReadFile(source->hPipe,source->buffer,PIPE_BUFFER_LENGTH,&cbRead,&source->overlap) && cbRead > 0)
  449 + process_input(source,cbRead);
  450 +
  451 + // The read operation is still pending.
  452 + switch(GetLastError())
  453 + {
  454 + case 0:
  455 + break;
  456 +
  457 + case ERROR_IO_PENDING:
  458 + // trace("%s: PIPE_STATE_PENDING_READ",__FUNCTION__);
  459 + source->state = PIPE_STATE_PENDING_READ;
  460 + break;
  461 +
  462 + case ERROR_PIPE_LISTENING:
  463 + // trace("%s: ERROR_PIPE_LISTENING",__FUNCTION__);
  464 + source->state = PIPE_STATE_READ;
  465 + break;
  466 +
  467 + case ERROR_BROKEN_PIPE:
  468 + trace("%s: ERROR_BROKEN_PIPE",__FUNCTION__);
  469 +
  470 + if(!DisconnectNamedPipe(source->hPipe))
  471 + {
  472 + set_active(FALSE);
  473 + popup_lasterror("%s",_( "Error in DisconnectNamedPipe" ));
  474 + }
  475 + else
  476 + {
  477 + IO_accept(source);
  478 + }
  479 + break;
  480 +
  481 + case ERROR_PIPE_NOT_CONNECTED:
  482 + trace("%s: ERROR_PIPE_NOT_CONNECTED",__FUNCTION__);
  483 + set_active(FALSE);
  484 + break;
  485 +
  486 + default:
  487 + if(source->hPipe != INVALID_HANDLE_VALUE)
  488 + popup_lasterror("%s",_( "Error receiving message from pipe" ) );
  489 + }
  490 +
  491 + }
  492 +
  493 + static gboolean IO_dispatch(GSource *source, GSourceFunc callback, gpointer data)
  494 + {
  495 + /*
  496 + * Called to dispatch the event source,
  497 + * after it has returned TRUE in either its prepare or its check function.
  498 + * The dispatch function is passed in a callback function and data.
  499 + * The callback function may be NULL if the source was never connected
  500 + * to a callback using g_source_set_callback(). The dispatch function
  501 + * should call the callback function with user_data and whatever additional
  502 + * parameters are needed for this type of event source.
  503 + */
  504 + BOOL fSuccess;
  505 + DWORD cbRead = 0;
  506 +// DWORD dwErr = 0;
  507 +
  508 + fSuccess = GetOverlappedResult(((pipe_source *) source)->hPipe,&((pipe_source *) source)->overlap,&cbRead,FALSE );
  509 +
  510 + // trace("%s: source=%p data=%p Result=%s cbRead=%d",__FUNCTION__,source,data,fSuccess ? "Success" : "Unsuccess",(int) cbRead);
  511 +
  512 + switch(((pipe_source *) source)->state)
  513 + {
  514 + case PIPE_STATE_WAITING:
  515 + if(fSuccess)
  516 + {
  517 + trace("Pipe connected (cbRet=%d)",(int) cbRead);
  518 + set_active(TRUE);
  519 + ((pipe_source *) source)->state = PIPE_STATE_READ;
  520 + }
  521 + else
  522 + {
  523 + popup_lasterror("%s", _( "Pipe connection failed" ));
  524 + }
  525 + break;
  526 +
  527 + case PIPE_STATE_READ:
  528 + // trace("Reading pipe (cbRead=%d)",(int) cbRead);
  529 + read_input_pipe( (pipe_source *) source);
  530 + break;
  531 +
  532 + case PIPE_STATE_PENDING_READ:
  533 + if(fSuccess && cbRead > 0)
  534 + process_input((pipe_source *) source,cbRead);
  535 + ((pipe_source *) source)->state = PIPE_STATE_READ;
  536 + break;
  537 +
  538 + case PIPE_STATE_UNDEFINED:
  539 + break;
  540 +
  541 +//#ifdef DEBUG
  542 +// default:
  543 +// trace("%s: source=%p data=%p Unexpected mode %d",__FUNCTION__,source,data,((pipe_source *) source)->state);
  544 +//#endif
  545 + }
  546 +
  547 + return TRUE;
  548 + }
  549 +
  550 + static void IO_finalize(GSource *source)
  551 + {
  552 +// trace("%s: source=%p",__FUNCTION__,source);
  553 +
  554 + if( ((pipe_source *) source)->hPipe != INVALID_HANDLE_VALUE)
  555 + {
  556 + CloseHandle(((pipe_source *) source)->hPipe);
  557 + ((pipe_source *) source)->hPipe = INVALID_HANDLE_VALUE;
  558 + }
  559 +
  560 + }
  561 +
  562 + static gboolean IO_closure(gpointer data)
  563 + {
  564 +// trace("%s: data=%p",__FUNCTION__,data);
  565 + return 0;
  566 + }
  567 +
  568 + void popup_lasterror(const gchar *fmt, ...)
  569 + {
  570 + char buffer[4096];
  571 + va_list arg_ptr;
  572 + int sz;
  573 + DWORD errcode = GetLastError();
  574 + char *ptr;
  575 + LPVOID lpMsgBuf = 0;
  576 +
  577 + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
  578 +
  579 + for(ptr= (char *) lpMsgBuf;*ptr && *ptr != '\n';ptr++);
  580 + *ptr = 0;
  581 +
  582 + va_start(arg_ptr, fmt);
  583 + vsnprintf(buffer,4095,fmt,arg_ptr);
  584 + va_end(arg_ptr);
  585 +
  586 + sz = strlen(buffer);
  587 + snprintf(buffer+sz,4096-sz,": %s\n(rc=%d)",lpMsgBuf,(int) errcode);
  588 +
  589 + printf("%s\n",buffer);
  590 +
  591 +#ifdef DEBUG
  592 + fprintf(stderr,"%s\n",buffer);
  593 + fflush(stderr);
  594 +#endif
  595 +
  596 + LocalFree(lpMsgBuf);
  597 + }
  598 +
  599 + LIB3270_EXPORT int pw3270_plugin_start(GtkWidget *window, GtkWidget *terminal)
  600 + {
  601 + char id;
  602 + const gchar * name = "pw3270";
  603 +
  604 + for(id='A';id < 'Z';id++)
  605 + {
  606 + gchar * pipename = g_strdup_printf("\\\\.\\pipe\\%s_%c",name,id);
  607 + gchar * ptr;
  608 + HANDLE hPipe;
  609 +
  610 + for(ptr=pipename;*ptr;ptr++)
  611 + *ptr = g_ascii_tolower(*ptr);
  612 +
  613 + hPipe = CreateNamedPipe( TEXT(pipename), // pipe name
  614 + PIPE_ACCESS_DUPLEX | // read/write access
  615 + FILE_FLAG_OVERLAPPED, // overlapped mode
  616 + PIPE_TYPE_MESSAGE | // pipe type
  617 + PIPE_READMODE_MESSAGE | // pipe mode
  618 + PIPE_WAIT, // blocking mode
  619 + 1, // number of instances
  620 + PIPE_BUFFER_LENGTH, // output buffer size
  621 + PIPE_BUFFER_LENGTH, // input buffer size
  622 + NMPWAIT_USE_DEFAULT_WAIT, // client time-out
  623 + NULL); // default security attributes
  624 +
  625 + trace("%s = %p",pipename,hPipe);
  626 + g_free(pipename);
  627 +
  628 + if(hPipe != INVALID_HANDLE_VALUE)
  629 + {
  630 + static GSourceFuncs pipe_source_funcs =
  631 + {
  632 + IO_prepare,
  633 + IO_check,
  634 + IO_dispatch,
  635 + IO_finalize,
  636 + IO_closure,
  637 + NULL
  638 + };
  639 + pipe_source * source;
  640 + gchar * session = g_strdup_printf("%s:%c",name,id);
  641 +
  642 + // pw3270_set_session_name(window,session);
  643 + v3270_set_session_name(terminal,session);
  644 +
  645 + g_free(session);
  646 +
  647 + source = (pipe_source *) g_source_new(&pipe_source_funcs,sizeof(pipe_source));
  648 +
  649 + source->hPipe = hPipe;
  650 + source->state = PIPE_STATE_WAITING;
  651 + source->overlap.hEvent = CreateEvent( NULL,TRUE,TRUE,NULL);
  652 +
  653 + g_source_attach((GSource *) source,NULL);
  654 + IO_accept(source);
  655 +
  656 + return 0;
  657 + }
  658 +
  659 + }
  660 +
  661 + popup_lasterror( "%s", _( "Can´t create remote control pipe" ));
  662 +
  663 + return -1;
  664 + }
  665 +
  666 + LIB3270_EXPORT int pw3270_plugin_stop(GtkWidget *window, GtkWidget *terminal)
  667 + {
  668 +
  669 + return 0;
  670 + }
  671 +
  672 + G_GNUC_INTERNAL void set_active(gboolean on)
  673 + {
  674 + trace("%s(%s)",__FUNCTION__,on ? "Active" : "Inactive");
  675 + // v3270_set_script(v3270_get_default_widget(),'H');
  676 + }
... ...