Commit 7074ab591da52072eaaa4c01c2e5f2ae0c5b49e8

Authored by Perry Werneck
1 parent 84df7ea4
Exists in master and in 1 other branch develop

Fixing windows IPC module.

client/ipcclient.cbp
... ... @@ -47,6 +47,8 @@
47 47 <Unit filename="src/core/events.cc" />
48 48 <Unit filename="src/core/linux/request.cc" />
49 49 <Unit filename="src/core/session.cc" />
  50 + <Unit filename="src/core/windows/pop.cc" />
  51 + <Unit filename="src/core/windows/push.cc" />
50 52 <Unit filename="src/core/windows/request.cc" />
51 53 <Unit filename="src/core/windows/resources.rc" />
52 54 <Unit filename="src/core/windows/resources.rc.in" />
... ...
client/src/core/windows/pop.cc 0 → 100644
... ... @@ -0,0 +1,118 @@
  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 - 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 +/**
  31 + * @file src/os/windows/request.cc
  32 + *
  33 + * @brief Implements WIN32 request methods.
  34 + *
  35 + * @author perry.werneck@gmail.com
  36 + *
  37 + */
  38 +
  39 + #include <ipc-client-internals.h>
  40 +
  41 + using std::string;
  42 +
  43 +/*---[ Implement ]----------------------------------------------------------------------------------*/
  44 +
  45 + namespace TN3270 {
  46 +
  47 + IPC::Request & IPC::Request::pop(std::string &value) {
  48 + DataBlock * block = getNextBlock();
  49 +
  50 + if(block->type != IPC::Request::String)
  51 + throw std::runtime_error("Invalid format");
  52 +
  53 + const char *ptr = (const char *) (block+1);
  54 +
  55 + in.current += (strlen(ptr)+1+sizeof(DataBlock));
  56 +
  57 + value.assign(ptr);
  58 +
  59 + return *this;
  60 + }
  61 +
  62 + IPC::Request & IPC::Request::Request::pop(int &value) {
  63 +
  64 + DataBlock * block = getNextBlock();
  65 +
  66 + switch(block->type) {
  67 + case IPC::Request::Int16:
  68 + value = * ((int16_t *) (block+1));
  69 + in.current += sizeof(int16_t) + sizeof(DataBlock);
  70 + break;
  71 +
  72 + case IPC::Request::Int32:
  73 + value = * ((int32_t *) (block+1));
  74 + in.current += sizeof(int32_t) + sizeof(DataBlock);
  75 + break;
  76 +
  77 + case IPC::Request::Int64:
  78 + value = * ((int64_t *) (block+1));
  79 + in.current += sizeof(int64_t) + sizeof(DataBlock);
  80 + break;
  81 +
  82 + default:
  83 + throw std::runtime_error("Invalid format");
  84 + }
  85 +
  86 + return *this;
  87 + }
  88 +
  89 + IPC::Request & IPC::Request::Request::pop(unsigned int &value) {
  90 +
  91 + DataBlock * block = getNextBlock();
  92 +
  93 + switch(block->type) {
  94 + case IPC::Request::Uint16:
  95 + value = * ((uint16_t *) (block+1));
  96 + in.current += sizeof(uint16_t) + sizeof(DataBlock);
  97 + break;
  98 +
  99 + case IPC::Request::Uint32:
  100 + value = * ((uint32_t *) (block+1));
  101 + in.current += sizeof(uint32_t) + sizeof(DataBlock);
  102 + break;
  103 +
  104 + case IPC::Request::Uint64:
  105 + value = * ((uint64_t *) (block+1));
  106 + in.current += sizeof(uint64_t) + sizeof(DataBlock);
  107 + break;
  108 +
  109 + default:
  110 + throw std::runtime_error("Invalid format");
  111 + }
  112 +
  113 + return *this;
  114 + }
  115 +
  116 + }
  117 +
  118 +
... ...
client/src/core/windows/push.cc 0 → 100644
... ... @@ -0,0 +1,80 @@
  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 - 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 +/**
  31 + * @file
  32 + *
  33 + * @brief Implements WIN32 request "push" methods.
  34 + *
  35 + * @author perry.werneck@gmail.com
  36 + *
  37 + */
  38 +
  39 + #include <ipc-client-internals.h>
  40 +
  41 + using std::string;
  42 +
  43 +/*---[ Implement ]----------------------------------------------------------------------------------*/
  44 +
  45 + namespace TN3270 {
  46 +
  47 + IPC::Request & IPC::Request::push(const char *arg) {
  48 + (*this->outvalues)++;
  49 + pushBlock(arg, strlen(arg)+1)->type = IPC::Request::String;
  50 + return *this;
  51 + }
  52 +
  53 + IPC::Request & IPC::Request::push(const bool arg) {
  54 + (*this->outvalues)++;
  55 + uint8_t value = (uint8_t) (arg ? 0xff : 0);
  56 + pushBlock(&value, sizeof(value))->type = IPC::Request::Boolean;
  57 + return *this;
  58 + }
  59 +
  60 + IPC::Request & IPC::Request::push(const uint8_t arg) {
  61 + (*this->outvalues)++;
  62 + pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uchar;
  63 + return *this;
  64 + }
  65 +
  66 + IPC::Request & IPC::Request::push(const int32_t arg) {
  67 + (*this->outvalues)++;
  68 + pushBlock(&arg, sizeof(arg))->type = IPC::Request::Int32;
  69 + return *this;
  70 + }
  71 +
  72 + IPC::Request & IPC::Request::push(const uint32_t arg) {
  73 + (*this->outvalues)++;
  74 + pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uint32;
  75 + return *this;
  76 + }
  77 +
  78 + }
  79 +
  80 +
... ...
client/src/core/windows/request.cc
... ... @@ -44,6 +44,39 @@
44 44  
45 45 namespace TN3270 {
46 46  
  47 + #define PIPE_BUFFER_LENGTH 8192
  48 +
  49 + IPC::Request::Request(HANDLE hPipe, const char *name, uint16_t type) {
  50 +
  51 + this->hPipe = hPipe;
  52 +
  53 + // Create buffers
  54 + in.length = PIPE_BUFFER_LENGTH;
  55 + in.used = 0;
  56 + in.block = new uint8_t[in.length];
  57 +
  58 + out.length = PIPE_BUFFER_LENGTH;
  59 + out.used = 0;
  60 + out.block = new uint8_t[out.length];
  61 +
  62 + // Add name
  63 + strcpy((char *) out.block, name);
  64 + out.used += strlen((char *) name) + 1;
  65 +
  66 + // Add type
  67 + debug("Request type stored @",out.used);
  68 +
  69 + *((uint16_t *) (out.block + out.used)) = type;
  70 + out.used += sizeof(uint16_t);
  71 +
  72 + // Add argument counter.
  73 + this->outvalues = (uint16_t *) (out.block + out.used);
  74 + out.used += sizeof(uint16_t);
  75 +
  76 + *this->outvalues = 0;
  77 +
  78 + }
  79 +
47 80 IPC::Request::~Request() {
48 81  
49 82 delete[] ((uint8_t *) in.block);
... ... @@ -78,107 +111,14 @@
78 111  
79 112 }
80 113  
81   - IPC::Request & IPC::Request::push(const char *arg) {
82   - pushBlock(arg, strlen(arg)+1)->type = IPC::Request::String;
83   - return *this;
84   - }
85   -
86   - IPC::Request & IPC::Request::push(const bool arg) {
87   - uint8_t value = (uint8_t) (arg ? 0xff : 0);
88   - pushBlock(&value, sizeof(value))->type = IPC::Request::Boolean;
89   - return *this;
90   - }
91   -
92   - IPC::Request & IPC::Request::push(const uint8_t arg) {
93   - pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uchar;
94   - return *this;
95   - }
96   -
97   - IPC::Request & IPC::Request::push(const int32_t arg) {
98   - pushBlock(&arg, sizeof(arg))->type = IPC::Request::Int32;
99   - return *this;
100   - }
101   -
102   - IPC::Request & IPC::Request::push(const uint32_t arg) {
103   - pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uint32;
104   - return *this;
105   - }
106   -
107   - IPC::Request & IPC::Request::pop(std::string &value) {
108   - DataBlock * block = getNextBlock();
109   -
110   - if(block->type != IPC::Request::String)
111   - throw std::runtime_error("Invalid format");
112   -
113   - const char *ptr = (const char *) (block+1);
114   -
115   - in.current += (strlen(ptr)+1+sizeof(DataBlock));
116   -
117   - value.assign(ptr);
118   -
119   - return *this;
120   - }
121   -
122   - IPC::Request & IPC::Request::Request::pop(int &value) {
123   -
124   - DataBlock * block = getNextBlock();
125   -
126   - switch(block->type) {
127   - case IPC::Request::Int16:
128   - value = * ((int16_t *) (block+1));
129   - in.current += sizeof(int16_t) + sizeof(DataBlock);
130   - break;
131   -
132   - case IPC::Request::Int32:
133   - value = * ((int32_t *) (block+1));
134   - in.current += sizeof(int32_t) + sizeof(DataBlock);
135   - break;
136   -
137   - case IPC::Request::Int64:
138   - value = * ((int64_t *) (block+1));
139   - in.current += sizeof(int64_t) + sizeof(DataBlock);
140   - break;
141   -
142   - default:
143   - throw std::runtime_error("Invalid format");
144   - }
145   -
146   - return *this;
147   - }
148   -
149   - IPC::Request & IPC::Request::Request::pop(unsigned int &value) {
150   -
151   - DataBlock * block = getNextBlock();
152   -
153   - switch(block->type) {
154   - case IPC::Request::Uint16:
155   - value = * ((uint16_t *) (block+1));
156   - in.current += sizeof(uint16_t) + sizeof(DataBlock);
157   - break;
158   -
159   - case IPC::Request::Uint32:
160   - value = * ((uint32_t *) (block+1));
161   - in.current += sizeof(uint32_t) + sizeof(DataBlock);
162   - break;
163   -
164   - case IPC::Request::Uint64:
165   - value = * ((uint64_t *) (block+1));
166   - in.current += sizeof(uint64_t) + sizeof(DataBlock);
167   - break;
168   -
169   - default:
170   - throw std::runtime_error("Invalid format");
171   - }
172   -
173   - return *this;
174   - }
175   -
176 114 IPC::Request & IPC::Request::call() {
177 115  
178 116 #ifdef DEBUG
179 117 // lib3270_trace_data(NULL,"Request block",(const char *) this->out.block, this->out.used);
180 118 #endif // DEBUG
181 119  
  120 + debug("Sending request with ", *this->outvalues, " elements");
  121 +
182 122 in.current = 0;
183 123  
184 124 if(!TransactNamedPipe(
... ...
client/src/host/string.cc
... ... @@ -46,16 +46,16 @@ std::string TN3270::Host::toString() const {
46 46 return this->session->toString();
47 47 }
48 48  
49   -std::string TN3270::Host::toString(int baddr, size_t len, char lf) const {
  49 +std::string TN3270::Host::toString(int baddr, int len, char lf) const {
50 50  
51 51 this->session->waitForReady(this->timeout);
52 52 return this->session->toString(baddr,len,lf);
53 53  
54 54 }
55 55  
56   -std::string TN3270::Host::toString(unsigned int row, unsigned int col, size_t sz, char lf) const {
  56 +std::string TN3270::Host::toString(unsigned int row, unsigned int col, int len, char lf) const {
57 57  
58 58 this->session->waitForReady(this->timeout);
59   - return this->session->toString(row,col,sz,lf);
  59 + return this->session->toString(row,col,len,lf);
60 60  
61 61 }
... ...
client/src/include/ipc-client-internals.h
... ... @@ -180,7 +180,6 @@
180 180 /// @brief PW3270 IPC Request/Response.
181 181 class Request {
182 182 private:
183   - Request(const IPC::Session &session);
184 183  
185 184 #ifdef _WIN32
186 185 /// @brief Pipe Handle.
... ... @@ -223,6 +222,9 @@
223 222 /// @brief Get next argument.
224 223 DataBlock * getNextBlock() const;
225 224  
  225 + /// @brief Pointer to number of variants in the output buffer.
  226 + uint16_t * outvalues;
  227 +
226 228 #else
227 229 struct {
228 230 DBusMessage * in;
... ... @@ -234,6 +236,12 @@
234 236  
235 237 #endif // _WIN32
236 238  
  239 + protected:
  240 +
  241 +#ifdef _WIN32
  242 + Request(HANDLE hPipe, const char *name, uint16_t type);
  243 +#endif // _WIN32
  244 +
237 245 public:
238 246  
239 247 /// @brief Create a method call.
... ...
client/src/session/remote/actions.cc
... ... @@ -71,8 +71,10 @@
71 71 .push(url)
72 72 .call();
73 73  
  74 + /*
74 75 if(seconds)
75 76 this->waitForReady(seconds);
  77 + */
76 78  
77 79 }
78 80  
... ...
client/src/session/remote/windows/request.cc
... ... @@ -44,44 +44,10 @@
44 44  
45 45 namespace TN3270 {
46 46  
47   - #define PIPE_BUFFER_LENGTH 8192
48   -
49   - IPC::Request::Request(const Session &session) {
50   -
51   - this->hPipe = session.hPipe;
52   -
53   - in.length = PIPE_BUFFER_LENGTH;
54   - in.used = 0;
55   - in.block = new uint8_t[in.length];
56   -
57   - out.length = PIPE_BUFFER_LENGTH;
58   - out.used = 0;
59   - out.block = new uint8_t[out.length];
60   -
  47 + IPC::Request::Request(const Session &session, const char *method) : Request(session.hPipe, method, 3) {
61 48 }
62 49  
63   - IPC::Request::Request(const Session &session, const char *method) : Request(session) {
64   -
65   - // Add name
66   - strcpy((char *) out.block, method);
67   - out.used += strlen((char *) method) + 1;
68   -
69   - // Add ID
70   - *((uint16_t *) (out.block + out.used)) = (uint16_t) 3;
71   - out.used += sizeof(uint16_t);
72   -
73   - }
74   -
75   - IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session) {
76   -
77   - // Add name
78   - strcpy((char *) out.block, property);
79   - out.used += strlen((char *) property) + 1;
80   -
81   - // Add ID (SetProperty = 2, getProperty = 1)
82   - *((uint16_t *) (out.block + out.used)) = (uint16_t) (isSet ? 2 : 1);
83   - out.used += sizeof(uint16_t);
84   -
  50 + IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session.hPipe, property, (isSet ? 2 : 1)) {
85 51 }
86 52  
87 53 }
... ...
client/src/testprogram/testprogram.cc
... ... @@ -98,6 +98,8 @@
98 98  
99 99 host.connect(nullptr);
100 100  
  101 + /*
  102 +
101 103 cout
102 104 << "Wait for unlock returns " << host.getKeyboardLockState() << std::endl
103 105 << "Connection state is " << toCharString(host.getConnectionState()) << std::endl
... ... @@ -123,6 +125,7 @@
123 125 host.pfkey(3);
124 126  
125 127 // host.disconnect();
  128 + */
126 129  
127 130 } catch(const std::exception &e) {
128 131  
... ...
common/src/include/lib3270/ipc.h
... ... @@ -423,8 +423,8 @@
423 423 Host & pop(std::string &text);
424 424  
425 425 std::string toString() const;
426   - std::string toString(int baddr, size_t len = -1, char lf = '\n') const;
427   - std::string toString(unsigned int row, unsigned int col, size_t len = -1, char lf = '\n') const;
  426 + std::string toString(int baddr, int len = -1, char lf = '\n') const;
  427 + std::string toString(unsigned int row, unsigned int col, int len = -1, char lf = '\n') const;
428 428  
429 429 template<typename T>
430 430 Host & push(T value) {
... ...
server/src/core/methods/methods.c
... ... @@ -73,7 +73,7 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req
73 73 size_t ix;
74 74 H3270 * hSession = ipc3270_get_session(object);
75 75  
76   - debug("%s(%s)",__FUNCTION__,method_name);
  76 + debug("%s(%s,request=%p,response=%p)",__FUNCTION__,method_name,request,response);
77 77  
78 78 lib3270_trace_event(hSession,"Method %s called on session %c\n",method_name,lib3270_get_session_id(hSession));
79 79  
... ... @@ -83,6 +83,8 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req
83 83  
84 84 int rc = methods[ix].call(object,request,response,error);
85 85  
  86 + debug("rc=%d",rc);
  87 +
86 88 if(rc)
87 89 ipc3270_set_error(object,rc,error);
88 90  
... ...
server/src/core/methods/wait.c
... ... @@ -61,7 +61,7 @@ int ipc3270_method_wait_for_keyboard_unlock(GObject *session, GVariant *request,
61 61  
62 62 guint seconds = 1;
63 63 g_variant_get(request, "(u)", &seconds);
64   - ipc3270_response_append_int32(response, (int32_t) lib3270_wait_for_keyboard_unlock(ipc3270_get_session(session),seconds));
  64 + ipc3270_response_append_int32(response, (gint32) lib3270_wait_for_keyboard_unlock(ipc3270_get_session(session),seconds));
65 65 return 0;
66 66  
67 67 }
... ...
server/src/core/windows/inout.c
... ... @@ -232,6 +232,8 @@ GVariant * ipc3270_unpack(const unsigned char *packet, int *id) {
232 232 packet += strlen((const char *) packet)+1;
233 233  
234 234 // Get Packet ID or error code.
  235 + debug("Request type is %u",(unsigned int) *((guint16 *) packet));
  236 +
235 237 if(id) {
236 238 *id = (int) *((guint16 *) packet);
237 239 }
... ... @@ -291,6 +293,7 @@ GVariant * ipc3270_unpack(const unsigned char *packet, int *id) {
291 293 break;
292 294  
293 295 default:
  296 + g_message("Unexpected format for argument %d: \"%c\"",ix,descrs[ix+1]);
294 297 errno = EINVAL;
295 298 return NULL;
296 299 }
... ...
server/src/core/windows/pipesource.c
... ... @@ -106,34 +106,46 @@ static void process_input(IPC3270_PIPE_SOURCE *source, DWORD cbRead) {
106 106 debug("Received packet \"%s\" with %u bytes", request_name, (unsigned int) cbRead);
107 107  
108 108 g_autoptr (GError) error = NULL;
109   - g_autoptr (GVariant) parameters = ipc3270_unpack(source->buffer, &request_type);
110 109 g_autoptr (GVariant) response = NULL;
  110 + g_autoptr (GVariant) parameters = ipc3270_unpack(source->buffer, &request_type);
111 111  
112   - // Process query
113   - switch(request_type) {
114   - case 1: // getProperty
115   - response = ipc3270_get_property(source->object, request_name, &error);
116   - break;
  112 + if(parameters) {
117 113  
118   - case 2: // setProperty
119   - ipc3270_set_property(source->object, request_name, parameters, &error);
120   - response = g_variant_new_int32(0);
121   - break;
  114 + // Process query
  115 + switch(request_type) {
  116 + case 1: // getProperty
  117 + response = ipc3270_get_property(source->object, request_name, &error);
  118 + break;
  119 +
  120 + case 2: // setProperty
  121 + ipc3270_set_property(source->object, request_name, parameters, &error);
  122 + response = g_variant_new_int32(0);
  123 + break;
  124 +
  125 + case 3: // method
  126 + {
  127 + g_autoptr(GObject) rsp = ipc3270_response_new();
122 128  
123   - case 3: // method
124   - {
125   - g_autoptr(GObject) rsp = ipc3270_response_new();
126   - ipc3270_method_call(source->object, request_name, parameters, response, &error);
  129 + debug("Parameters: %p", parameters);
  130 + debug("rsp: %p", rsp);
127 131  
128   - if(ipc3270_response_has_values(rsp))
129   - response = ipc3270_response_steal_value(rsp);
  132 + ipc3270_method_call(source->object, request_name, parameters, rsp, &error);
  133 +
  134 + if(ipc3270_response_has_values(rsp))
  135 + response = ipc3270_response_steal_value(rsp);
  136 +
  137 + }
  138 + break;
  139 +
  140 + default:
  141 + g_message("Rejecting request \"%s\": Invalid type %d",request_name, request_type);
  142 + g_set_error(&error,IPC3270(source->object)->error_domain,EINVAL,"Invalid or unexpected type %d",request_type);
130 143  
131 144 }
132   - break;
133 145  
134   - default:
135   - g_message("Rejecting request \"%s\": Invalid type %d",request_name, request_type);
136   - g_set_error(&error,IPC3270(source->object)->error_domain,EINVAL,"Invalid or unexpected type %d",request_type);
  146 + } else if(!error) {
  147 +
  148 + g_set_error(&error,IPC3270(source->object)->error_domain,errno ? errno : EINVAL,"Can't parse parameter list");
137 149  
138 150 }
139 151  
... ...