Commit 31431682be669afde3f66858cf0b3f509e1291bc
1 parent
e78a7560
Exists in
master
and in
1 other branch
Working on windows IPC.
Showing
3 changed files
with
119 additions
and
68 deletions
Show diff stats
src/core/windows/inout.c
| ... | ... | @@ -66,14 +66,121 @@ unsigned char * ipc3270_pack_error(const GError *error, size_t * szPacket) { |
| 66 | 66 | return outputBuffer; |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | +static unsigned char * setup_header(unsigned char *txtptr, const gchar *name, int id, size_t count) { | |
| 70 | + | |
| 71 | + // Add name | |
| 72 | + strcpy((char *) txtptr,name); | |
| 73 | + txtptr += strlen((char *) txtptr) + 1; | |
| 74 | + | |
| 75 | + // Add ID | |
| 76 | + *((guint16 *) txtptr) = (guint16) id; | |
| 77 | + txtptr += sizeof(guint16); | |
| 78 | + | |
| 79 | + // Update ptr; | |
| 80 | + *((guint16 *) txtptr) = (guint16) count; | |
| 81 | + txtptr += sizeof(guint16); | |
| 82 | + | |
| 83 | + return txtptr; | |
| 84 | +} | |
| 85 | + | |
| 86 | +unsigned char * pack_value(unsigned char *txtptr, GVariant *value) { | |
| 87 | + | |
| 88 | + unsigned char type = (unsigned char) g_variant_get_type_string(value)[0]; | |
| 89 | + | |
| 90 | + debug("%s type=%c",__FUNCTION__,type); | |
| 91 | + | |
| 92 | + *(txtptr++) = type; | |
| 93 | + | |
| 94 | + switch(type) { | |
| 95 | + // https://developer.gnome.org/glib/stable/gvariant-format-strings.html | |
| 96 | + case 's': | |
| 97 | + strcpy((char *) txtptr,g_variant_get_string(value,NULL)); | |
| 98 | + txtptr += (strlen((char *) txtptr)+1); | |
| 99 | + break; | |
| 100 | + | |
| 101 | + case 'b': // gboolean | |
| 102 | + *(txtptr++) = g_variant_get_boolean(value) ? 1 : 0; | |
| 103 | + break; | |
| 104 | + | |
| 105 | + case 'y': // guchar | |
| 106 | + *(txtptr++) = g_variant_get_byte(value); | |
| 107 | + break; | |
| 108 | + | |
| 109 | + case 'n': // gint16 | |
| 110 | + *((gint16 *) txtptr) = g_variant_get_int16(value); | |
| 111 | + txtptr += sizeof(gint16); | |
| 112 | + break; | |
| 113 | + | |
| 114 | + case 'q': // guint16 | |
| 115 | + *((guint16 *) txtptr) = g_variant_get_uint16(value); | |
| 116 | + txtptr += sizeof(guint16); | |
| 117 | + break; | |
| 118 | + | |
| 119 | + case 'i': // gint32 | |
| 120 | + case 'h': // gint32 | |
| 121 | + *((gint32 *) txtptr) = g_variant_get_int32(value); | |
| 122 | + txtptr += sizeof(gint32); | |
| 123 | + break; | |
| 124 | + | |
| 125 | + case 'u': // guint32 | |
| 126 | + *((guint32 *) txtptr) = g_variant_get_uint32(value); | |
| 127 | + txtptr += sizeof(guint32); | |
| 128 | + break; | |
| 129 | + | |
| 130 | + case 'x': // gint64 | |
| 131 | + *((gint64 *) txtptr) = g_variant_get_int64(value); | |
| 132 | + txtptr += sizeof(gint64); | |
| 133 | + break; | |
| 134 | + | |
| 135 | + case 't': // guint64 | |
| 136 | + *((guint64 *) txtptr) = g_variant_get_uint64(value); | |
| 137 | + txtptr += sizeof(guint64); | |
| 138 | + break; | |
| 139 | + | |
| 140 | + default: | |
| 141 | + errno = EINVAL; | |
| 142 | + return NULL; | |
| 143 | + | |
| 144 | + } | |
| 145 | + | |
| 146 | + return txtptr; | |
| 147 | +} | |
| 148 | + | |
| 149 | +unsigned char * ipc3270_pack_value(const gchar *name, int id, GVariant *value, size_t * szPacket) { | |
| 150 | + | |
| 151 | + debug("%s(%s)",__FUNCTION__,name); | |
| 152 | + | |
| 153 | + // Set packet size; | |
| 154 | + *szPacket = | |
| 155 | + strlen(name) + 1 | |
| 156 | + + (sizeof(guint16) * 2) | |
| 157 | + + g_variant_get_size(value) +1; | |
| 158 | + | |
| 159 | + unsigned char * outputBuffer = g_malloc0(*szPacket); | |
| 160 | + unsigned char * txtptr = setup_header(outputBuffer,name,id,1); | |
| 161 | + | |
| 162 | + txtptr = pack_value(txtptr, value); | |
| 163 | + if(!txtptr) { | |
| 164 | + g_free(outputBuffer); | |
| 165 | + return NULL; | |
| 166 | + } | |
| 167 | + | |
| 168 | + debug("used=%u allocated=%u",(unsigned int) (txtptr-outputBuffer), (unsigned int) *szPacket); | |
| 169 | + | |
| 170 | + return outputBuffer; | |
| 171 | + | |
| 172 | +} | |
| 173 | + | |
| 174 | + | |
| 69 | 175 | unsigned char * ipc3270_pack(const gchar * name, int id, GVariant *values, size_t * szPacket) { |
| 70 | 176 | |
| 71 | 177 | GVariantIter iter; |
| 72 | 178 | gsize count = g_variant_iter_init(&iter, values); |
| 73 | - g_autofree char * types = g_new0(char, count); | |
| 74 | 179 | GVariant * child; |
| 75 | 180 | size_t ix = 0; |
| 76 | 181 | |
| 182 | + debug("%s(%s)",__FUNCTION__,name); | |
| 183 | + | |
| 77 | 184 | // Init packet size; |
| 78 | 185 | *szPacket = strlen(name) + 1 + (sizeof(guint16) * 2); |
| 79 | 186 | |
| ... | ... | @@ -82,7 +189,6 @@ unsigned char * ipc3270_pack(const gchar * name, int id, GVariant *values, size_ |
| 82 | 189 | |
| 83 | 190 | // debug("type='%s' size=%u", g_variant_get_type_string(child), (unsigned int) g_variant_get_size(child)); |
| 84 | 191 | |
| 85 | - types[ix] = g_variant_get_type_string(child)[0]; | |
| 86 | 192 | *szPacket += (1+g_variant_get_size(child)); |
| 87 | 193 | |
| 88 | 194 | g_variant_unref(child); |
| ... | ... | @@ -91,19 +197,7 @@ unsigned char * ipc3270_pack(const gchar * name, int id, GVariant *values, size_ |
| 91 | 197 | |
| 92 | 198 | // Allocate buffer |
| 93 | 199 | unsigned char * outputBuffer = g_malloc0(*szPacket); |
| 94 | - unsigned char * txtptr = outputBuffer; | |
| 95 | - | |
| 96 | - // Add name | |
| 97 | - strcpy((char *) txtptr,name); | |
| 98 | - txtptr += strlen((char *) txtptr) + 1; | |
| 99 | - | |
| 100 | - // Add ID | |
| 101 | - *((guint16 *) txtptr) = (guint16) id; | |
| 102 | - txtptr += sizeof(guint16); | |
| 103 | - | |
| 104 | - // Update ptr; | |
| 105 | - *((guint16 *) txtptr) = (guint16) count; | |
| 106 | - txtptr += sizeof(guint16); | |
| 200 | + unsigned char * txtptr = setup_header(outputBuffer,name,id,count); | |
| 107 | 201 | |
| 108 | 202 | ix = 0; |
| 109 | 203 | g_variant_iter_init(&iter, values); |
| ... | ... | @@ -111,58 +205,8 @@ unsigned char * ipc3270_pack(const gchar * name, int id, GVariant *values, size_ |
| 111 | 205 | |
| 112 | 206 | debug("type='%s' size=%u index=%u", g_variant_get_type_string(child), (unsigned int) g_variant_get_size(child), (unsigned int) (txtptr - outputBuffer)); |
| 113 | 207 | |
| 114 | - *(txtptr++) = types[ix]; | |
| 115 | - | |
| 116 | - switch(types[ix]) { | |
| 117 | - | |
| 118 | - // https://developer.gnome.org/glib/stable/gvariant-format-strings.html | |
| 119 | - | |
| 120 | - case 's': | |
| 121 | - strcpy((char *) txtptr,g_variant_get_string(child,NULL)); | |
| 122 | - txtptr += (strlen((char *) txtptr)+1); | |
| 123 | - break; | |
| 124 | - | |
| 125 | - case 'b': // gboolean | |
| 126 | - *(txtptr++) = g_variant_get_boolean(child) ? 1 : 0; | |
| 127 | - break; | |
| 128 | - | |
| 129 | - case 'y': // guchar | |
| 130 | - *(txtptr++) = g_variant_get_byte(child); | |
| 131 | - break; | |
| 132 | - | |
| 133 | - case 'n': // gint16 | |
| 134 | - *((gint16 *) txtptr) = g_variant_get_int16(child); | |
| 135 | - txtptr += sizeof(gint16); | |
| 136 | - break; | |
| 137 | - | |
| 138 | - case 'q': // guint16 | |
| 139 | - *((guint16 *) txtptr) = g_variant_get_uint16(child); | |
| 140 | - txtptr += sizeof(guint16); | |
| 141 | - break; | |
| 142 | - | |
| 143 | - case 'i': // gint32 | |
| 144 | - case 'h': // gint32 | |
| 145 | - *((gint32 *) txtptr) = g_variant_get_int32(child); | |
| 146 | - txtptr += sizeof(gint32); | |
| 147 | - break; | |
| 148 | - | |
| 149 | - case 'u': // guint32 | |
| 150 | - *((guint32 *) txtptr) = g_variant_get_uint32(child); | |
| 151 | - txtptr += sizeof(guint32); | |
| 152 | - break; | |
| 153 | - | |
| 154 | - case 'x': // gint64 | |
| 155 | - *((gint64 *) txtptr) = g_variant_get_int64(child); | |
| 156 | - txtptr += sizeof(gint64); | |
| 157 | - break; | |
| 158 | - | |
| 159 | - case 't': // guint64 | |
| 160 | - *((guint64 *) txtptr) = g_variant_get_uint64(child); | |
| 161 | - txtptr += sizeof(guint64); | |
| 162 | - break; | |
| 163 | - | |
| 164 | - default: | |
| 165 | - errno = EINVAL; | |
| 208 | + txtptr = pack_value(txtptr, child); | |
| 209 | + if(!txtptr) { | |
| 166 | 210 | g_free(outputBuffer); |
| 167 | 211 | return NULL; |
| 168 | 212 | } | ... | ... |
src/core/windows/pipesource.c
| ... | ... | @@ -131,6 +131,8 @@ static void process_input(IPC3270_PIPE_SOURCE *source, DWORD cbRead) { |
| 131 | 131 | |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | + debug("response=%p",response); | |
| 135 | + | |
| 134 | 136 | // Pack response |
| 135 | 137 | size_t szPacket = 0; |
| 136 | 138 | g_autofree unsigned char * buffer = NULL; |
| ... | ... | @@ -141,12 +143,16 @@ static void process_input(IPC3270_PIPE_SOURCE *source, DWORD cbRead) { |
| 141 | 143 | |
| 142 | 144 | } else { |
| 143 | 145 | |
| 144 | - buffer = ipc3270_pack(request_name, 0, response, &szPacket); | |
| 146 | + buffer = ipc3270_pack_value(request_name, 0, response, &szPacket); | |
| 145 | 147 | |
| 146 | 148 | } |
| 147 | 149 | |
| 148 | 150 | // Send response |
| 149 | 151 | DWORD wrote = (DWORD) szPacket; |
| 152 | + | |
| 153 | + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_EVENT_TRACE)) | |
| 154 | + lib3270_trace_data(hSession, "IPC Data block sent to pipe", (const char *) buffer, szPacket); | |
| 155 | + | |
| 150 | 156 | WriteFile(source->hPipe,buffer,wrote,&wrote,NULL); |
| 151 | 157 | |
| 152 | 158 | } | ... | ... |
src/include/lib3270/ipc.h
| ... | ... | @@ -91,6 +91,7 @@ |
| 91 | 91 | |
| 92 | 92 | #ifdef _WIN32 |
| 93 | 93 | unsigned char * ipc3270_pack(const gchar *name, int id, GVariant *values, size_t * szPacket); |
| 94 | + unsigned char * ipc3270_pack_value(const gchar *name, int id, GVariant *value, size_t * szPacket); | |
| 94 | 95 | unsigned char * ipc3270_pack_error(const GError *error, size_t * szPacket); |
| 95 | 96 | GVariant * ipc3270_unpack(const unsigned char *packet, int *id); |
| 96 | 97 | #endif // _WIN32 | ... | ... |