diff --git a/client/ipcclient.cbp b/client/ipcclient.cbp
index a47d0af..70ada5a 100644
--- a/client/ipcclient.cbp
+++ b/client/ipcclient.cbp
@@ -47,6 +47,8 @@
+
+
diff --git a/client/src/core/windows/pop.cc b/client/src/core/windows/pop.cc
new file mode 100644
index 0000000..194eaf9
--- /dev/null
+++ b/client/src/core/windows/pop.cc
@@ -0,0 +1,118 @@
+/*
+ * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
+ * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
+ * aplicativos mainframe. Registro no INPI sob o nome G3270.
+ *
+ * Copyright (C) <2008>
+ *
+ * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
+ * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
+ * Free Software Foundation.
+ *
+ * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
+ * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
+ * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
+ * obter mais detalhes.
+ *
+ * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
+ * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
+ * St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Este programa está nomeado como - e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
+ *
+ */
+
+/**
+ * @file src/os/windows/request.cc
+ *
+ * @brief Implements WIN32 request methods.
+ *
+ * @author perry.werneck@gmail.com
+ *
+ */
+
+ #include
+
+ using std::string;
+
+/*---[ Implement ]----------------------------------------------------------------------------------*/
+
+ namespace TN3270 {
+
+ IPC::Request & IPC::Request::pop(std::string &value) {
+ DataBlock * block = getNextBlock();
+
+ if(block->type != IPC::Request::String)
+ throw std::runtime_error("Invalid format");
+
+ const char *ptr = (const char *) (block+1);
+
+ in.current += (strlen(ptr)+1+sizeof(DataBlock));
+
+ value.assign(ptr);
+
+ return *this;
+ }
+
+ IPC::Request & IPC::Request::Request::pop(int &value) {
+
+ DataBlock * block = getNextBlock();
+
+ switch(block->type) {
+ case IPC::Request::Int16:
+ value = * ((int16_t *) (block+1));
+ in.current += sizeof(int16_t) + sizeof(DataBlock);
+ break;
+
+ case IPC::Request::Int32:
+ value = * ((int32_t *) (block+1));
+ in.current += sizeof(int32_t) + sizeof(DataBlock);
+ break;
+
+ case IPC::Request::Int64:
+ value = * ((int64_t *) (block+1));
+ in.current += sizeof(int64_t) + sizeof(DataBlock);
+ break;
+
+ default:
+ throw std::runtime_error("Invalid format");
+ }
+
+ return *this;
+ }
+
+ IPC::Request & IPC::Request::Request::pop(unsigned int &value) {
+
+ DataBlock * block = getNextBlock();
+
+ switch(block->type) {
+ case IPC::Request::Uint16:
+ value = * ((uint16_t *) (block+1));
+ in.current += sizeof(uint16_t) + sizeof(DataBlock);
+ break;
+
+ case IPC::Request::Uint32:
+ value = * ((uint32_t *) (block+1));
+ in.current += sizeof(uint32_t) + sizeof(DataBlock);
+ break;
+
+ case IPC::Request::Uint64:
+ value = * ((uint64_t *) (block+1));
+ in.current += sizeof(uint64_t) + sizeof(DataBlock);
+ break;
+
+ default:
+ throw std::runtime_error("Invalid format");
+ }
+
+ return *this;
+ }
+
+ }
+
+
diff --git a/client/src/core/windows/push.cc b/client/src/core/windows/push.cc
new file mode 100644
index 0000000..315f652
--- /dev/null
+++ b/client/src/core/windows/push.cc
@@ -0,0 +1,80 @@
+/*
+ * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
+ * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
+ * aplicativos mainframe. Registro no INPI sob o nome G3270.
+ *
+ * Copyright (C) <2008>
+ *
+ * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
+ * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
+ * Free Software Foundation.
+ *
+ * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
+ * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
+ * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
+ * obter mais detalhes.
+ *
+ * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
+ * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
+ * St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Este programa está nomeado como - e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
+ *
+ */
+
+/**
+ * @file
+ *
+ * @brief Implements WIN32 request "push" methods.
+ *
+ * @author perry.werneck@gmail.com
+ *
+ */
+
+ #include
+
+ using std::string;
+
+/*---[ Implement ]----------------------------------------------------------------------------------*/
+
+ namespace TN3270 {
+
+ IPC::Request & IPC::Request::push(const char *arg) {
+ (*this->outvalues)++;
+ pushBlock(arg, strlen(arg)+1)->type = IPC::Request::String;
+ return *this;
+ }
+
+ IPC::Request & IPC::Request::push(const bool arg) {
+ (*this->outvalues)++;
+ uint8_t value = (uint8_t) (arg ? 0xff : 0);
+ pushBlock(&value, sizeof(value))->type = IPC::Request::Boolean;
+ return *this;
+ }
+
+ IPC::Request & IPC::Request::push(const uint8_t arg) {
+ (*this->outvalues)++;
+ pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uchar;
+ return *this;
+ }
+
+ IPC::Request & IPC::Request::push(const int32_t arg) {
+ (*this->outvalues)++;
+ pushBlock(&arg, sizeof(arg))->type = IPC::Request::Int32;
+ return *this;
+ }
+
+ IPC::Request & IPC::Request::push(const uint32_t arg) {
+ (*this->outvalues)++;
+ pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uint32;
+ return *this;
+ }
+
+ }
+
+
diff --git a/client/src/core/windows/request.cc b/client/src/core/windows/request.cc
index b5c33e4..eb41978 100644
--- a/client/src/core/windows/request.cc
+++ b/client/src/core/windows/request.cc
@@ -44,6 +44,39 @@
namespace TN3270 {
+ #define PIPE_BUFFER_LENGTH 8192
+
+ IPC::Request::Request(HANDLE hPipe, const char *name, uint16_t type) {
+
+ this->hPipe = hPipe;
+
+ // Create buffers
+ in.length = PIPE_BUFFER_LENGTH;
+ in.used = 0;
+ in.block = new uint8_t[in.length];
+
+ out.length = PIPE_BUFFER_LENGTH;
+ out.used = 0;
+ out.block = new uint8_t[out.length];
+
+ // Add name
+ strcpy((char *) out.block, name);
+ out.used += strlen((char *) name) + 1;
+
+ // Add type
+ debug("Request type stored @",out.used);
+
+ *((uint16_t *) (out.block + out.used)) = type;
+ out.used += sizeof(uint16_t);
+
+ // Add argument counter.
+ this->outvalues = (uint16_t *) (out.block + out.used);
+ out.used += sizeof(uint16_t);
+
+ *this->outvalues = 0;
+
+ }
+
IPC::Request::~Request() {
delete[] ((uint8_t *) in.block);
@@ -78,107 +111,14 @@
}
- IPC::Request & IPC::Request::push(const char *arg) {
- pushBlock(arg, strlen(arg)+1)->type = IPC::Request::String;
- return *this;
- }
-
- IPC::Request & IPC::Request::push(const bool arg) {
- uint8_t value = (uint8_t) (arg ? 0xff : 0);
- pushBlock(&value, sizeof(value))->type = IPC::Request::Boolean;
- return *this;
- }
-
- IPC::Request & IPC::Request::push(const uint8_t arg) {
- pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uchar;
- return *this;
- }
-
- IPC::Request & IPC::Request::push(const int32_t arg) {
- pushBlock(&arg, sizeof(arg))->type = IPC::Request::Int32;
- return *this;
- }
-
- IPC::Request & IPC::Request::push(const uint32_t arg) {
- pushBlock(&arg, sizeof(arg))->type = IPC::Request::Uint32;
- return *this;
- }
-
- IPC::Request & IPC::Request::pop(std::string &value) {
- DataBlock * block = getNextBlock();
-
- if(block->type != IPC::Request::String)
- throw std::runtime_error("Invalid format");
-
- const char *ptr = (const char *) (block+1);
-
- in.current += (strlen(ptr)+1+sizeof(DataBlock));
-
- value.assign(ptr);
-
- return *this;
- }
-
- IPC::Request & IPC::Request::Request::pop(int &value) {
-
- DataBlock * block = getNextBlock();
-
- switch(block->type) {
- case IPC::Request::Int16:
- value = * ((int16_t *) (block+1));
- in.current += sizeof(int16_t) + sizeof(DataBlock);
- break;
-
- case IPC::Request::Int32:
- value = * ((int32_t *) (block+1));
- in.current += sizeof(int32_t) + sizeof(DataBlock);
- break;
-
- case IPC::Request::Int64:
- value = * ((int64_t *) (block+1));
- in.current += sizeof(int64_t) + sizeof(DataBlock);
- break;
-
- default:
- throw std::runtime_error("Invalid format");
- }
-
- return *this;
- }
-
- IPC::Request & IPC::Request::Request::pop(unsigned int &value) {
-
- DataBlock * block = getNextBlock();
-
- switch(block->type) {
- case IPC::Request::Uint16:
- value = * ((uint16_t *) (block+1));
- in.current += sizeof(uint16_t) + sizeof(DataBlock);
- break;
-
- case IPC::Request::Uint32:
- value = * ((uint32_t *) (block+1));
- in.current += sizeof(uint32_t) + sizeof(DataBlock);
- break;
-
- case IPC::Request::Uint64:
- value = * ((uint64_t *) (block+1));
- in.current += sizeof(uint64_t) + sizeof(DataBlock);
- break;
-
- default:
- throw std::runtime_error("Invalid format");
- }
-
- return *this;
- }
-
IPC::Request & IPC::Request::call() {
#ifdef DEBUG
// lib3270_trace_data(NULL,"Request block",(const char *) this->out.block, this->out.used);
#endif // DEBUG
+ debug("Sending request with ", *this->outvalues, " elements");
+
in.current = 0;
if(!TransactNamedPipe(
diff --git a/client/src/host/string.cc b/client/src/host/string.cc
index 6cc3193..e0f82dd 100644
--- a/client/src/host/string.cc
+++ b/client/src/host/string.cc
@@ -46,16 +46,16 @@ std::string TN3270::Host::toString() const {
return this->session->toString();
}
-std::string TN3270::Host::toString(int baddr, size_t len, char lf) const {
+std::string TN3270::Host::toString(int baddr, int len, char lf) const {
this->session->waitForReady(this->timeout);
return this->session->toString(baddr,len,lf);
}
-std::string TN3270::Host::toString(unsigned int row, unsigned int col, size_t sz, char lf) const {
+std::string TN3270::Host::toString(unsigned int row, unsigned int col, int len, char lf) const {
this->session->waitForReady(this->timeout);
- return this->session->toString(row,col,sz,lf);
+ return this->session->toString(row,col,len,lf);
}
diff --git a/client/src/include/ipc-client-internals.h b/client/src/include/ipc-client-internals.h
index 0377158..60e1c1d 100644
--- a/client/src/include/ipc-client-internals.h
+++ b/client/src/include/ipc-client-internals.h
@@ -180,7 +180,6 @@
/// @brief PW3270 IPC Request/Response.
class Request {
private:
- Request(const IPC::Session &session);
#ifdef _WIN32
/// @brief Pipe Handle.
@@ -223,6 +222,9 @@
/// @brief Get next argument.
DataBlock * getNextBlock() const;
+ /// @brief Pointer to number of variants in the output buffer.
+ uint16_t * outvalues;
+
#else
struct {
DBusMessage * in;
@@ -234,6 +236,12 @@
#endif // _WIN32
+ protected:
+
+#ifdef _WIN32
+ Request(HANDLE hPipe, const char *name, uint16_t type);
+#endif // _WIN32
+
public:
/// @brief Create a method call.
diff --git a/client/src/session/remote/actions.cc b/client/src/session/remote/actions.cc
index 812a3df..55b7147 100644
--- a/client/src/session/remote/actions.cc
+++ b/client/src/session/remote/actions.cc
@@ -71,8 +71,10 @@
.push(url)
.call();
+ /*
if(seconds)
this->waitForReady(seconds);
+ */
}
diff --git a/client/src/session/remote/windows/request.cc b/client/src/session/remote/windows/request.cc
index 7a4763b..b224fc1 100644
--- a/client/src/session/remote/windows/request.cc
+++ b/client/src/session/remote/windows/request.cc
@@ -44,44 +44,10 @@
namespace TN3270 {
- #define PIPE_BUFFER_LENGTH 8192
-
- IPC::Request::Request(const Session &session) {
-
- this->hPipe = session.hPipe;
-
- in.length = PIPE_BUFFER_LENGTH;
- in.used = 0;
- in.block = new uint8_t[in.length];
-
- out.length = PIPE_BUFFER_LENGTH;
- out.used = 0;
- out.block = new uint8_t[out.length];
-
+ IPC::Request::Request(const Session &session, const char *method) : Request(session.hPipe, method, 3) {
}
- IPC::Request::Request(const Session &session, const char *method) : Request(session) {
-
- // Add name
- strcpy((char *) out.block, method);
- out.used += strlen((char *) method) + 1;
-
- // Add ID
- *((uint16_t *) (out.block + out.used)) = (uint16_t) 3;
- out.used += sizeof(uint16_t);
-
- }
-
- IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session) {
-
- // Add name
- strcpy((char *) out.block, property);
- out.used += strlen((char *) property) + 1;
-
- // Add ID (SetProperty = 2, getProperty = 1)
- *((uint16_t *) (out.block + out.used)) = (uint16_t) (isSet ? 2 : 1);
- out.used += sizeof(uint16_t);
-
+ IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session.hPipe, property, (isSet ? 2 : 1)) {
}
}
diff --git a/client/src/testprogram/testprogram.cc b/client/src/testprogram/testprogram.cc
index 748cbc0..711baa6 100644
--- a/client/src/testprogram/testprogram.cc
+++ b/client/src/testprogram/testprogram.cc
@@ -98,6 +98,8 @@
host.connect(nullptr);
+ /*
+
cout
<< "Wait for unlock returns " << host.getKeyboardLockState() << std::endl
<< "Connection state is " << toCharString(host.getConnectionState()) << std::endl
@@ -123,6 +125,7 @@
host.pfkey(3);
// host.disconnect();
+ */
} catch(const std::exception &e) {
diff --git a/common/src/include/lib3270/ipc.h b/common/src/include/lib3270/ipc.h
index 6f2cc2b..b2258b6 100644
--- a/common/src/include/lib3270/ipc.h
+++ b/common/src/include/lib3270/ipc.h
@@ -423,8 +423,8 @@
Host & pop(std::string &text);
std::string toString() const;
- std::string toString(int baddr, size_t len = -1, char lf = '\n') const;
- std::string toString(unsigned int row, unsigned int col, size_t len = -1, char lf = '\n') const;
+ std::string toString(int baddr, int len = -1, char lf = '\n') const;
+ std::string toString(unsigned int row, unsigned int col, int len = -1, char lf = '\n') const;
template
Host & push(T value) {
diff --git a/server/src/core/methods/methods.c b/server/src/core/methods/methods.c
index cdd5416..8d1d06f 100644
--- a/server/src/core/methods/methods.c
+++ b/server/src/core/methods/methods.c
@@ -73,7 +73,7 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req
size_t ix;
H3270 * hSession = ipc3270_get_session(object);
- debug("%s(%s)",__FUNCTION__,method_name);
+ debug("%s(%s,request=%p,response=%p)",__FUNCTION__,method_name,request,response);
lib3270_trace_event(hSession,"Method %s called on session %c\n",method_name,lib3270_get_session_id(hSession));
@@ -83,6 +83,8 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req
int rc = methods[ix].call(object,request,response,error);
+ debug("rc=%d",rc);
+
if(rc)
ipc3270_set_error(object,rc,error);
diff --git a/server/src/core/methods/wait.c b/server/src/core/methods/wait.c
index 0a065c4..99c19e6 100644
--- a/server/src/core/methods/wait.c
+++ b/server/src/core/methods/wait.c
@@ -61,7 +61,7 @@ int ipc3270_method_wait_for_keyboard_unlock(GObject *session, GVariant *request,
guint seconds = 1;
g_variant_get(request, "(u)", &seconds);
- ipc3270_response_append_int32(response, (int32_t) lib3270_wait_for_keyboard_unlock(ipc3270_get_session(session),seconds));
+ ipc3270_response_append_int32(response, (gint32) lib3270_wait_for_keyboard_unlock(ipc3270_get_session(session),seconds));
return 0;
}
diff --git a/server/src/core/windows/inout.c b/server/src/core/windows/inout.c
index 93d9cd8..13ccea5 100644
--- a/server/src/core/windows/inout.c
+++ b/server/src/core/windows/inout.c
@@ -232,6 +232,8 @@ GVariant * ipc3270_unpack(const unsigned char *packet, int *id) {
packet += strlen((const char *) packet)+1;
// Get Packet ID or error code.
+ debug("Request type is %u",(unsigned int) *((guint16 *) packet));
+
if(id) {
*id = (int) *((guint16 *) packet);
}
@@ -291,6 +293,7 @@ GVariant * ipc3270_unpack(const unsigned char *packet, int *id) {
break;
default:
+ g_message("Unexpected format for argument %d: \"%c\"",ix,descrs[ix+1]);
errno = EINVAL;
return NULL;
}
diff --git a/server/src/core/windows/pipesource.c b/server/src/core/windows/pipesource.c
index dd57f0b..ffe27f6 100644
--- a/server/src/core/windows/pipesource.c
+++ b/server/src/core/windows/pipesource.c
@@ -106,34 +106,46 @@ static void process_input(IPC3270_PIPE_SOURCE *source, DWORD cbRead) {
debug("Received packet \"%s\" with %u bytes", request_name, (unsigned int) cbRead);
g_autoptr (GError) error = NULL;
- g_autoptr (GVariant) parameters = ipc3270_unpack(source->buffer, &request_type);
g_autoptr (GVariant) response = NULL;
+ g_autoptr (GVariant) parameters = ipc3270_unpack(source->buffer, &request_type);
- // Process query
- switch(request_type) {
- case 1: // getProperty
- response = ipc3270_get_property(source->object, request_name, &error);
- break;
+ if(parameters) {
- case 2: // setProperty
- ipc3270_set_property(source->object, request_name, parameters, &error);
- response = g_variant_new_int32(0);
- break;
+ // Process query
+ switch(request_type) {
+ case 1: // getProperty
+ response = ipc3270_get_property(source->object, request_name, &error);
+ break;
+
+ case 2: // setProperty
+ ipc3270_set_property(source->object, request_name, parameters, &error);
+ response = g_variant_new_int32(0);
+ break;
+
+ case 3: // method
+ {
+ g_autoptr(GObject) rsp = ipc3270_response_new();
- case 3: // method
- {
- g_autoptr(GObject) rsp = ipc3270_response_new();
- ipc3270_method_call(source->object, request_name, parameters, response, &error);
+ debug("Parameters: %p", parameters);
+ debug("rsp: %p", rsp);
- if(ipc3270_response_has_values(rsp))
- response = ipc3270_response_steal_value(rsp);
+ ipc3270_method_call(source->object, request_name, parameters, rsp, &error);
+
+ if(ipc3270_response_has_values(rsp))
+ response = ipc3270_response_steal_value(rsp);
+
+ }
+ break;
+
+ default:
+ g_message("Rejecting request \"%s\": Invalid type %d",request_name, request_type);
+ g_set_error(&error,IPC3270(source->object)->error_domain,EINVAL,"Invalid or unexpected type %d",request_type);
}
- break;
- default:
- g_message("Rejecting request \"%s\": Invalid type %d",request_name, request_type);
- g_set_error(&error,IPC3270(source->object)->error_domain,EINVAL,"Invalid or unexpected type %d",request_type);
+ } else if(!error) {
+
+ g_set_error(&error,IPC3270(source->object)->error_domain,errno ? errno : EINVAL,"Can't parse parameter list");
}
--
libgit2 0.21.2