Commit 9c1b63e1969f13aa7a66bdc429722902e10d56ed

Authored by Perry Werneck
1 parent 58bff019
Exists in master and in 1 other branch develop

Importing windows pipe service.

pw3270-plugin-ipc.cbp
... ... @@ -89,6 +89,13 @@
89 89 <Unit filename="src/testprogram/testprogram.c">
90 90 <Option compilerVar="CC" />
91 91 </Unit>
  92 + <Unit filename="src/windows/gobject.c">
  93 + <Option compilerVar="CC" />
  94 + </Unit>
  95 + <Unit filename="src/windows/gobject.h" />
  96 + <Unit filename="src/windows/pipesource.c">
  97 + <Option compilerVar="CC" />
  98 + </Unit>
92 99 <Extensions>
93 100 <code_completion />
94 101 <envvars />
... ...
src/linux/gobject.h
... ... @@ -29,13 +29,13 @@
29 29 */
30 30  
31 31 /**
32   - * @brief Private definitions for pw3270 IPC linux plugin.
  32 + * @brief Private definitions for pw3270 IPC linux module.
33 33 *
34 34 */
35 35  
36   -#ifndef LINUX_PRIVATE_H_INCLUDED
  36 +#ifndef LINUX_GOBJECT_H_INCLUDED
37 37  
38   - #define LINUX_PRIVATE_H_INCLUDED
  38 + #define LINUX_GOBJECT_H_INCLUDED
39 39  
40 40 #include <config.h>
41 41  
... ... @@ -72,4 +72,4 @@
72 72  
73 73 G_END_DECLS
74 74  
75   -#endif // LINUX_PRIVATE_H_INCLUDED
  75 +#endif // LINUX_GOBJECT_H_INCLUDED
... ...
src/windows/gobject.c 0 → 100644
... ... @@ -0,0 +1,125 @@
  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 gobject.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 + */
  29 +
  30 +#include "gobject.h"
  31 +#include <lib3270.h>
  32 +#include <lib3270/actions.h>
  33 +#include <lib3270/properties.h>
  34 +
  35 +G_DEFINE_TYPE(ipc3270, ipc3270, G_TYPE_OBJECT)
  36 +
  37 +static void ipc3270_finalize(GObject *object) {
  38 +
  39 + ipc3270 * ipc = IPC3270(object);
  40 +
  41 +
  42 + G_OBJECT_CLASS(ipc3270_parent_class)->finalize(object);
  43 +}
  44 +
  45 +
  46 +static void ipc3270_class_init(ipc3270Class *klass) {
  47 +
  48 + debug("%s",__FUNCTION__);
  49 +
  50 + GObjectClass *object_class;
  51 + object_class = G_OBJECT_CLASS (klass);
  52 + object_class->finalize = ipc3270_finalize;
  53 +
  54 +}
  55 +
  56 +static void ipc3270_init(ipc3270 *object) {
  57 +
  58 + debug("%s",__FUNCTION__);
  59 + object->error_domain = g_quark_from_static_string(PACKAGE_NAME);
  60 +
  61 +}
  62 +
  63 +GObject * ipc3270_new() {
  64 + return g_object_new(GLIB_TYPE_IPC3270, NULL);
  65 +}
  66 +
  67 +void ipc3270_set_session(GObject *object, H3270 *hSession, const char *name, GError **error) {
  68 +
  69 + char id;
  70 +
  71 + ipc3270 * ipc = IPC3270(object);
  72 + ipc->hSession = hSession;
  73 +
  74 + for(id='A';id < 'Z';id++) {
  75 +
  76 + gchar * pipename = g_strdup_printf("\\\\.\\pipe\\%s\\%c",name,id);
  77 + gchar * ptr;
  78 + HANDLE hPipe;
  79 +
  80 + for(ptr=pipename;*ptr;ptr++)
  81 + *ptr = g_ascii_tolower(*ptr);
  82 +
  83 + hPipe = CreateNamedPipe( TEXT(pipename), // pipe name
  84 + PIPE_ACCESS_DUPLEX | // read/write access
  85 + FILE_FLAG_OVERLAPPED, // overlapped mode
  86 + PIPE_TYPE_MESSAGE | // pipe type
  87 + PIPE_READMODE_MESSAGE | // pipe mode
  88 + PIPE_WAIT, // blocking mode
  89 + 1, // number of instances
  90 + PIPE_BUFFER_LENGTH, // output buffer size
  91 + PIPE_BUFFER_LENGTH, // input buffer size
  92 + NMPWAIT_USE_DEFAULT_WAIT, // client time-out
  93 + NULL); // default security attributes
  94 +
  95 + debug("%s = %p",pipename,hPipe);
  96 + g_free(pipename);
  97 +
  98 + if(hPipe != INVALID_HANDLE_VALUE) {
  99 +
  100 + ipc->source = (IPC3270_PIPE_SOURCE *) g_source_new(&pipe_source_funcs,sizeof(IPC3270_PIPE_SOURCE));
  101 +
  102 + lib3270_set_session_id(ipc->hSession, id);
  103 +
  104 + ipc->source->hPipe = hPipe;
  105 + ipc->source->state = PIPE_STATE_WAITING;
  106 + ipc->source->overlap.hEvent = CreateEvent( NULL,TRUE,TRUE,NULL);
  107 +
  108 + g_source_attach((GSource *) ipc->source,NULL);
  109 +
  110 + // IO_accept(source);
  111 + ipc3270_wait_for_client(ipc->source);
  112 +
  113 + break;
  114 + }
  115 +
  116 + }
  117 +
  118 +
  119 +}
  120 +
  121 +const gchar * ipc3270_get_display_charset(GObject *object) {
  122 + return lib3270_get_display_charset(IPC3270(object)->hSession);
  123 +}
  124 +
  125 +
... ...
src/windows/gobject.h 0 → 100644
... ... @@ -0,0 +1,93 @@
  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
  5 + * o nome G3270.
  6 + *
  7 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  8 + *
  9 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  10 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  11 + * Free Software Foundation.
  12 + *
  13 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  14 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  15 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  16 + * obter mais detalhes.
  17 + *
  18 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  19 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  20 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * Este programa está nomeado como - e possui - linhas de código.
  23 + *
  24 + * Contatos:
  25 + *
  26 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  27 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  28 + *
  29 + */
  30 +
  31 + /**
  32 + * @brief Private definitions for pw3270 IPC windows module.
  33 + *
  34 + */
  35 +
  36 +#ifndef WINDOWS_GOBJECT_H_INCLUDED
  37 +
  38 + #define WINDOWS_GOBJECT_H_INCLUDED
  39 +
  40 + #include <windows.h>
  41 + #include <config.h>
  42 +
  43 + #define ENABLE_NLS
  44 + #define GETTEXT_PACKAGE PACKAGE_NAME
  45 +
  46 + #include <libintl.h>
  47 + #include <glib/gi18n.h>
  48 + #include <gio/gio.h>
  49 +
  50 + #include <lib3270.h>
  51 + #include <lib3270/ipc.h>
  52 +
  53 + #define PIPE_BUFFER_LENGTH 8192
  54 +
  55 + G_BEGIN_DECLS
  56 +
  57 + typedef struct _ipc3270 ipc3270;
  58 + typedef struct _ipc3270Class ipc3270Class;
  59 +
  60 + typedef enum _ipc3270_pipe_state {
  61 + PIPE_STATE_WAITING,
  62 + PIPE_STATE_READ,
  63 + PIPE_STATE_PENDING_READ,
  64 + PIPE_STATE_UNDEFINED
  65 + } IPC3270_PIPE_STATE;
  66 +
  67 + typedef struct _ipc3270_pipe_source {
  68 + GSource gsrc;
  69 + HANDLE hPipe;
  70 +
  71 + enum PIPE_STATE state;
  72 +
  73 + OVERLAPPED overlap;
  74 + unsigned char buffer[PIPE_BUFFER_LENGTH+1];
  75 + } IPC3270_PIPE_SOURCE;
  76 +
  77 + struct _ipc3270 {
  78 + H3270 * hSession;
  79 + IPC3270_PIPE_SOURCE * source;
  80 + GQuark error_domain;
  81 + };
  82 +
  83 + struct _ipc3270Class {
  84 + GObjectClass parent;
  85 + };
  86 +
  87 + G_GNUC_INTERNAL GSourceFuncs ipc3270_source_funcs;
  88 +
  89 + G_GNUC_INTERNAL void ipc3270_wait_for_client(IPC3270_PIPE_SOURCE *source);
  90 +
  91 + G_END_DECLS
  92 +
  93 +#endif // WINDOWS_GOBJECT_H_INCLUDED
... ...
src/windows/pipesource.c 0 → 100644
... ... @@ -0,0 +1,210 @@
  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 pipesource.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 + */
  29 +
  30 +#include "gobject.h"
  31 +
  32 +void ipc3270_wait_for_client(IPC3270_PIPE_SOURCE *source) {
  33 +
  34 + if(ConnectNamedPipe(source->hPipe,&source->overlap)) {
  35 + g_message("Error %u in ConnectNamedPipe",(unsigned int) getLastError());
  36 + // popup_lasterror("%s",_( "Error in ConnectNamedPipe" ));
  37 + return;
  38 + }
  39 +
  40 + switch(GetLastError()) {
  41 + case ERROR_IO_PENDING: // The overlapped connection in progress.
  42 + source->state = PIPE_STATE_WAITING;
  43 + break;
  44 +
  45 +
  46 + case ERROR_PIPE_CONNECTED: // Client is already connected, so signal an event.
  47 + if(SetEvent(source->overlap.hEvent))
  48 + break;
  49 +
  50 + default:
  51 + g_message("Error %u in ConnectNamedPipe",(unsigned int) getLastError());
  52 + // popup_lasterror("%s", _( "ConnectNamedPipe failed" ));
  53 + }
  54 +
  55 +}
  56 +
  57 +static gboolean IO_prepare(GSource *source, gint *timeout) {
  58 + /*
  59 + * Called before all the file descriptors are polled.
  60 + * If the source can determine that it is ready here
  61 + * (without waiting for the results of the poll() call)
  62 + * it should return TRUE.
  63 + *
  64 + * It can also return a timeout_ value which should be the maximum
  65 + * timeout (in milliseconds) which should be passed to the poll() call.
  66 + * The actual timeout used will be -1 if all sources returned -1,
  67 + * or it will be the minimum of all the timeout_ values
  68 + * returned which were >= 0.
  69 + *
  70 + */
  71 + if(WaitForSingleObject(((pipe_source *) source)->overlap.hEvent,0) == WAIT_OBJECT_0)
  72 + return TRUE;
  73 +
  74 + *timeout = 10;
  75 +
  76 + return FALSE;
  77 +
  78 +}
  79 +
  80 +static gboolean IO_check(GSource *source) {
  81 + /*
  82 + * Called after all the file descriptors are polled.
  83 + * The source should return TRUE if it is ready to be dispatched.
  84 + * Note that some time may have passed since the previous prepare
  85 + * function was called, so the source should be checked again here.
  86 + *
  87 + */
  88 + if(WaitForSingleObject(((IPC3270_PIPE_SOURCE *) source)->overlap.hEvent,0) == WAIT_OBJECT_0)
  89 + return TRUE;
  90 +
  91 + return FALSE;
  92 +}
  93 +
  94 +static void process_input(IPC3270_PIPE_SOURCE *source, DWORD cbRead) {
  95 +
  96 +}
  97 +
  98 +static void read_input_pipe(IPC3270_PIPE_SOURCE *source) {
  99 +
  100 + DWORD cbRead = 0;
  101 +
  102 + if(ReadFile(source->hPipe,source->buffer,PIPE_BUFFER_LENGTH,&cbRead,&source->overlap) && cbRead > 0)
  103 + process_input(source,cbRead);
  104 +
  105 + // The read operation is still pending.
  106 + switch(GetLastError())
  107 + {
  108 + case 0:
  109 + break;
  110 +
  111 + case ERROR_IO_PENDING:
  112 + source->state = PIPE_STATE_PENDING_READ;
  113 + break;
  114 +
  115 + case ERROR_PIPE_LISTENING:
  116 + source->state = PIPE_STATE_READ;
  117 + break;
  118 +
  119 + case ERROR_BROKEN_PIPE:
  120 +
  121 + if(!DisconnectNamedPipe(source->hPipe)) {
  122 +
  123 + g_message("Error %u on DisconnectNamedPipe", (unsigned int) GetLastError());
  124 +
  125 + } else {
  126 +
  127 + ipc3270_wait_for_client(source);
  128 +
  129 + }
  130 + break;
  131 +
  132 + case ERROR_PIPE_NOT_CONNECTED:
  133 + g_message("Cliente was disconnected");
  134 + break;
  135 +
  136 + default:
  137 + if(source->hPipe != INVALID_HANDLE_VALUE) {
  138 + g_message( "Error %u receiving message from pipe", (unsigned int) GetLastError());
  139 + }
  140 + }
  141 +
  142 +}
  143 +
  144 +
  145 +static gboolean IO_dispatch(GSource *source, GSourceFunc callback, gpointer data) {
  146 + /*
  147 + * Called to dispatch the event source,
  148 + * after it has returned TRUE in either its prepare or its check function.
  149 + * The dispatch function is passed in a callback function and data.
  150 + * The callback function may be NULL if the source was never connected
  151 + * to a callback using g_source_set_callback(). The dispatch function
  152 + * should call the callback function with user_data and whatever additional
  153 + * parameters are needed for this type of event source.
  154 + */
  155 + BOOL fSuccess;
  156 + DWORD cbRead = 0;
  157 +
  158 + fSuccess = GetOverlappedResult(((pipe_source *) source)->hPipe,&((pipe_source *) source)->overlap,&cbRead,FALSE );
  159 +
  160 + switch(((pipe_source *) source)->state) {
  161 + case PIPE_STATE_WAITING:
  162 +
  163 + if(fSuccess) {
  164 +
  165 + g_message("Client is connected");
  166 + ((pipe_source *) source)->state = PIPE_STATE_READ;
  167 +
  168 + } else {
  169 +
  170 + // popup_lasterror("%s", _( "Pipe connection failed" ));
  171 +
  172 + }
  173 + break;
  174 +
  175 + case PIPE_STATE_READ:
  176 + // trace("Reading pipe (cbRead=%d)",(int) cbRead);
  177 + read_input_pipe( (pipe_source *) source);
  178 + break;
  179 +
  180 + case PIPE_STATE_PENDING_READ:
  181 + if(fSuccess && cbRead > 0)
  182 + process_input((pipe_source *) source,cbRead);
  183 + ((pipe_source *) source)->state = PIPE_STATE_READ;
  184 + break;
  185 +
  186 + case PIPE_STATE_UNDEFINED:
  187 + break;
  188 +
  189 + }
  190 +
  191 + return TRUE;
  192 +}
  193 +
  194 +static void IO_finalize(GSource *source) {
  195 +
  196 + if( ((pipe_source *) source)->hPipe != INVALID_HANDLE_VALUE) {
  197 + CloseHandle(((pipe_source *) source)->hPipe);
  198 + ((pipe_source *) source)->hPipe = INVALID_HANDLE_VALUE;
  199 + }
  200 +
  201 +}
  202 +
  203 +GSourceFuncs ipc3270_source_funcs = {
  204 + IO_prepare,
  205 + IO_check,
  206 + IO_dispatch,
  207 + IO_finalize,
  208 + IO_closure,
  209 + NULL
  210 +};
... ...