aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2022-09-09 16:52:28 +0200
committerToni Uhlig <matzeton@googlemail.com>2022-09-09 16:52:28 +0200
commit38495d423f23b145a4377f87a536db5d2721f814 (patch)
tree61087a4c5e4138873cc4e6e0f9eeb4ac22d617e2 /examples
parentccb717ac524bb8a5c49ae92710864d022eebb401 (diff)
Cleaned up repository, moved files where they belong to.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'examples')
-rw-r--r--examples/driver-protobuf-c-tcp.bat27
-rw-r--r--examples/driver-protobuf-c-tcp.cpp139
-rw-r--r--examples/driver-protobuf-c.bat27
-rw-r--r--examples/driver-protobuf-c.cpp105
-rw-r--r--examples/driver.bat27
-rw-r--r--examples/driver.cpp152
-rw-r--r--examples/echo_srv.py16
-rw-r--r--examples/example.pb-c.c411
-rw-r--r--examples/example.pb-c.h166
-rw-r--r--examples/example.proto31
-rw-r--r--examples/userspace_client.cpp78
-rw-r--r--examples/userspace_client_protobuf.cpp152
12 files changed, 1331 insertions, 0 deletions
diff --git a/examples/driver-protobuf-c-tcp.bat b/examples/driver-protobuf-c-tcp.bat
new file mode 100644
index 0000000..9aa935b
--- /dev/null
+++ b/examples/driver-protobuf-c-tcp.bat
@@ -0,0 +1,27 @@
+@echo off
+set SERVICE_NAME=protobuf-c-tcp
+set DRIVER="%~dp0\driver-protobuf-c-tcp.sys"
+
+net session >nul 2>&1
+if NOT %ERRORLEVEL% EQU 0 (
+ echo ERROR: This script requires Administrator privileges!
+ pause
+ exit /b 1
+)
+
+echo ---------------------------------------
+echo -- Service Name: %SERVICE_NAME%
+echo -- Driver......: %DRIVER%
+echo ---------------------------------------
+
+sc create %SERVICE_NAME% binPath= %DRIVER% type= kernel
+echo ---------------------------------------
+sc start %SERVICE_NAME%
+echo ---------------------------------------
+sc query %SERVICE_NAME%
+echo [PRESS A KEY TO STOP THE DRIVER]
+pause
+sc stop %SERVICE_NAME%
+sc delete %SERVICE_NAME%
+echo Done.
+timeout /t 3
diff --git a/examples/driver-protobuf-c-tcp.cpp b/examples/driver-protobuf-c-tcp.cpp
new file mode 100644
index 0000000..da2142d
--- /dev/null
+++ b/examples/driver-protobuf-c-tcp.cpp
@@ -0,0 +1,139 @@
+#include "berkeley.h"
+#include "ksocket.h"
+#include "examples/example.pb-c.h"
+#include "wsk.h"
+
+#include "common.hpp"
+
+extern "C" {
+DRIVER_INITIALIZE DriverEntry;
+DRIVER_UNLOAD DriverUnload;
+
+#define DebuggerPrint(...) \
+ DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, __VA_ARGS__);
+
+NTSTATUS
+NTAPI
+DriverEntry(_In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING RegistryPath) {
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(RegistryPath);
+
+ NTSTATUS Status;
+
+ DebuggerPrint("Hi.\n");
+ Status = KsInitialize();
+
+ if (!NT_SUCCESS(Status)) {
+ return Status;
+ }
+
+ int server_sockfd = socket_listen(AF_INET, SOCK_STREAM, 0);
+
+ struct sockaddr_in addr;
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_port = htons(9095);
+
+ int result = bind(server_sockfd, (struct sockaddr *)&addr, sizeof(addr));
+ if (result != 0) {
+ DebuggerPrint("TCP server bind failed\n");
+ return STATUS_FAILED_DRIVER_ENTRY;
+ }
+
+ result = listen(server_sockfd, 1);
+ if (result != 0) {
+ DebuggerPrint("TCP server listen failed\n");
+ return STATUS_FAILED_DRIVER_ENTRY;
+ }
+
+ socklen_t addrlen = sizeof(addr);
+ int client_sockfd = accept(server_sockfd, (struct sockaddr *)&addr, &addrlen);
+ if (client_sockfd < 0) {
+ DebuggerPrint("TCP accept failed\n");
+ return STATUS_FAILED_DRIVER_ENTRY;
+ }
+
+ int iResult;
+ SocketBuffer<1024> sb_send, sb_recv;
+
+ do {
+ bool ok = false;
+ RECV_PDU_BEGIN(client_sockfd, sb_recv, iResult, pdu_type, pdu_len) {
+ DebuggerPrint("PDU type/len: %u/%u\n", pdu_type, pdu_len);
+ switch ((enum PduTypes)pdu_type) {
+ case PDU_SOMETHING_WITH_UINTS: {
+ SomethingWithUINTsDeserializer swud;
+ if ((ok = swud.Deserialize(pdu_len, sb_recv.GetStart())) == true) {
+ SomethingWithUINTsSerializer swus;
+ if (swud.swu->has_id == TRUE) {
+ DebuggerPrint("Id: 0x%X\n", swud.swu->id);
+ swus.SetId(swud.swu->id + 1);
+ }
+ ok = sb_send.AddPdu(swus);
+ }
+ break;
+ }
+ case PDU_SOMETHING_MORE: {
+ SomethingMoreDeserializer smd;
+ if ((ok = smd.Deserialize(pdu_len, sb_recv.GetStart())) == true) {
+ SomethingMoreSerializer sms;
+ if (smd.sm->has_error_code == TRUE) {
+ DebuggerPrint("Error Code: %u\n", smd.sm->error_code);
+ }
+ if (smd.sm->uints->has_id == TRUE) {
+ DebuggerPrint("Id: 0x%X\n", smd.sm->uints->id);
+ sms.SetId(smd.sm->uints->id + 1);
+ }
+ sms.SetErrorCode(SOMETHING_MORE__ERRORS__SUCCESS);
+ sms.SetIpAddress(0xCCCCCCCC);
+ sms.SetPortNum(0xDDDDDDDD);
+ ok = sb_send.AddPdu(sms);
+ }
+ break;
+ }
+ case PDU_EVEN_MORE: {
+ EvenMoreDeserializer emd;
+ if ((ok = emd.Deserialize(pdu_len, sb_recv.GetStart())) == true) {
+ DebuggerPrint("EnumValue: %d\n", emd.em->enum_value);
+ if (emd.em->s != NULL) {
+ DebuggerPrint("String: '%s'\n", emd.em->s);
+ }
+ EvenMoreSerializer ems;
+ SomethingWithUINTsSerializer swus;
+ swus.SetId(0xDEADDEAD);
+ ems.SetS("Hi userspace!");
+ ems.AddUints(&swus);
+ ok = sb_send.AddPdu(ems);
+ }
+ break;
+ }
+ }
+ }
+ RECV_PDU_END(sb_recv, pdu_len);
+
+ if (ok == true) {
+ SEND_ALL(client_sockfd, sb_send, iResult);
+ if (iResult == SOCKET_ERROR || iResult == 0) {
+ DebuggerPrint("send failed\n");
+ break;
+ }
+ } else {
+ DebuggerPrint("Serialization/Deserialization failed\n");
+ break;
+ }
+ } while (iResult != SOCKET_ERROR && iResult > 0);
+
+ DebuggerPrint("Client gone.\n") closesocket(client_sockfd);
+ closesocket(server_sockfd);
+ KsDestroy();
+
+ return STATUS_SUCCESS;
+}
+
+VOID DriverUnload(_In_ struct _DRIVER_OBJECT *DriverObject) {
+ UNREFERENCED_PARAMETER(DriverObject);
+
+ DebuggerPrint("Bye.\n");
+}
+}
diff --git a/examples/driver-protobuf-c.bat b/examples/driver-protobuf-c.bat
new file mode 100644
index 0000000..671bf19
--- /dev/null
+++ b/examples/driver-protobuf-c.bat
@@ -0,0 +1,27 @@
+@echo off
+set SERVICE_NAME=protobuf-c
+set DRIVER="%~dp0\driver-protobuf-c.sys"
+
+net session >nul 2>&1
+if NOT %ERRORLEVEL% EQU 0 (
+ echo ERROR: This script requires Administrator privileges!
+ pause
+ exit /b 1
+)
+
+echo ---------------------------------------
+echo -- Service Name: %SERVICE_NAME%
+echo -- Driver......: %DRIVER%
+echo ---------------------------------------
+
+sc create %SERVICE_NAME% binPath= %DRIVER% type= kernel
+echo ---------------------------------------
+sc start %SERVICE_NAME%
+echo ---------------------------------------
+sc query %SERVICE_NAME%
+echo [PRESS A KEY TO STOP THE DRIVER]
+pause
+sc stop %SERVICE_NAME%
+sc delete %SERVICE_NAME%
+echo Done.
+timeout /t 3
diff --git a/examples/driver-protobuf-c.cpp b/examples/driver-protobuf-c.cpp
new file mode 100644
index 0000000..942782d
--- /dev/null
+++ b/examples/driver-protobuf-c.cpp
@@ -0,0 +1,105 @@
+#include "berkeley.h"
+#include "ksocket.h"
+#include "examples/example.pb-c.h"
+#include "wsk.h"
+
+#include "common.hpp"
+
+extern "C" {
+DRIVER_INITIALIZE DriverEntry;
+DRIVER_UNLOAD DriverUnload;
+
+#define DebuggerPrint(...) \
+ DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, __VA_ARGS__);
+
+NTSTATUS
+NTAPI
+DriverEntry(_In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING RegistryPath) {
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(RegistryPath);
+
+ size_t len = 0;
+
+ {
+ uint8_t *buf = NULL;
+
+ {
+ SomethingMoreSerializer sms;
+ sms.SetErrorCode(SOMETHING_MORE__ERRORS__SUCCESS);
+ sms.SetId(0x12345678);
+ sms.SetIpAddress(0xAAAAAAAA);
+ sms.SetPortNum(0xBBBBBBBB);
+ len = sms.GetSerializedSize();
+ buf = (uint8_t *)malloc(len);
+ if (buf == NULL) {
+ return STATUS_UNSUCCESSFUL;
+ }
+ if (sms.Serialize(buf) != len) {
+ DebuggerPrint("Packing failed.\n");
+ free(buf);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ DebuggerPrint("Packed Size: %zu\n", len);
+
+ SomethingMoreDeserializer smd;
+ if (smd.Deserialize(len, buf) == true && smd.sm->uints != NULL &&
+ smd.sm->uints->id == 0x12345678 &&
+ smd.sm->uints->ip_address == 0xAAAAAAAA &&
+ smd.sm->uints->port_num == 0xBBBBBBBB) {
+ DebuggerPrint("Success!\n");
+ }
+ }
+
+ free(buf);
+ }
+
+ {
+ EvenMoreSerializer ems(EVEN_MORE__SOME_ENUM__FIRST,
+ {0xde, 0xad, 0xc0, 0xde}, {0xde, 0xad, 0xc0, 0xde});
+ SomethingWithUINTsSerializer sws[3];
+
+ sws[0].SetId(0xdeadc0de);
+ sws[1].SetIpAddress(0xdeadbeef);
+ sws[2].SetPortNum(0xcafecafe);
+
+ ems.SetS("This is a zero-terminated String!");
+ ems.AddUints(&sws[0]);
+ ems.AddUints(&sws[1]);
+ ems.AddUints(&sws[2]);
+
+ len = ems.GetSerializedSize();
+ uint8_t tmp[len];
+ if (ems.Serialize(tmp) != len) {
+ DebuggerPrint("Packing failed.\n");
+ }
+ DebuggerPrint("Packed Size: %zu\n", len);
+
+ EvenMoreDeserializer emd;
+ if (emd.Deserialize(len, tmp) == true && emd.em->n_uints == 3 &&
+ emd.em->uints != NULL && emd.em->name.len > 0 &&
+ emd.em->name.data != NULL && emd.em->value.len > 0 &&
+ emd.em->value.data != NULL && emd.em->s != NULL) {
+ if (emd.em->enum_value == EVEN_MORE__SOME_ENUM__FIRST ||
+ emd.em->uints[0]->has_id == TRUE ||
+ emd.em->uints[0]->id == 0xdeadc0de ||
+ emd.em->uints[1]->has_ip_address == TRUE ||
+ emd.em->uints[1]->ip_address == 0xdeadbeef ||
+ emd.em->uints[2]->has_port_num == TRUE ||
+ emd.em->uints[2]->port_num == 0xcafecafe) {
+ DebuggerPrint("Success!\n");
+ }
+ DebuggerPrint("Deserialized String: '%s'\n", emd.em->s);
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+VOID DriverUnload(_In_ struct _DRIVER_OBJECT *DriverObject) {
+ UNREFERENCED_PARAMETER(DriverObject);
+
+ DebuggerPrint("Bye.");
+}
+}
diff --git a/examples/driver.bat b/examples/driver.bat
new file mode 100644
index 0000000..519d9e8
--- /dev/null
+++ b/examples/driver.bat
@@ -0,0 +1,27 @@
+@echo off
+set SERVICE_NAME=ksocket
+set DRIVER="%~dp0\driver.sys"
+
+net session >nul 2>&1
+if NOT %ERRORLEVEL% EQU 0 (
+ echo ERROR: This script requires Administrator privileges!
+ pause
+ exit /b 1
+)
+
+echo ---------------------------------------
+echo -- Service Name: %SERVICE_NAME%
+echo -- Driver......: %DRIVER%
+echo ---------------------------------------
+
+sc create %SERVICE_NAME% binPath= %DRIVER% type= kernel
+echo ---------------------------------------
+sc start %SERVICE_NAME%
+echo ---------------------------------------
+sc query %SERVICE_NAME%
+echo [PRESS A KEY TO STOP THE DRIVER]
+pause
+sc stop %SERVICE_NAME%
+sc delete %SERVICE_NAME%
+echo Done.
+timeout /t 3
diff --git a/examples/driver.cpp b/examples/driver.cpp
new file mode 100644
index 0000000..ceae8ff
--- /dev/null
+++ b/examples/driver.cpp
@@ -0,0 +1,152 @@
+
+extern "C" {
+#include "berkeley.h"
+#include "ksocket.h"
+#include "wsk.h"
+
+DRIVER_INITIALIZE DriverEntry;
+DRIVER_UNLOAD DriverUnload;
+
+#define DebuggerPrint(...) \
+ DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, __VA_ARGS__);
+
+NTSTATUS
+NTAPI
+DriverEntry(_In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING RegistryPath) {
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(RegistryPath);
+
+ NTSTATUS Status;
+
+ //
+ // Initialize KSOCKET.
+ //
+
+ Status = KsInitialize();
+
+ if (!NT_SUCCESS(Status)) {
+ return Status;
+ }
+
+ //
+ // Client.
+ // Perform HTTP request to http://httpbin.org/uuid
+ //
+
+ {
+ int result;
+ UNREFERENCED_PARAMETER(result);
+
+ char send_buffer[] = "GET /uuid HTTP/1.1\r\n"
+ "Host: httpbin.org\r\n"
+ "Connection: close\r\n"
+ "\r\n";
+
+ char recv_buffer[1024] = {};
+
+ struct addrinfo hints = {};
+ hints.ai_flags |= AI_CANONNAME;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ struct addrinfo *res;
+ result = getaddrinfo("httpbin.org", "80", &hints, &res);
+
+ int sockfd;
+ sockfd = socket_connection(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (sockfd < 0) {
+ DebuggerPrint("TCP client socket_connection failed\n");
+ return STATUS_FAILED_DRIVER_ENTRY;
+ }
+
+ result = connect(sockfd, res->ai_addr, (int)res->ai_addrlen);
+ if (result != 0) {
+ DebuggerPrint("TCP client connect failed\n");
+ return STATUS_FAILED_DRIVER_ENTRY;
+ }
+
+ result = send(sockfd, send_buffer, sizeof(send_buffer), 0);
+ if (result <= 0) {
+ DebuggerPrint("TCP client send failed\n");
+ return STATUS_FAILED_DRIVER_ENTRY;
+ }
+
+ result = recv(sockfd, recv_buffer, sizeof(recv_buffer), 0);
+ if (result <= 0) {
+ DebuggerPrint("TCP client recv failed\n");
+ return STATUS_FAILED_DRIVER_ENTRY;
+ } else {
+ DebuggerPrint("TCP client:\n%.*s\n", result, recv_buffer);
+ }
+
+ closesocket(sockfd);
+ }
+
+ //
+ // TCP server.
+ // Listen on port 9095, wait for some message,
+ // then send our buffer and close connection.
+ //
+
+ {
+ int result;
+
+ char send_buffer[] = "Hello from WSK!";
+ char recv_buffer[1024] = {0};
+
+ int server_sockfd = socket_listen(AF_INET, SOCK_STREAM, 0);
+
+ struct sockaddr_in addr;
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_port = htons(9095);
+
+ result = bind(server_sockfd, (struct sockaddr *)&addr, sizeof(addr));
+ if (result != 0) {
+ DebuggerPrint("TCP server bind failed\n");
+ return STATUS_FAILED_DRIVER_ENTRY;
+ }
+
+ result = listen(server_sockfd, 1);
+ if (result != 0) {
+ DebuggerPrint("TCP server listen failed\n");
+ return STATUS_FAILED_DRIVER_ENTRY;
+ }
+
+ socklen_t addrlen = sizeof(addr);
+ int client_sockfd =
+ accept(server_sockfd, (struct sockaddr *)&addr, &addrlen);
+ if (client_sockfd < 0) {
+ DebuggerPrint("TCP accept failed\n");
+ return STATUS_FAILED_DRIVER_ENTRY;
+ }
+
+ result = recv(client_sockfd, recv_buffer, sizeof(recv_buffer) - 1, 0);
+ if (result > 0) {
+ DebuggerPrint("TCP server:\n%.*s\n", result, recv_buffer);
+ } else {
+ DebuggerPrint("TCP server recv failed\n");
+ }
+
+ result = send(client_sockfd, send_buffer, sizeof(send_buffer), 0);
+
+ // Wait for the client to terminate the connection.
+ do {
+ } while (recv(client_sockfd, recv_buffer, sizeof(recv_buffer) - 1, 0) > 0);
+
+ closesocket(client_sockfd);
+ closesocket(server_sockfd);
+ }
+
+ KsDestroy();
+
+ return STATUS_SUCCESS;
+}
+
+VOID DriverUnload(_In_ struct _DRIVER_OBJECT *DriverObject) {
+ UNREFERENCED_PARAMETER(DriverObject);
+
+ DebuggerPrint("Bye.");
+}
+}
diff --git a/examples/echo_srv.py b/examples/echo_srv.py
new file mode 100644
index 0000000..b3855eb
--- /dev/null
+++ b/examples/echo_srv.py
@@ -0,0 +1,16 @@
+import socket
+
+HOST = '127.0.0.1'
+PORT = 9095
+
+with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
+ s.bind((HOST, PORT))
+ s.listen()
+ conn, addr = s.accept()
+ with conn:
+ while True:
+ data = conn.recv(1024)
+ print('recvd: {} bytes'.format(len(data)))
+ if len(data) == 0:
+ break;
+ conn.sendall(data)
diff --git a/examples/example.pb-c.c b/examples/example.pb-c.c
new file mode 100644
index 0000000..20b33ae
--- /dev/null
+++ b/examples/example.pb-c.c
@@ -0,0 +1,411 @@
+/* Generated by the protocol buffer compiler. DO NOT EDIT! */
+/* Generated from: examples/example.proto */
+
+/* Do not generate deprecated warnings for self */
+#ifndef PROTOBUF_C__NO_DEPRECATED
+#define PROTOBUF_C__NO_DEPRECATED
+#endif
+
+#include "examples/example.pb-c.h"
+void something_with_uints__init
+ (SomethingWithUINTs *message)
+{
+ static const SomethingWithUINTs init_value = SOMETHING_WITH_UINTS__INIT;
+ *message = init_value;
+}
+size_t something_with_uints__get_packed_size
+ (const SomethingWithUINTs *message)
+{
+ assert(message->base.descriptor == &something_with_uints__descriptor);
+ return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t something_with_uints__pack
+ (const SomethingWithUINTs *message,
+ uint8_t *out)
+{
+ assert(message->base.descriptor == &something_with_uints__descriptor);
+ return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t something_with_uints__pack_to_buffer
+ (const SomethingWithUINTs *message,
+ ProtobufCBuffer *buffer)
+{
+ assert(message->base.descriptor == &something_with_uints__descriptor);
+ return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+SomethingWithUINTs *
+ something_with_uints__unpack
+ (ProtobufCAllocator *allocator,
+ size_t len,
+ const uint8_t *data)
+{
+ return (SomethingWithUINTs *)
+ protobuf_c_message_unpack (&something_with_uints__descriptor,
+ allocator, len, data);
+}
+void something_with_uints__free_unpacked
+ (SomethingWithUINTs *message,
+ ProtobufCAllocator *allocator)
+{
+ if(!message)
+ return;
+ assert(message->base.descriptor == &something_with_uints__descriptor);
+ protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+void something_more__init
+ (SomethingMore *message)
+{
+ static const SomethingMore init_value = SOMETHING_MORE__INIT;
+ *message = init_value;
+}
+size_t something_more__get_packed_size
+ (const SomethingMore *message)
+{
+ assert(message->base.descriptor == &something_more__descriptor);
+ return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t something_more__pack
+ (const SomethingMore *message,
+ uint8_t *out)
+{
+ assert(message->base.descriptor == &something_more__descriptor);
+ return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t something_more__pack_to_buffer
+ (const SomethingMore *message,
+ ProtobufCBuffer *buffer)
+{
+ assert(message->base.descriptor == &something_more__descriptor);
+ return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+SomethingMore *
+ something_more__unpack
+ (ProtobufCAllocator *allocator,
+ size_t len,
+ const uint8_t *data)
+{
+ return (SomethingMore *)
+ protobuf_c_message_unpack (&something_more__descriptor,
+ allocator, len, data);
+}
+void something_more__free_unpacked
+ (SomethingMore *message,
+ ProtobufCAllocator *allocator)
+{
+ if(!message)
+ return;
+ assert(message->base.descriptor == &something_more__descriptor);
+ protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+void even_more__init
+ (EvenMore *message)
+{
+ static const EvenMore init_value = EVEN_MORE__INIT;
+ *message = init_value;
+}
+size_t even_more__get_packed_size
+ (const EvenMore *message)
+{
+ assert(message->base.descriptor == &even_more__descriptor);
+ return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t even_more__pack
+ (const EvenMore *message,
+ uint8_t *out)
+{
+ assert(message->base.descriptor == &even_more__descriptor);
+ return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t even_more__pack_to_buffer
+ (const EvenMore *message,
+ ProtobufCBuffer *buffer)
+{
+ assert(message->base.descriptor == &even_more__descriptor);
+ return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+EvenMore *
+ even_more__unpack
+ (ProtobufCAllocator *allocator,
+ size_t len,
+ const uint8_t *data)
+{
+ return (EvenMore *)
+ protobuf_c_message_unpack (&even_more__descriptor,
+ allocator, len, data);
+}
+void even_more__free_unpacked
+ (EvenMore *message,
+ ProtobufCAllocator *allocator)
+{
+ if(!message)
+ return;
+ assert(message->base.descriptor == &even_more__descriptor);
+ protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+static const ProtobufCFieldDescriptor something_with_uints__field_descriptors[3] =
+{
+ {
+ "id",
+ 1,
+ PROTOBUF_C_LABEL_OPTIONAL,
+ PROTOBUF_C_TYPE_UINT32,
+ offsetof(SomethingWithUINTs, has_id),
+ offsetof(SomethingWithUINTs, id),
+ NULL,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+ {
+ "ip_address",
+ 2,
+ PROTOBUF_C_LABEL_OPTIONAL,
+ PROTOBUF_C_TYPE_UINT32,
+ offsetof(SomethingWithUINTs, has_ip_address),
+ offsetof(SomethingWithUINTs, ip_address),
+ NULL,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+ {
+ "port_num",
+ 3,
+ PROTOBUF_C_LABEL_OPTIONAL,
+ PROTOBUF_C_TYPE_UINT32,
+ offsetof(SomethingWithUINTs, has_port_num),
+ offsetof(SomethingWithUINTs, port_num),
+ NULL,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+};
+static const unsigned something_with_uints__field_indices_by_name[] = {
+ 0, /* field[0] = id */
+ 1, /* field[1] = ip_address */
+ 2, /* field[2] = port_num */
+};
+static const ProtobufCIntRange something_with_uints__number_ranges[1 + 1] =
+{
+ { 1, 0 },
+ { 0, 3 }
+};
+const ProtobufCMessageDescriptor something_with_uints__descriptor =
+{
+ PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+ "SomethingWithUINTs",
+ "SomethingWithUINTs",
+ "SomethingWithUINTs",
+ "",
+ sizeof(SomethingWithUINTs),
+ 3,
+ something_with_uints__field_descriptors,
+ something_with_uints__field_indices_by_name,
+ 1, something_with_uints__number_ranges,
+ (ProtobufCMessageInit) something_with_uints__init,
+ NULL,NULL,NULL /* reserved[123] */
+};
+static const ProtobufCEnumValue something_more__errors__enum_values_by_number[5] =
+{
+ { "SUCCESS", "SOMETHING_MORE__ERRORS__SUCCESS", 200 },
+ { "ERROR_BAD_REQUEST", "SOMETHING_MORE__ERRORS__ERROR_BAD_REQUEST", 400 },
+ { "ERROR_NOT_FOUND", "SOMETHING_MORE__ERRORS__ERROR_NOT_FOUND", 404 },
+ { "ERROR_SERVER_ERROR", "SOMETHING_MORE__ERRORS__ERROR_SERVER_ERROR", 500 },
+ { "ERROR_SERVICE_UNAVAILABLE", "SOMETHING_MORE__ERRORS__ERROR_SERVICE_UNAVAILABLE", 503 },
+};
+static const ProtobufCIntRange something_more__errors__value_ranges[] = {
+{200, 0},{400, 1},{404, 2},{500, 3},{503, 4},{0, 5}
+};
+static const ProtobufCEnumValueIndex something_more__errors__enum_values_by_name[5] =
+{
+ { "ERROR_BAD_REQUEST", 1 },
+ { "ERROR_NOT_FOUND", 2 },
+ { "ERROR_SERVER_ERROR", 3 },
+ { "ERROR_SERVICE_UNAVAILABLE", 4 },
+ { "SUCCESS", 0 },
+};
+const ProtobufCEnumDescriptor something_more__errors__descriptor =
+{
+ PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
+ "SomethingMore.Errors",
+ "Errors",
+ "SomethingMore__Errors",
+ "",
+ 5,
+ something_more__errors__enum_values_by_number,
+ 5,
+ something_more__errors__enum_values_by_name,
+ 5,
+ something_more__errors__value_ranges,
+ NULL,NULL,NULL,NULL /* reserved[1234] */
+};
+static const ProtobufCFieldDescriptor something_more__field_descriptors[2] =
+{
+ {
+ "error_code",
+ 1,
+ PROTOBUF_C_LABEL_OPTIONAL,
+ PROTOBUF_C_TYPE_ENUM,
+ offsetof(SomethingMore, has_error_code),
+ offsetof(SomethingMore, error_code),
+ &something_more__errors__descriptor,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+ {
+ "uints",
+ 2,
+ PROTOBUF_C_LABEL_OPTIONAL,
+ PROTOBUF_C_TYPE_MESSAGE,
+ 0, /* quantifier_offset */
+ offsetof(SomethingMore, uints),
+ &something_with_uints__descriptor,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+};
+static const unsigned something_more__field_indices_by_name[] = {
+ 0, /* field[0] = error_code */
+ 1, /* field[1] = uints */
+};
+static const ProtobufCIntRange something_more__number_ranges[1 + 1] =
+{
+ { 1, 0 },
+ { 0, 2 }
+};
+const ProtobufCMessageDescriptor something_more__descriptor =
+{
+ PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+ "SomethingMore",
+ "SomethingMore",
+ "SomethingMore",
+ "",
+ sizeof(SomethingMore),
+ 2,
+ something_more__field_descriptors,
+ something_more__field_indices_by_name,
+ 1, something_more__number_ranges,
+ (ProtobufCMessageInit) something_more__init,
+ NULL,NULL,NULL /* reserved[123] */
+};
+static const ProtobufCEnumValue even_more__some_enum__enum_values_by_number[2] =
+{
+ { "FIRST", "EVEN_MORE__SOME_ENUM__FIRST", 254 },
+ { "SECOND", "EVEN_MORE__SOME_ENUM__SECOND", 255 },
+};
+static const ProtobufCIntRange even_more__some_enum__value_ranges[] = {
+{254, 0},{0, 2}
+};
+static const ProtobufCEnumValueIndex even_more__some_enum__enum_values_by_name[2] =
+{
+ { "FIRST", 0 },
+ { "SECOND", 1 },
+};
+const ProtobufCEnumDescriptor even_more__some_enum__descriptor =
+{
+ PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
+ "EvenMore.SomeEnum",
+ "SomeEnum",
+ "EvenMore__SomeEnum",
+ "",
+ 2,
+ even_more__some_enum__enum_values_by_number,
+ 2,
+ even_more__some_enum__enum_values_by_name,
+ 1,
+ even_more__some_enum__value_ranges,
+ NULL,NULL,NULL,NULL /* reserved[1234] */
+};
+static const ProtobufCFieldDescriptor even_more__field_descriptors[5] =
+{
+ {
+ "enum_value",
+ 1,
+ PROTOBUF_C_LABEL_REQUIRED,
+ PROTOBUF_C_TYPE_ENUM,
+ 0, /* quantifier_offset */
+ offsetof(EvenMore, enum_value),
+ &even_more__some_enum__descriptor,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+ {
+ "uints",
+ 2,
+ PROTOBUF_C_LABEL_REPEATED,
+ PROTOBUF_C_TYPE_MESSAGE,
+ offsetof(EvenMore, n_uints),
+ offsetof(EvenMore, uints),
+ &something_with_uints__descriptor,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+ {
+ "name",
+ 3,
+ PROTOBUF_C_LABEL_REQUIRED,
+ PROTOBUF_C_TYPE_BYTES,
+ 0, /* quantifier_offset */
+ offsetof(EvenMore, name),
+ NULL,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+ {
+ "value",
+ 4,
+ PROTOBUF_C_LABEL_REQUIRED,
+ PROTOBUF_C_TYPE_BYTES,
+ 0, /* quantifier_offset */
+ offsetof(EvenMore, value),
+ NULL,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+ {
+ "s",
+ 5,
+ PROTOBUF_C_LABEL_OPTIONAL,
+ PROTOBUF_C_TYPE_STRING,
+ 0, /* quantifier_offset */
+ offsetof(EvenMore, s),
+ NULL,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+};
+static const unsigned even_more__field_indices_by_name[] = {
+ 0, /* field[0] = enum_value */
+ 2, /* field[2] = name */
+ 4, /* field[4] = s */
+ 1, /* field[1] = uints */
+ 3, /* field[3] = value */
+};
+static const ProtobufCIntRange even_more__number_ranges[1 + 1] =
+{
+ { 1, 0 },
+ { 0, 5 }
+};
+const ProtobufCMessageDescriptor even_more__descriptor =
+{
+ PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+ "EvenMore",
+ "EvenMore",
+ "EvenMore",
+ "",
+ sizeof(EvenMore),
+ 5,
+ even_more__field_descriptors,
+ even_more__field_indices_by_name,
+ 1, even_more__number_ranges,
+ (ProtobufCMessageInit) even_more__init,
+ NULL,NULL,NULL /* reserved[123] */
+};
diff --git a/examples/example.pb-c.h b/examples/example.pb-c.h
new file mode 100644
index 0000000..9e4f1db
--- /dev/null
+++ b/examples/example.pb-c.h
@@ -0,0 +1,166 @@
+/* Generated by the protocol buffer compiler. DO NOT EDIT! */
+/* Generated from: examples/example.proto */
+
+#ifndef PROTOBUF_C_examples_2fexample_2eproto__INCLUDED
+#define PROTOBUF_C_examples_2fexample_2eproto__INCLUDED
+
+#include <protobuf-c/protobuf-c.h>
+
+PROTOBUF_C__BEGIN_DECLS
+
+#if PROTOBUF_C_VERSION_NUMBER < 1000000
+# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
+#elif 1003003 < PROTOBUF_C_MIN_COMPILER_VERSION
+# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
+#endif
+
+
+typedef struct _SomethingWithUINTs SomethingWithUINTs;
+typedef struct _SomethingMore SomethingMore;
+typedef struct _EvenMore EvenMore;
+
+
+/* --- enums --- */
+
+typedef enum _SomethingMore__Errors {
+ SOMETHING_MORE__ERRORS__SUCCESS = 200,
+ SOMETHING_MORE__ERRORS__ERROR_BAD_REQUEST = 400,
+ SOMETHING_MORE__ERRORS__ERROR_NOT_FOUND = 404,
+ SOMETHING_MORE__ERRORS__ERROR_SERVER_ERROR = 500,
+ SOMETHING_MORE__ERRORS__ERROR_SERVICE_UNAVAILABLE = 503
+ PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SOMETHING_MORE__ERRORS)
+} SomethingMore__Errors;
+typedef enum _EvenMore__SomeEnum {
+ EVEN_MORE__SOME_ENUM__FIRST = 254,
+ EVEN_MORE__SOME_ENUM__SECOND = 255
+ PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(EVEN_MORE__SOME_ENUM)
+} EvenMore__SomeEnum;
+
+/* --- messages --- */
+
+struct _SomethingWithUINTs
+{
+ ProtobufCMessage base;
+ protobuf_c_boolean has_id;
+ uint32_t id;
+ protobuf_c_boolean has_ip_address;
+ uint32_t ip_address;
+ protobuf_c_boolean has_port_num;
+ uint32_t port_num;
+};
+#define SOMETHING_WITH_UINTS__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&something_with_uints__descriptor) \
+ , 0, 0, 0, 0, 0, 0 }
+
+
+struct _SomethingMore
+{
+ ProtobufCMessage base;
+ protobuf_c_boolean has_error_code;
+ SomethingMore__Errors error_code;
+ SomethingWithUINTs *uints;
+};
+#define SOMETHING_MORE__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&something_more__descriptor) \
+ , 0, SOMETHING_MORE__ERRORS__SUCCESS, NULL }
+
+
+struct _EvenMore
+{
+ ProtobufCMessage base;
+ EvenMore__SomeEnum enum_value;
+ size_t n_uints;
+ SomethingWithUINTs **uints;
+ ProtobufCBinaryData name;
+ ProtobufCBinaryData value;
+ char *s;
+};
+#define EVEN_MORE__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&even_more__descriptor) \
+ , EVEN_MORE__SOME_ENUM__FIRST, 0,NULL, {0,NULL}, {0,NULL}, NULL }
+
+
+/* SomethingWithUINTs methods */
+void something_with_uints__init
+ (SomethingWithUINTs *message);
+size_t something_with_uints__get_packed_size
+ (const SomethingWithUINTs *message);
+size_t something_with_uints__pack
+ (const SomethingWithUINTs *message,
+ uint8_t *out);
+size_t something_with_uints__pack_to_buffer
+ (const SomethingWithUINTs *message,
+ ProtobufCBuffer *buffer);
+SomethingWithUINTs *
+ something_with_uints__unpack
+ (ProtobufCAllocator *allocator,
+ size_t len,
+ const uint8_t *data);
+void something_with_uints__free_unpacked
+ (SomethingWithUINTs *message,
+ ProtobufCAllocator *allocator);
+/* SomethingMore methods */
+void something_more__init
+ (SomethingMore *message);
+size_t something_more__get_packed_size
+ (const SomethingMore *message);
+size_t something_more__pack
+ (const SomethingMore *message,
+ uint8_t *out);
+size_t something_more__pack_to_buffer
+ (const SomethingMore *message,
+ ProtobufCBuffer *buffer);
+SomethingMore *
+ something_more__unpack
+ (ProtobufCAllocator *allocator,
+ size_t len,
+ const uint8_t *data);
+void something_more__free_unpacked
+ (SomethingMore *message,
+ ProtobufCAllocator *allocator);
+/* EvenMore methods */
+void even_more__init
+ (EvenMore *message);
+size_t even_more__get_packed_size
+ (const EvenMore *message);
+size_t even_more__pack
+ (const EvenMore *message,
+ uint8_t *out);
+size_t even_more__pack_to_buffer
+ (const EvenMore *message,
+ ProtobufCBuffer *buffer);
+EvenMore *
+ even_more__unpack
+ (ProtobufCAllocator *allocator,
+ size_t len,
+ const uint8_t *data);
+void even_more__free_unpacked
+ (EvenMore *message,
+ ProtobufCAllocator *allocator);
+/* --- per-message closures --- */
+
+typedef void (*SomethingWithUINTs_Closure)
+ (const SomethingWithUINTs *message,
+ void *closure_data);
+typedef void (*SomethingMore_Closure)
+ (const SomethingMore *message,
+ void *closure_data);
+typedef void (*EvenMore_Closure)
+ (const EvenMore *message,
+ void *closure_data);
+
+/* --- services --- */
+
+
+/* --- descriptors --- */
+
+extern const ProtobufCMessageDescriptor something_with_uints__descriptor;
+extern const ProtobufCMessageDescriptor something_more__descriptor;
+extern const ProtobufCEnumDescriptor something_more__errors__descriptor;
+extern const ProtobufCMessageDescriptor even_more__descriptor;
+extern const ProtobufCEnumDescriptor even_more__some_enum__descriptor;
+
+PROTOBUF_C__END_DECLS
+
+
+#endif /* PROTOBUF_C_examples_2fexample_2eproto__INCLUDED */
diff --git a/examples/example.proto b/examples/example.proto
new file mode 100644
index 0000000..e77f36c
--- /dev/null
+++ b/examples/example.proto
@@ -0,0 +1,31 @@
+syntax = "proto2";
+
+message SomethingWithUINTs {
+ optional uint32 id = 1;
+ optional uint32 ip_address = 2;
+ optional uint32 port_num = 3;
+}
+
+message SomethingMore {
+ enum Errors {
+ SUCCESS = 200;
+ ERROR_BAD_REQUEST = 400;
+ ERROR_NOT_FOUND = 404;
+ ERROR_SERVER_ERROR = 500;
+ ERROR_SERVICE_UNAVAILABLE = 503;
+ }
+ optional Errors error_code = 1;
+ optional SomethingWithUINTs uints = 2;
+}
+
+message EvenMore {
+ enum SomeEnum {
+ FIRST = 0xFE;
+ SECOND = 0xFF;
+ }
+ required SomeEnum enum_value = 1;
+ repeated SomethingWithUINTs uints = 2;
+ required bytes name=3;
+ required bytes value=4;
+ optional string s=5;
+}
diff --git a/examples/userspace_client.cpp b/examples/userspace_client.cpp
new file mode 100644
index 0000000..cb2a3b4
--- /dev/null
+++ b/examples/userspace_client.cpp
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h> // Needed for _wtoi
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+int main(int argc, char **argv) {
+ WSADATA wsaData = {};
+ int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+
+ UNREFERENCED_PARAMETER(argc);
+ UNREFERENCED_PARAMETER(argv);
+
+ if (iResult != 0) {
+ wprintf(L"WSAStartup failed: %d\n", iResult);
+ return 1;
+ }
+
+ SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if (sock == INVALID_SOCKET) {
+ wprintf(L"socket function failed with error = %d\n", WSAGetLastError());
+ } else {
+ wprintf(L"socket function succeeded\n");
+ }
+
+ sockaddr_in clientService;
+ clientService.sin_family = AF_INET;
+ clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
+ clientService.sin_port = htons(9095);
+
+ do {
+ iResult = connect(sock, (SOCKADDR *)&clientService, sizeof(clientService));
+ if (iResult == SOCKET_ERROR) {
+ wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
+ Sleep(1000);
+ }
+ } while (iResult == SOCKET_ERROR);
+
+ wprintf(L"Connected to server.\n");
+
+ char sendbuf[] = "Hello Driver, greetings from userspace.";
+ iResult = send(sock, sendbuf, (int)strlen(sendbuf), 0);
+ if (iResult == SOCKET_ERROR) {
+ wprintf(L"send failed with error: %d\n", WSAGetLastError());
+ closesocket(sock);
+ WSACleanup();
+ return 1;
+ }
+
+ {
+ char recvbuf[1024];
+
+ iResult = recv(sock, recvbuf, 1024, 0);
+ if (iResult > 0) {
+ wprintf(L"Bytes received: %d\n", iResult);
+ wprintf(L"Data received: %.*s\n", iResult, recvbuf);
+ } else if (iResult == 0) {
+ wprintf(L"Connection closed by remote\n");
+ } else if (WSAGetLastError() != WSAECONNRESET) {
+ wprintf(L"recv failed: %d\n", WSAGetLastError());
+ }
+ };
+ wprintf(L"Closing Connection ..\n");
+
+ iResult = closesocket(sock);
+ if (iResult == SOCKET_ERROR) {
+ wprintf(L"closesocket function failed with error: %ld\n",
+ WSAGetLastError());
+ WSACleanup();
+ return 1;
+ }
+
+ WSACleanup();
+
+ system("pause");
+
+ return 0;
+}
diff --git a/examples/userspace_client_protobuf.cpp b/examples/userspace_client_protobuf.cpp
new file mode 100644
index 0000000..b8ad711
--- /dev/null
+++ b/examples/userspace_client_protobuf.cpp
@@ -0,0 +1,152 @@
+#include <stdio.h>
+#include <stdlib.h> // Needed for _wtoi
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+#include "common.hpp"
+#include "examples/example.pb-c.h"
+
+int main(int argc, char **argv) {
+ WSADATA wsaData = {};
+ int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+
+ UNREFERENCED_PARAMETER(argc);
+ UNREFERENCED_PARAMETER(argv);
+
+ if (iResult != 0) {
+ wprintf(L"WSAStartup failed: %d\n", iResult);
+ return 1;
+ }
+
+ SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if (sock == INVALID_SOCKET) {
+ wprintf(L"socket function failed with error = %d\n", WSAGetLastError());
+ } else {
+ wprintf(L"socket function succeeded\n");
+ }
+
+ sockaddr_in clientService;
+ clientService.sin_family = AF_INET;
+ clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
+ clientService.sin_port = htons(9095);
+
+ do {
+ iResult = connect(sock, (SOCKADDR *)&clientService, sizeof(clientService));
+ if (iResult == SOCKET_ERROR) {
+ wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
+ Sleep(1000);
+ }
+ } while (iResult == SOCKET_ERROR);
+
+ wprintf(L"Connected to server.\n");
+
+ uint32_t start_id = 0x12345678;
+ for (size_t i = 0; i < 256; ++i) {
+ SocketBuffer<1024> sb_send, sb_recv;
+ SomethingMoreSerializer sms;
+
+ sms.SetErrorCode(SOMETHING_MORE__ERRORS__SUCCESS);
+ sms.SetId(start_id++);
+ sms.SetIpAddress(0xAAAAAAAA);
+ sms.SetPortNum(0xBBBBBBBB);
+
+ if (!sb_send.AddPdu(sms)) {
+ wprintf(L"Serialization failed\n");
+ break;
+ }
+
+ SEND_ALL(sock, sb_send, iResult);
+ if (iResult == SOCKET_ERROR || iResult == 0) {
+ wprintf(L"send failed with error: %d\n", WSAGetLastError());
+ break;
+ }
+
+ RECV_PDU_BEGIN(sock, sb_recv, iResult, pdu_type, pdu_len) {
+ wprintf(L"PDU type/len: %u/%u\n", pdu_type, pdu_len);
+ switch ((enum PduTypes)pdu_type) {
+ case PDU_SOMETHING_WITH_UINTS: {
+ break;
+ }
+ case PDU_SOMETHING_MORE: {
+ SomethingMoreDeserializer smd;
+ if (smd.Deserialize(pdu_len, sb_recv.GetStart()) == true &&
+ smd.sm->uints != NULL && smd.sm->uints->has_id == TRUE &&
+ smd.sm->uints->has_ip_address == TRUE &&
+ smd.sm->uints->has_port_num == TRUE)
+ wprintf(L"Id: 0x%X, IpAddress: 0x%X, PortNum: 0x%X\n",
+ smd.sm->uints->id, smd.sm->uints->ip_address,
+ smd.sm->uints->port_num);
+ break;
+ }
+ case PDU_EVEN_MORE: {
+ break;
+ }
+ }
+ }
+ RECV_PDU_END(sb_recv, pdu_len);
+
+ ////////////////////////////////////////////////////////
+
+ EvenMoreSerializer ems(EVEN_MORE__SOME_ENUM__FIRST,
+ {0xde, 0xad, 0xc0, 0xde}, {0xde, 0xad, 0xc0, 0xde});
+ SomethingWithUINTsSerializer swus[3];
+
+ swus[0].SetId(0xdeadc0de);
+ swus[1].SetIpAddress(0xdeadbeef);
+ swus[2].SetPortNum(0xcafecafe);
+
+ ems.SetS("This is a zero-terminated String!");
+ ems.AddUints(&swus[0]);
+ ems.AddUints(&swus[1]);
+ ems.AddUints(&swus[2]);
+
+ if (!sb_send.AddPdu(ems)) {
+ wprintf(L"Serialization failed\n");
+ break;
+ }
+
+ SEND_ALL(sock, sb_send, iResult);
+ if (iResult == SOCKET_ERROR || iResult == 0) {
+ wprintf(L"send failed with error: %d\n", WSAGetLastError());
+ break;
+ }
+
+ RECV_PDU_BEGIN(sock, sb_recv, iResult, pdu_type, pdu_len) {
+ wprintf(L"PDU type/len: %u/%u\n", pdu_type, pdu_len);
+ switch ((enum PduTypes)pdu_type) {
+ case PDU_SOMETHING_WITH_UINTS: {
+ break;
+ }
+ case PDU_SOMETHING_MORE: {
+ break;
+ }
+ case PDU_EVEN_MORE: {
+ EvenMoreDeserializer emd;
+ if (emd.Deserialize(pdu_len, sb_recv.GetStart()) == true) {
+ wprintf(L"EnumValue: %d\n", emd.em->enum_value);
+ if (emd.em->s != NULL)
+ wprintf(L"String: '%s'\n", emd.em->s);
+ }
+ break;
+ }
+ }
+ }
+ RECV_PDU_END(sb_recv, pdu_len);
+ }
+ wprintf(L"Closing Connection ..\n");
+
+ iResult = closesocket(sock);
+ if (iResult == SOCKET_ERROR) {
+ wprintf(L"closesocket function failed with error: %ld\n",
+ WSAGetLastError());
+ WSACleanup();
+ return 1;
+ }
+
+ WSACleanup();
+
+ system("pause");
+
+ return 0;
+}