From 38495d423f23b145a4377f87a536db5d2721f814 Mon Sep 17 00:00:00 2001
From: Toni Uhlig <matzeton@googlemail.com>
Date: Fri, 9 Sep 2022 16:52:28 +0200
Subject: Cleaned up repository, moved files where they belong to.

Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
---
 Makefile                               |  19 +-
 common.hpp                             |   2 +-
 driver-protobuf-c-tcp.bat              |  27 ---
 driver-protobuf-c-tcp.cpp              | 139 -----------
 driver-protobuf-c.bat                  |  27 ---
 driver-protobuf-c.cpp                  | 105 ---------
 driver.bat                             |  27 ---
 driver.cpp                             | 152 ------------
 echo_srv.py                            |  16 --
 examples/driver-protobuf-c-tcp.bat     |  27 +++
 examples/driver-protobuf-c-tcp.cpp     | 139 +++++++++++
 examples/driver-protobuf-c.bat         |  27 +++
 examples/driver-protobuf-c.cpp         | 105 +++++++++
 examples/driver.bat                    |  27 +++
 examples/driver.cpp                    | 152 ++++++++++++
 examples/echo_srv.py                   |  16 ++
 examples/example.pb-c.c                | 411 +++++++++++++++++++++++++++++++++
 examples/example.pb-c.h                | 166 +++++++++++++
 examples/example.proto                 |  31 +++
 examples/userspace_client.cpp          |  78 +++++++
 examples/userspace_client_protobuf.cpp | 152 ++++++++++++
 protobuf-c/example.pb-c.c              | 411 ---------------------------------
 protobuf-c/example.pb-c.h              | 166 -------------
 protobuf-c/example.proto               |  31 ---
 userspace_client.cpp                   |  78 -------
 userspace_client_protobuf.cpp          | 152 ------------
 26 files changed, 1343 insertions(+), 1340 deletions(-)
 delete mode 100644 driver-protobuf-c-tcp.bat
 delete mode 100644 driver-protobuf-c-tcp.cpp
 delete mode 100644 driver-protobuf-c.bat
 delete mode 100644 driver-protobuf-c.cpp
 delete mode 100644 driver.bat
 delete mode 100644 driver.cpp
 delete mode 100644 echo_srv.py
 create mode 100644 examples/driver-protobuf-c-tcp.bat
 create mode 100644 examples/driver-protobuf-c-tcp.cpp
 create mode 100644 examples/driver-protobuf-c.bat
 create mode 100644 examples/driver-protobuf-c.cpp
 create mode 100644 examples/driver.bat
 create mode 100644 examples/driver.cpp
 create mode 100644 examples/echo_srv.py
 create mode 100644 examples/example.pb-c.c
 create mode 100644 examples/example.pb-c.h
 create mode 100644 examples/example.proto
 create mode 100644 examples/userspace_client.cpp
 create mode 100644 examples/userspace_client_protobuf.cpp
 delete mode 100644 protobuf-c/example.pb-c.c
 delete mode 100644 protobuf-c/example.pb-c.h
 delete mode 100644 protobuf-c/example.proto
 delete mode 100644 userspace_client.cpp
 delete mode 100644 userspace_client_protobuf.cpp

diff --git a/Makefile b/Makefile
index 35e3a38..dbeff62 100644
--- a/Makefile
+++ b/Makefile
@@ -5,23 +5,23 @@ endif
 include $(DPP_ROOT)/Makefile.inc
 
 DRIVER0_NAME = driver
-DRIVER0_OBJECTS = $(DRIVER0_NAME).o ksocket.o berkeley.o
+DRIVER0_OBJECTS = examples/$(DRIVER0_NAME).o ksocket.o berkeley.o
 DRIVER0_TARGET = $(DRIVER0_NAME).sys
 
 DRIVER1_NAME = driver-protobuf-c
-DRIVER1_OBJECTS = $(DRIVER1_NAME).o protobuf-c/protobuf-c.o protobuf-c/example.pb-c.o
+DRIVER1_OBJECTS = examples/$(DRIVER1_NAME).o protobuf-c/protobuf-c.o examples/example.pb-c.o
 DRIVER1_TARGET = $(DRIVER1_NAME).sys
 
 DRIVER2_NAME = driver-protobuf-c-tcp
-DRIVER2_OBJECTS = $(DRIVER2_NAME).o ksocket.o berkeley.o protobuf-c/protobuf-c.o protobuf-c/example.pb-c.o
+DRIVER2_OBJECTS = examples/$(DRIVER2_NAME).o ksocket.o berkeley.o protobuf-c/protobuf-c.o examples/example.pb-c.o
 DRIVER2_TARGET = $(DRIVER2_NAME).sys
 
 USERSPACE0_NAME = userspace_client
-USERSPACE0_OBJECTS = $(USERSPACE0_NAME).o
+USERSPACE0_OBJECTS = examples/$(USERSPACE0_NAME).o
 USERSPACE0_TARGET = $(USERSPACE0_NAME).exe
 
 USERSPACE1_NAME = userspace_client_protobuf
-USERSPACE1_OBJECTS = $(USERSPACE1_NAME).o protobuf-c/protobuf-c.o protobuf-c/example.pb-c.o
+USERSPACE1_OBJECTS = examples/$(USERSPACE1_NAME).o protobuf-c/protobuf-c.o examples/example.pb-c.o
 USERSPACE1_TARGET = $(USERSPACE1_NAME).exe
 
 # mingw-w64-dpp related
@@ -53,15 +53,18 @@ $(USERSPACE0_TARGET): $(USERSPACE0_OBJECTS)
 $(USERSPACE1_TARGET): $(USERSPACE1_OBJECTS)
 	$(call LINK_CPP_USER_TARGET,$(USERSPACE1_OBJECTS),$@)
 
+generate:
+	protoc-c --c_out=. examples/example.proto
+
 install: $(DRIVER0_TARGET) $(DRIVER1_TARGET) $(DRIVER2_TARGET) $(USERSPACE0_TARGET) $(USERSPACE1_TARGET)
 	$(call INSTALL_EXEC_SIGN,$(DRIVER0_TARGET))
 	$(call INSTALL_EXEC_SIGN,$(DRIVER1_TARGET))
 	$(call INSTALL_EXEC_SIGN,$(DRIVER2_TARGET))
 	$(call INSTALL_EXEC,$(USERSPACE0_TARGET))
 	$(call INSTALL_EXEC,$(USERSPACE1_TARGET))
-	$(INSTALL) '$(DRIVER0_NAME).bat' '$(DESTDIR)/'
-	$(INSTALL) '$(DRIVER1_NAME).bat' '$(DESTDIR)/'
-	$(INSTALL) '$(DRIVER2_NAME).bat' '$(DESTDIR)/'
+	$(INSTALL) 'examples/$(DRIVER0_NAME).bat' '$(DESTDIR)/'
+	$(INSTALL) 'examples/$(DRIVER1_NAME).bat' '$(DESTDIR)/'
+	$(INSTALL) 'examples/$(DRIVER2_NAME).bat' '$(DESTDIR)/'
 
 clean:
 	rm -f $(DRIVER0_OBJECTS) $(DRIVER1_OBJECTS) $(DRIVER2_OBJECTS)
diff --git a/common.hpp b/common.hpp
index 0cbbe6b..2632fc0 100644
--- a/common.hpp
+++ b/common.hpp
@@ -1,4 +1,4 @@
-#include "protobuf-c/example.pb-c.h"
+#include "examples/example.pb-c.h"
 
 #include <EASTL/algorithm.h>
 #include <EASTL/array.h>
diff --git a/driver-protobuf-c-tcp.bat b/driver-protobuf-c-tcp.bat
deleted file mode 100644
index 9aa935b..0000000
--- a/driver-protobuf-c-tcp.bat
+++ /dev/null
@@ -1,27 +0,0 @@
-@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/driver-protobuf-c-tcp.cpp b/driver-protobuf-c-tcp.cpp
deleted file mode 100644
index 0808b88..0000000
--- a/driver-protobuf-c-tcp.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-#include "berkeley.h"
-#include "ksocket.h"
-#include "protobuf-c/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/driver-protobuf-c.bat b/driver-protobuf-c.bat
deleted file mode 100644
index 671bf19..0000000
--- a/driver-protobuf-c.bat
+++ /dev/null
@@ -1,27 +0,0 @@
-@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/driver-protobuf-c.cpp b/driver-protobuf-c.cpp
deleted file mode 100644
index 762137c..0000000
--- a/driver-protobuf-c.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-#include "berkeley.h"
-#include "ksocket.h"
-#include "protobuf-c/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/driver.bat b/driver.bat
deleted file mode 100644
index 519d9e8..0000000
--- a/driver.bat
+++ /dev/null
@@ -1,27 +0,0 @@
-@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/driver.cpp b/driver.cpp
deleted file mode 100644
index ceae8ff..0000000
--- a/driver.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-
-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/echo_srv.py b/echo_srv.py
deleted file mode 100644
index b3855eb..0000000
--- a/echo_srv.py
+++ /dev/null
@@ -1,16 +0,0 @@
-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/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;
+}
diff --git a/protobuf-c/example.pb-c.c b/protobuf-c/example.pb-c.c
deleted file mode 100644
index abce500..0000000
--- a/protobuf-c/example.pb-c.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
-/* Generated from: protobuf-c/example.proto */
-
-/* Do not generate deprecated warnings for self */
-#ifndef PROTOBUF_C__NO_DEPRECATED
-#define PROTOBUF_C__NO_DEPRECATED
-#endif
-
-#include "protobuf-c/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/protobuf-c/example.pb-c.h b/protobuf-c/example.pb-c.h
deleted file mode 100644
index b1fc5a0..0000000
--- a/protobuf-c/example.pb-c.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
-/* Generated from: protobuf-c/example.proto */
-
-#ifndef PROTOBUF_C_protobuf_2dc_2fexample_2eproto__INCLUDED
-#define PROTOBUF_C_protobuf_2dc_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_protobuf_2dc_2fexample_2eproto__INCLUDED */
diff --git a/protobuf-c/example.proto b/protobuf-c/example.proto
deleted file mode 100644
index e77f36c..0000000
--- a/protobuf-c/example.proto
+++ /dev/null
@@ -1,31 +0,0 @@
-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/userspace_client.cpp b/userspace_client.cpp
deleted file mode 100644
index cb2a3b4..0000000
--- a/userspace_client.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-#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/userspace_client_protobuf.cpp b/userspace_client_protobuf.cpp
deleted file mode 100644
index 7ee674e..0000000
--- a/userspace_client_protobuf.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h> // Needed for _wtoi
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#include "common.hpp"
-#include "protobuf-c/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;
-}
-- 
cgit v1.2.3