Fix debug logging in w32nsp to not to use libintl
[oweals/gnunet.git] / src / gns / w32nsp.c
index b3604271e1cf374025e59fab24ca81d1af7537de..5ad9fc7538957bb99a70f2161549f91df3dc54e7 100644 (file)
@@ -1,23 +1,47 @@
-/* This code is partially based upon samples from the book\r
- * "Network Programming For Microsoft Windows, 2Nd Edition".\r
- */\r
-\r
-#define INITGUID\r
-#include <windows.h>\r
-#include <nspapi.h>\r
-#include <stdint.h>\r
-#include <ws2tcpip.h>\r
-#include <ws2spi.h>\r
-\r
-#if 1\r
-#  define DEBUGLOG(s, ...)\r
-#endif\r
-#if 0\r
-#  define DEBUGLOG(s, ...) printf (s, ##__VA_ARGS__)\r
-#endif\r
-\r
-#define WINDOWS 1\r
-#define MINGW 1\r
+/*
+     This file is part of GNUnet.
+     (C) 2012 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file gns/w32nsp.c
+ * @brief W32 integration for GNS
+ * @author LRN
+ */
+/* This code is partially based upon samples from the book
+ * "Network Programming For Microsoft Windows, 2Nd Edition".
+ */
+
+#if 1
+#  define DEBUGLOG(s, ...)
+#endif
+#if 0
+#  define __printf__ printf
+#  define DEBUGLOG(s, ...) printf (s, ##__VA_ARGS__)
+#endif
+
+#include <stdint.h>
+#include <ws2tcpip.h>
+#include <ws2spi.h>
+#include <windows.h>
+#include <nspapi.h>
+
+#define WINDOWS 1
+#define MINGW 1
 #ifndef __BYTE_ORDER
 #ifdef _BYTE_ORDER
 #define __BYTE_ORDER _BYTE_ORDER
 #endif
 #endif
 #endif
-#include <gnunet_w32nsp_lib.h>\r
-#include <w32resolver.h>\r
-\r
-#define NSPAPI_VERSION_MAJOR 4\r
-#define NSPAPI_VERSION_MINOR 4\r
-\r
-#define REPLY_LIFETIME 60*5\r
-\r
-#define STATE_BEGIN  0x01\r
-#define STATE_END    0x02\r
-#define STATE_REPLY  0x04\r
-#define STATE_GHBN   0x08\r
-\r
-uint64_t
-GNUNET_htonll (uint64_t n)
+#include "w32resolver.h"
+#define INITGUID
+#include "gnunet_w32nsp_lib.h"
+#undef INITGUID
+
+#define NSPAPI_VERSION_MAJOR 4
+#define NSPAPI_VERSION_MINOR 4
+
+#define REPLY_LIFETIME 60*5
+
+#define STATE_BEGIN  0x01
+#define STATE_END    0x02
+#define STATE_REPLY  0x04
+#define STATE_GHBN   0x08
+
+static CRITICAL_SECTION records_cs;
+
+struct record
 {
-#if __BYTE_ORDER == __BIG_ENDIAN
-  return n;
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
-  return (((uint64_t) htonl (n)) << 32) + htonl (n >> 32);
-#else
-  #error byteorder undefined
-#endif
+  SOCKET s;
+  DWORD flags;
+  uint8_t state;
+  char *buf;
+  wchar_t *name;
+};
+
+static struct record *records = NULL;
+static size_t records_len = 0;
+static size_t records_size = 0;
+
+static int
+resize_records ()
+{
+  size_t new_size = records_len > 0 ? records_len * 2 : 5;
+  struct record *new_records = malloc (new_size * sizeof (struct record));
+  if (new_records == NULL)
+  {
+    SetLastError (WSA_NOT_ENOUGH_MEMORY);
+    return 0;
+  }
+  memcpy (new_records, records, records_len * sizeof (struct record));
+  memset (&new_records[records_len], 0, sizeof (struct record) * (new_size - records_len));
+  records_size = new_size;
+  free (records);
+  records = new_records;
+  return 1;
+}
+
+static int
+add_record (SOCKET s, const wchar_t *name, DWORD flags)
+{
+  int res = 1;
+  int i;
+  int empty = -1;
+  //EnterCriticalSection (&records_cs);
+  for (i = 0; i < records_len; i++)
+    if (records[i].state == 0)
+      break;
+  empty = i;
+  if (i == records_len)
+  {
+    res = resize_records ();
+    if (res)
+      empty = records_len++;
+  }
+  if (res)
+  {
+    struct record r;
+    r.s = s;
+    r.flags = flags;
+    r.name = (wchar_t *) name;
+    r.state = 1;
+    r.buf = NULL;
+    if (name)
+      r.name = wcsdup (name);
+    records[empty] = r;
+  }
+  //LeaveCriticalSection (&records_cs);
+  return res;
+}
+
+static void
+free_record (int i)
+{
+  if (records[i].name)
+    free (records[i].name);
+  records[i].state = 0;
 }
-\r
-CRITICAL_SECTION records_cs;\r
-\r
-struct record\r
-{\r
-  SOCKET s;\r
-  DWORD flags;\r
-  uint8_t state;\r
-  char *buf;\r
-  wchar_t *name;\r
-};\r
-\r
-static struct record *records = NULL;\r
-static size_t records_len = 0;\r
-static size_t records_size = 0;\r
-\r
-int\r
-resize_records ()\r
-{\r
-  size_t new_size = records_len > 0 ? records_len * 2 : 5;\r
-  struct record *new_records = malloc (new_size * sizeof (struct record));\r
-  if (new_records == NULL)\r
-  {\r
-    SetLastError (WSA_NOT_ENOUGH_MEMORY);\r
-    return 0;\r
-  }\r
-  memcpy (new_records, records, records_len * sizeof (struct record));\r
-  memset (&new_records[records_len], 0, sizeof (struct record) * (new_size - records_len));\r
-  records_size = new_size;\r
-  free (records);\r
-  records = new_records;\r
-  return 1;\r
-}\r
-\r
-int\r
-add_record (SOCKET s, const wchar_t *name, DWORD flags)\r
-{\r
-  int res = 1;\r
-  int i;\r
-  int empty = -1;\r
-  //EnterCriticalSection (&records_cs);\r
-  for (i = 0; i < records_len; i++)\r
-    if (records[i].state == 0)\r
-      break;\r
-  empty = i;\r
-  if (i == records_len)\r
-  {\r
-    res = resize_records ();\r
-    if (res)\r
-      empty = records_len++;\r
-  }\r
-  if (res)\r
-  {\r
-    struct record r;\r
-    r.s = s;\r
-    r.flags = flags;\r
-    r.name = (wchar_t *) name;\r
-    r.state = 1;\r
-    r.buf = NULL;\r
-    if (name)\r
-      r.name = wcsdup (name);\r
-    records[empty] = r;\r
-  }\r
-  //LeaveCriticalSection (&records_cs);\r
-  return res;\r
-}\r
-\r
-void\r
-free_record (int i)\r
-{\r
-  if (records[i].name)\r
-    free (records[i].name);\r
-  records[i].state = 0;\r
-}\r
-\r
-/* These are not defined by mingw.org headers at the moment*/\r
-typedef INT (WSPAPI *LPNSPIOCTL) (HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPWSACOMPLETION,LPWSATHREADID);\r
-typedef struct _NSP_ROUTINE_XP {\r
+
+/* These are not defined by mingw.org headers at the moment*/
+typedef INT (WSPAPI *LPNSPIOCTL) (HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPWSACOMPLETION,LPWSATHREADID);
+typedef struct _NSP_ROUTINE_XP {
   DWORD cbSize;
   DWORD dwMajorVersion;
   DWORD dwMinorVersion;
@@ -159,57 +173,57 @@ typedef struct _NSP_ROUTINE_XP {
   LPNSPREMOVESERVICECLASS NSPRemoveServiceClass;
   LPNSPGETSERVICECLASSINFO NSPGetServiceClassInfo;
   LPNSPIOCTL NSPIoctl;
-} NSP_ROUTINE_XP, *PNSP_ROUTINE_XP, *LPNSP_ROUTINE_XP;
-\r
-static SOCKET\r
-connect_to_dns_resolver ()\r
-{\r
-  struct sockaddr_in addr;\r
-  SOCKET r;\r
-  int ret;\r
-\r
-  r = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);\r
-  if (INVALID_SOCKET == r)\r
-  {\r
-    SetLastError (16004);\r
-    return r;\r
-  }\r
-\r
-  addr.sin_family = AF_INET;\r
-  addr.sin_port = htons (5353); /* TCP 5353 is not registered; UDP 5353 is */\r
-  addr.sin_addr.s_addr = inet_addr ("127.0.0.1");\r
-\r
-  ret = connect (r, (struct sockaddr *) &addr, sizeof (addr));\r
-  if (SOCKET_ERROR == ret)\r
-  {\r
-    DWORD err = GetLastError ();\r
-    closesocket (r);\r
-    SetLastError (err);\r
-    SetLastError (16005);\r
-    r = INVALID_SOCKET;\r
-  }\r
-  return r;\r
-}\r
-\r
-static int\r
-send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,\r
-    LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,\r
-    SOCKET *resolver)\r
-{\r
+} NSP_ROUTINE_XP;
+
+static SOCKET
+connect_to_dns_resolver ()
+{
+  struct sockaddr_in addr;
+  SOCKET r;
+  int ret;
+
+  r = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (INVALID_SOCKET == r)
+  {
+    SetLastError (16004);
+    return r;
+  }
+
+  addr.sin_family = AF_INET;
+  addr.sin_port = htons (5353); /* TCP 5353 is not registered; UDP 5353 is */
+  addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
+
+  ret = connect (r, (struct sockaddr *) &addr, sizeof (addr));
+  if (SOCKET_ERROR == ret)
+  {
+    DWORD err = GetLastError ();
+    closesocket (r);
+    SetLastError (err);
+    SetLastError (16005);
+    r = INVALID_SOCKET;
+  }
+  return r;
+}
+
+static int
+send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,
+    LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
+    SOCKET *resolver)
+{
   struct GNUNET_W32RESOLVER_GetMessage *msg;
   int af4 = 0;
   int af6 = 0;
-  char *buf;\r
-  int ret = 1;\r
-  int i;\r
-  uint32_t id;\r
-  size_t size = sizeof (struct GNUNET_W32RESOLVER_GetMessage);\r
-  size_t namelen = 0;\r
-  if (lpqsRestrictions->lpszServiceInstanceName)\r
-    namelen = sizeof (wchar_t) * (wcslen (lpqsRestrictions->lpszServiceInstanceName) + 1);\r
-  size += namelen;\r
-  buf = malloc (size);\r
-  msg = (struct GNUNET_W32RESOLVER_GetMessage *) buf;\r
+  char *buf;
+  int ret = 1;
+  int i;
+  uint32_t id;
+  size_t size = sizeof (struct GNUNET_W32RESOLVER_GetMessage);
+  size_t namelen = 0;
+  if (lpqsRestrictions->lpszServiceInstanceName)
+    namelen = sizeof (wchar_t) * (wcslen (lpqsRestrictions->lpszServiceInstanceName) + 1);
+  size += namelen;
+  buf = malloc (size);
+  msg = (struct GNUNET_W32RESOLVER_GetMessage *) buf;
   msg->header.size = htons (size);
   msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST);
   if (lpqsRestrictions->dwNumberOfProtocols > 0)
@@ -234,448 +248,467 @@ send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,
   msg->sc_data1 = htonl (lpqsRestrictions->lpServiceClassId->Data1);
   msg->sc_data2 = htons (lpqsRestrictions->lpServiceClassId->Data2);
   msg->sc_data3 = htons (lpqsRestrictions->lpServiceClassId->Data3);
-  msg->sc_data4 = 0;
   for (i = 0; i < 8; i++)
-    msg->sc_data4 |= ((uint64_t) lpqsRestrictions->lpServiceClassId->Data4[i]) << ((7 - i) * 8);
-  msg->sc_data4 = GNUNET_htonll (msg->sc_data4);
+    msg->sc_data4[i] = lpqsRestrictions->lpServiceClassId->Data4[i];
   *resolver = connect_to_dns_resolver ();
   if (*resolver != INVALID_SOCKET)
   {
-    if (size != send (*resolver, buf, size, 0))\r
-    {\r
-      DWORD err = GetLastError ();\r
-      closesocket (*resolver);\r
-      *resolver = INVALID_SOCKET;\r
-      DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to send request: %lu\n", err);\r
-      SetLastError (WSATRY_AGAIN);\r
-      ret = 0;\r
-    }\r
-  }\r
-  else\r
-    ret = 0;\r
-  free (buf);\r
-  return ret;\r
-}\r
-\r
-int WSPAPI\r
-NSPCleanup (LPGUID lpProviderId)\r
-{\r
-  DEBUGLOG ("NSPCleanup\n");\r
-  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))\r
-  {\r
-    return NO_ERROR;\r
-  }\r
-  SetLastError (WSAEINVALIDPROVIDER);\r
-  return SOCKET_ERROR;\r
-}\r
-\r
-BOOL WINAPI\r
-DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r
-{\r
-  switch (fdwReason)\r
-  {\r
-    case DLL_PROCESS_ATTACH:\r
-      if (!InitializeCriticalSectionAndSpinCount (&records_cs, 0x00000400))\r
-      {\r
-        return FALSE;\r
-      }\r
-      break;\r
-    case DLL_THREAD_ATTACH:\r
-      break;\r
-    case DLL_THREAD_DETACH:\r
-      break;\r
-    case DLL_PROCESS_DETACH:\r
-      DeleteCriticalSection (&records_cs);\r
-      break;\r
-  }\r
-  return TRUE;\r
-}\r
-\r
-\r
-\r
-\r
-int WSPAPI\r
-GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions,\r
-    LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,\r
-    LPHANDLE lphLookup)\r
-{\r
-  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin\n");\r
-  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))\r
-  {\r
-    SOCKET s;\r
-    if (lpqsRestrictions->dwNameSpace != NS_DNS && lpqsRestrictions->dwNameSpace != NS_ALL)\r
-    {\r
-      DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong namespace\n");\r
-      SetLastError (WSANO_DATA);\r
-      return SOCKET_ERROR;\r
-    }\r
-    if (lpqsRestrictions->lpszServiceInstanceName != NULL)\r
-    {\r
-      wchar_t *s = lpqsRestrictions->lpszServiceInstanceName;\r
-      size_t len = wcslen (s);\r
-      if (len >= 4 && wcscmp (&s[len - 4], L"zkey") == 0)\r
-      {\r
-      }\r
-      else if (len >= 6 && wcscmp (&s[len - 6], L"gnunet") == 0)\r
-      {\r
-      }\r
-      else\r
-      {\r
-        DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n");\r
-        SetLastError (WSANO_DATA);\r
-        return SOCKET_ERROR;\r
-      }\r
-    }\r
-\r
-    if (send_name_to_ip_request (lpqsRestrictions,\r
-        lpServiceClassInfo, dwControlFlags, &s))\r
-    {\r
-      if (!(add_record (s, lpqsRestrictions->lpszServiceInstanceName, dwControlFlags)))\r
-      {\r
-        DWORD err = GetLastError ();\r
-        DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to add a record\n");\r
-        closesocket (s);\r
-        SetLastError (err);\r
-        return SOCKET_ERROR;\r
-      }\r
-      *lphLookup = (HANDLE) s;\r
-      DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: OK (%lu)\n", GetLastError ());\r
-      return NO_ERROR;\r
-    }\r
-    return SOCKET_ERROR;\r
-  }\r
-  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong provider\n");\r
-  SetLastError (WSAEINVALIDPROVIDER);\r
-  return SOCKET_ERROR;\r
-}\r
-\r
-#define UnmarshallPtr(ptr, ptrtype, base) \\r
-  if (ptr) \\r
-    ptr = (ptrtype *) (base + (uintptr_t) ptr)\r
-\r
-void\r
-UnmarshallWSAQUERYSETW (LPWSAQUERYSETW req)\r
-{\r
-  int i;\r
-  char *base = (char *) req;\r
-  UnmarshallPtr (req->lpszServiceInstanceName, wchar_t, base);\r
-  UnmarshallPtr (req->lpServiceClassId, GUID, base);\r
-  UnmarshallPtr (req->lpVersion, WSAVERSION, base);\r
-  UnmarshallPtr (req->lpszComment, wchar_t, base);\r
-  UnmarshallPtr (req->lpNSProviderId, GUID, base);\r
-  UnmarshallPtr (req->lpszContext, wchar_t, base);\r
-  UnmarshallPtr (req->lpafpProtocols, AFPROTOCOLS, base);\r
-  UnmarshallPtr (req->lpszQueryString, wchar_t, base);\r
-  UnmarshallPtr (req->lpcsaBuffer, CSADDR_INFO, base);\r
-  for (i = 0; i < req->dwNumberOfCsAddrs; i++)\r
-  {\r
-    UnmarshallPtr (req->lpcsaBuffer[i].LocalAddr.lpSockaddr, SOCKADDR, base);\r
-    UnmarshallPtr (req->lpcsaBuffer[i].RemoteAddr.lpSockaddr, SOCKADDR, base);\r
-  }\r
-  UnmarshallPtr (req->lpBlob, BLOB, base);\r
-  if (req->lpBlob)\r
-    UnmarshallPtr (req->lpBlob->pBlobData, BYTE, base);\r
-}\r
-\r
-int WSAAPI\r
-GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,\r
-    LPDWORD lpdwBufferLength, LPWSAQUERYSET lpqsResults)\r
-{\r
-  DWORD effective_flags;\r
-  int i;\r
+    if (size != send (*resolver, buf, size, 0))
+    {
+      DWORD err = GetLastError ();
+      closesocket (*resolver);
+      *resolver = INVALID_SOCKET;
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to send request: %lu\n", err);
+      SetLastError (WSATRY_AGAIN);
+      ret = 0;
+    }
+  }
+  else
+    ret = 0;
+  free (buf);
+  return ret;
+}
+
+static int WSPAPI
+NSPCleanup (LPGUID lpProviderId)
+{
+  DEBUGLOG ("NSPCleanup\n");
+  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
+  {
+    return NO_ERROR;
+  }
+  SetLastError (WSAEINVALIDPROVIDER);
+  return SOCKET_ERROR;
+}
+
+BOOL WINAPI
+DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+  switch (fdwReason)
+  {
+    case DLL_PROCESS_ATTACH:
+      if (!InitializeCriticalSectionAndSpinCount (&records_cs, 0x00000400))
+      {
+        return FALSE;
+      }
+      break;
+    case DLL_THREAD_ATTACH:
+      break;
+    case DLL_THREAD_DETACH:
+      break;
+    case DLL_PROCESS_DETACH:
+      DeleteCriticalSection (&records_cs);
+      break;
+  }
+  return TRUE;
+}
+
+
+
+
+static int WSPAPI
+GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions,
+    LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
+    LPHANDLE lphLookup)
+{
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin\n");
+  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
+  {
+    SOCKET s;
+    if (lpqsRestrictions->dwNameSpace != NS_DNS && lpqsRestrictions->dwNameSpace != NS_ALL)
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong namespace\n");
+      SetLastError (WSANO_DATA);
+      return SOCKET_ERROR;
+    }
+    if (lpqsRestrictions->lpszServiceInstanceName != NULL)
+    {
+      wchar_t *s = lpqsRestrictions->lpszServiceInstanceName;
+      size_t len = wcslen (s);
+      if (len >= 5 && wcscmp (&s[len - 5], L".zkey") == 0)
+      {
+      }
+      else if (len >= 4 && wcscmp (&s[len - 4], L".gnu") == 0)
+      {
+      }
+      else
+      {
+        DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n");
+        SetLastError (WSANO_DATA);
+        return SOCKET_ERROR;
+      }
+    }
+
+    if (send_name_to_ip_request (lpqsRestrictions,
+        lpServiceClassInfo, dwControlFlags, &s))
+    {
+      if (!(add_record (s, lpqsRestrictions->lpszServiceInstanceName, dwControlFlags)))
+      {
+        DWORD err = GetLastError ();
+        DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to add a record\n");
+        closesocket (s);
+        SetLastError (err);
+        return SOCKET_ERROR;
+      }
+      *lphLookup = (HANDLE) s;
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: OK (%lu)\n", GetLastError ());
+      return NO_ERROR;
+    }
+    return SOCKET_ERROR;
+  }
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong provider\n");
+  SetLastError (WSAEINVALIDPROVIDER);
+  return SOCKET_ERROR;
+}
+
+#define UnmarshallPtr(ptr, ptrtype, base) \
+  if (ptr) \
+    ptr = (ptrtype *) (base + (uintptr_t) ptr)
+
+static void
+UnmarshallWSAQUERYSETW (LPWSAQUERYSETW req)
+{
+  int i;
+  char *base = (char *) req;
+  UnmarshallPtr (req->lpszServiceInstanceName, wchar_t, base);
+  UnmarshallPtr (req->lpServiceClassId, GUID, base);
+  UnmarshallPtr (req->lpVersion, WSAVERSION, base);
+  UnmarshallPtr (req->lpszComment, wchar_t, base);
+  UnmarshallPtr (req->lpNSProviderId, GUID, base);
+  UnmarshallPtr (req->lpszContext, wchar_t, base);
+  UnmarshallPtr (req->lpafpProtocols, AFPROTOCOLS, base);
+  UnmarshallPtr (req->lpszQueryString, wchar_t, base);
+  UnmarshallPtr (req->lpcsaBuffer, CSADDR_INFO, base);
+  for (i = 0; i < req->dwNumberOfCsAddrs; i++)
+  {
+    UnmarshallPtr (req->lpcsaBuffer[i].LocalAddr.lpSockaddr, SOCKADDR, base);
+    UnmarshallPtr (req->lpcsaBuffer[i].RemoteAddr.lpSockaddr, SOCKADDR, base);
+  }
+  UnmarshallPtr (req->lpBlob, BLOB, base);
+  if (req->lpBlob)
+    UnmarshallPtr (req->lpBlob->pBlobData, BYTE, base);
+}
+
+static int WSAAPI
+GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
+    LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
+{
+  DWORD effective_flags;
+  int i;
   struct GNUNET_MessageHeader header = {0, 0};
-  int rec = -1;\r
-  int rc;\r
-  int to_receive;\r
-  int t;\r
-  char *buf;\r
-\r
-  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext\n");\r
-  //EnterCriticalSection (&records_cs);\r
-  for (i = 0; i < records_len; i++)\r
-  {\r
-    if (records[i].s == (SOCKET) hLookup)\r
-    {\r
-      rec = i;\r
-      break;\r
-    }\r
-  }\r
-  if (rec == -1)\r
-  {\r
-    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: invalid handle\n");\r
-    SetLastError (WSA_INVALID_HANDLE);\r
-    //LeaveCriticalSection (&records_cs);\r
-    return SOCKET_ERROR;\r
-  }\r
-  if (records[rec].state & 4)\r
-  {\r
-    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: session is closed\n");\r
-    SetLastError (WSA_E_NO_MORE);\r
-    //LeaveCriticalSection (&records_cs);\r
-    return SOCKET_ERROR;\r
-  }\r
-  effective_flags = dwControlFlags & records[rec].flags;\r
-  if (records[rec].buf)\r
-  {\r
-    header = *((struct GNUNET_MessageHeader *) records[rec].buf);\r
-    if (dwControlFlags & LUP_FLUSHCACHE)\r
-    {\r
-      free (records[rec].buf);\r
-      records[rec].buf = NULL;\r
-    }\r
-    else\r
-    {\r
-      if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))\r
-      {\r
-        DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");\r
-        SetLastError (WSAEFAULT);\r
-        //LeaveCriticalSection (&records_cs);\r
-        return SOCKET_ERROR;\r
-      }\r
-      memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)records[rec].buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));\r
-      free (records[rec].buf);\r
-      records[rec].buf = NULL;\r
-      //LeaveCriticalSection (&records_cs);\r
-      UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);\r
-      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n");\r
-      return NO_ERROR;\r
-    }\r
-  }\r
-  records[rec].state |= 8;\r
-  //LeaveCriticalSection (&records_cs);\r
-  to_receive = sizeof (header);\r
-  rc = 0;\r
-  while (to_receive > 0)\r
-  {\r
-    t = recv ((SOCKET) hLookup, &((char *) &header)[rc], to_receive, 0);\r
-    if (t > 0)\r
-    {\r
-      rc += t;\r
-      to_receive -= t;\r
-    }\r
-    else\r
-      break;\r
-  }\r
-  //EnterCriticalSection (&records_cs);\r
-  records[rec].state &= ~8;\r
-  if (rc != sizeof (header))\r
-  {\r
-    if (records[rec].state & 2)\r
-    {\r
-      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");\r
-      SetLastError (WSA_E_CANCELLED);\r
-    }\r
-    else\r
-    {\r
-      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data\n");\r
-      SetLastError (WSA_E_NO_MORE);\r
-    }\r
-    records[rec].state |= 4;\r
-    //LeaveCriticalSection (&records_cs);\r
-    return SOCKET_ERROR;\r
-  }\r
-  records[rec].state &= ~8;\r
-  header.type = ntohs (header.type);\r
-  header.size = ntohs (header.size);\r
-  if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE ||\r
-      (header.type == GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE &&\r
-      header.size == sizeof (header)))\r
-  {\r
-    records[rec].state |= 4;\r
-    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header is wrong or type is wrong or no data\n");\r
-    //LeaveCriticalSection (&records_cs);\r
-    SetLastError (WSA_E_NO_MORE);\r
-    return SOCKET_ERROR;\r
-  }\r
-  buf = malloc (header.size);\r
-  if (buf == NULL)\r
-  {\r
-    records[rec].state |= 4;\r
-    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: malloc() failed\n");\r
-    //LeaveCriticalSection (&records_cs);\r
-    SetLastError (WSA_E_NO_MORE);\r
-    return SOCKET_ERROR;\r
-  }\r
-  records[rec].state |= 8;\r
-  //LeaveCriticalSection (&records_cs);\r
-  memcpy (buf, &header, sizeof (header));\r
-  to_receive = header.size - sizeof (header);\r
-  rc = 0;\r
-  while (to_receive > 0)\r
-  {\r
-    t = recv ((SOCKET) hLookup, &((char *) &((struct GNUNET_MessageHeader *) buf)[1])[rc], to_receive, 0);\r
-    if (t > 0)\r
-    {\r
-      rc += t;\r
-      to_receive -= t;\r
-    }\r
-    else\r
-      break;\r
-  }\r
-  //EnterCriticalSection (&records_cs);\r
-  records[rec].state &= ~8;\r
-  if (rc != header.size - sizeof (header))\r
-  {\r
-    free (buf);\r
-    if (records[rec].state & 2)\r
-    {\r
-      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");\r
-      SetLastError (WSA_E_CANCELLED);\r
-    }\r
-    else\r
-    {\r
-      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data\n");\r
-      SetLastError (WSA_E_NO_MORE);\r
-    }\r
-    records[rec].state |= 4;\r
-    //LeaveCriticalSection (&records_cs);\r
-    return SOCKET_ERROR;\r
-  }\r
-  if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))\r
-  {\r
-    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");\r
-    SetLastError (WSAEFAULT);\r
-    records[rec].buf = buf;\r
-    //LeaveCriticalSection (&records_cs);\r
-    return SOCKET_ERROR;\r
-  }\r
-  //LeaveCriticalSection (&records_cs);\r
-  memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));\r
-  free (buf);\r
-  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK\n");\r
-  UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);\r
-  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: returning (%lu)\n", GetLastError ());\r
-  return NO_ERROR;\r
-}\r
-\r
-int WSPAPI\r
-GNUNET_W32NSP_LookupServiceEnd (HANDLE hLookup)\r
-{\r
-  DWORD effective_flags;\r
-  int i;\r
+  int rec = -1;
+  int rc;
+  int to_receive;
+  int t;
+  char *buf;
+
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext\n");
+  //EnterCriticalSection (&records_cs);
+  for (i = 0; i < records_len; i++)
+  {
+    if (records[i].s == (SOCKET) hLookup)
+    {
+      rec = i;
+      break;
+    }
+  }
+  if (rec == -1)
+  {
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: invalid handle\n");
+    SetLastError (WSA_INVALID_HANDLE);
+    //LeaveCriticalSection (&records_cs);
+    return SOCKET_ERROR;
+  }
+  if (records[rec].state & 4)
+  {
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: session is closed\n");
+    SetLastError (WSA_E_NO_MORE);
+    //LeaveCriticalSection (&records_cs);
+    return SOCKET_ERROR;
+  }
+  effective_flags = dwControlFlags & records[rec].flags;
+  if (records[rec].buf)
+  {
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: checking buffer\n");
+    header = *((struct GNUNET_MessageHeader *) records[rec].buf);
+    if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
+      SetLastError (WSAEFAULT);
+      //LeaveCriticalSection (&records_cs);
+      return SOCKET_ERROR;
+    }
+    memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)records[rec].buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
+    free (records[rec].buf);
+    records[rec].buf = NULL;
+    //LeaveCriticalSection (&records_cs);
+    UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n");
+    return NO_ERROR;
+  }
+  records[rec].state |= 8;
+  //LeaveCriticalSection (&records_cs);
+  to_receive = sizeof (header);
+  rc = 0;
+  {
+    unsigned long have;
+    int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a header from %p, %lu bytes available\n", to_receive, hLookup, have);
+  }
+  while (to_receive > 0)
+  {
+    t = recv ((SOCKET) hLookup, &((char *) &header)[rc], to_receive, 0);
+    if (t > 0)
+    {
+      rc += t;
+      to_receive -= t;
+    }
+    else
+      break;
+  }
+  {
+    unsigned long have;
+    int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a header from %p, %lu bytes available\n", rc, hLookup, have);
+  }
+  //EnterCriticalSection (&records_cs);
+  records[rec].state &= ~8;
+  if (rc != sizeof (header))
+  {
+    if (records[rec].state & 2)
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
+      SetLastError (WSA_E_CANCELLED);
+    }
+    else
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data for a header (rc %d != %u, state is 0x%0X)\n", rc, sizeof (header), records[rec].state);
+      SetLastError (WSA_E_NO_MORE);
+    }
+    records[rec].state |= 4;
+    //LeaveCriticalSection (&records_cs);
+    return SOCKET_ERROR;
+  }
+  records[rec].state &= ~8;
+  header.type = ntohs (header.type);
+  header.size = ntohs (header.size);
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header type %d, header size %u\n", header.type, header.size);
+  if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE ||
+      (header.type == GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE &&
+      header.size == sizeof (header)))
+  {
+    records[rec].state |= 4;
+    if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE)
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header type is wrong\n");
+    else
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: empty header - no data\n");
+    //LeaveCriticalSection (&records_cs);
+    SetLastError (WSA_E_NO_MORE);
+    return SOCKET_ERROR;
+  }
+  buf = malloc (header.size);
+  if (buf == NULL)
+  {
+    records[rec].state |= 4;
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: malloc() failed\n");
+    //LeaveCriticalSection (&records_cs);
+    SetLastError (WSA_E_NO_MORE);
+    return SOCKET_ERROR;
+  }
+  records[rec].state |= 8;
+  //LeaveCriticalSection (&records_cs);
+  memcpy (buf, &header, sizeof (header));
+  to_receive = header.size - sizeof (header);
+  rc = 0;
+  {
+    unsigned long have;
+    int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a body from %p, %lu bytes available\n", to_receive, hLookup, have);
+  }
+  while (to_receive > 0)
+  {
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: recv (%d)\n", to_receive);
+    t = recv ((SOCKET) hLookup, &((char *) &((struct GNUNET_MessageHeader *) buf)[1])[rc], to_receive, 0);
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: recv returned %d\n", t);
+    if (t > 0)
+    {
+      rc += t;
+      to_receive -= t;
+    }
+    else
+      break;
+  }
+  {
+    unsigned long have;
+    int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a body from %p, %lu bytes available\n", rc, hLookup, have);
+  }
+  //EnterCriticalSection (&records_cs);
+  records[rec].state &= ~8;
+  if (rc != header.size - sizeof (header))
+  {
+    free (buf);
+    if (records[rec].state & 2)
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
+      SetLastError (WSA_E_CANCELLED);
+    }
+    else
+    {
+      DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data for the rest (rc %d != %d, state is 0x%0X)\n", rc, header.size - sizeof (header), records[rec].state);
+      SetLastError (WSA_E_NO_MORE);
+    }
+    records[rec].state |= 4;
+    //LeaveCriticalSection (&records_cs);
+    return SOCKET_ERROR;
+  }
+  if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
+  {
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
+    SetLastError (WSAEFAULT);
+    records[rec].buf = buf;
+    //LeaveCriticalSection (&records_cs);
+    return SOCKET_ERROR;
+  }
+  //LeaveCriticalSection (&records_cs);
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: writing %d bytes into result buffer\n", header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
+  memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
+  free (buf);
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK\n");
+  UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: returning (%lu)\n", GetLastError ());
+  return NO_ERROR;
+}
+
+static int WSPAPI
+GNUNET_W32NSP_LookupServiceEnd (HANDLE hLookup)
+{
+  DWORD effective_flags;
+  int i;
   struct GNUNET_MessageHeader header = {0, 0};
-  int rec = -1;\r
-  int rc;\r
-  char *buf;\r
-\r
-  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd\n");\r
-  //EnterCriticalSection (&records_cs);\r
-  for (i = 0; i < records_len; i++)\r
-  {\r
-    if (records[i].s == (SOCKET) hLookup)\r
-    {\r
-      rec = i;\r
-      break;\r
-    }\r
-  }\r
-  if (rec == -1)\r
-  {\r
-    SetLastError (WSA_INVALID_HANDLE);\r
-    //LeaveCriticalSection (&records_cs);\r
-    DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: invalid handle\n");\r
-    return SOCKET_ERROR;\r
-  }\r
-  records[rec].state |= 2;\r
-  closesocket (records[rec].s);\r
-  while (records[rec].state & 8)\r
-  {\r
-    //LeaveCriticalSection (&records_cs);\r
-    Sleep (10);\r
-    //EnterCriticalSection (&records_cs);\r
-  }\r
-  if (records[rec].buf)\r
-    free (records[rec].buf);\r
-  records[rec].buf = NULL;\r
-  records[rec].state = 0;\r
-  if (records[rec].name)\r
-    free (records[rec].name);\r
-  //LeaveCriticalSection (&records_cs);\r
-  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: OK\n");\r
-  return NO_ERROR;\r
-}\r
-\r
-int WSAAPI\r
-GNUNET_W32NSP_SetService (LPGUID lpProviderId,\r
-    LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo,\r
-    WSAESETSERVICEOP essOperation, DWORD dwControlFlags)\r
-{\r
-  DEBUGLOG ("GNUNET_W32NSP_SetService\n");\r
-  SetLastError (WSAEOPNOTSUPP);\r
-  return SOCKET_ERROR;\r
-}\r
-\r
-int WSAAPI\r
-GNUNET_W32NSP_InstallServiceClass (LPGUID lpProviderId,\r
-    LPWSASERVICECLASSINFOW lpServiceClassInfo)\r
-{\r
-  DEBUGLOG ("GNUNET_W32NSP_InstallServiceClass\n");\r
-  SetLastError (WSAEOPNOTSUPP);\r
-  return SOCKET_ERROR;\r
-}\r
-\r
-\r
-int WSAAPI\r
-GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)\r
-{\r
-  DEBUGLOG ("GNUNET_W32NSP_RemoveServiceClass\n");\r
-  SetLastError (WSAEOPNOTSUPP);\r
-  return SOCKET_ERROR;\r
-}\r
-\r
-int WSAAPI\r
-GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize,\r
-  LPWSASERVICECLASSINFOW lpServiceClassInfo)\r
-{\r
-  DEBUGLOG ("GNUNET_W32NSP_GetServiceClassInfo\n");\r
-  SetLastError (WSAEOPNOTSUPP);\r
-  return SOCKET_ERROR;\r
-}\r
-\r
-int WSAAPI\r
-GNUNET_W32NSP_Ioctl (HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer,\r
-    DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer,\r
-    LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion,\r
-    LPWSATHREADID lpThreadId)\r
-{\r
-  DEBUGLOG ("GNUNET_W32NSP_Ioctl\n");\r
-  SetLastError (WSAEOPNOTSUPP);\r
-  return SOCKET_ERROR;\r
-}\r
-\r
-/**\r
- * This function is called by Winsock to hook up our provider.\r
- * It is the only function that [should be/is] exported by the\r
- * provider. All other routines are passed as pointers in lpnspRoutines.\r
- */\r
-int WSPAPI\r
-NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)\r
-{\r
-  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))\r
-  {\r
-    if (!connect_to_dns_resolver ())\r
-    {\r
-      return SOCKET_ERROR;\r
-    }\r
-    /* This assumes that NSP_ROUTINE struct doesn't have a NSPIoctl member.\r
-     * If it does, you need to use FIELD_OFFSET() macro to get offset of NSPIoctl\r
-     * and use that offset as cbSize.\r
-     */\r
-    lpnspRoutines->cbSize = sizeof(NSP_ROUTINE_XP);\r
-\r
-    lpnspRoutines->dwMajorVersion = NSPAPI_VERSION_MAJOR;\r
-    lpnspRoutines->dwMinorVersion = NSPAPI_VERSION_MINOR;\r
-    lpnspRoutines->NSPCleanup = NSPCleanup;\r
-    lpnspRoutines->NSPLookupServiceBegin = GNUNET_W32NSP_LookupServiceBegin;\r
-    lpnspRoutines->NSPLookupServiceNext = GNUNET_W32NSP_LookupServiceNext;\r
-    lpnspRoutines->NSPLookupServiceEnd = GNUNET_W32NSP_LookupServiceEnd;\r
-    lpnspRoutines->NSPSetService = GNUNET_W32NSP_SetService;\r
-    lpnspRoutines->NSPInstallServiceClass = GNUNET_W32NSP_InstallServiceClass;\r
-    lpnspRoutines->NSPRemoveServiceClass = GNUNET_W32NSP_RemoveServiceClass;\r
-    lpnspRoutines->NSPGetServiceClassInfo = GNUNET_W32NSP_GetServiceClassInfo;\r
-    ((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;\r
-    return NO_ERROR;\r
-  }\r
-  SetLastError (WSAEINVALIDPROVIDER);\r
-  return SOCKET_ERROR;\r
-}\r
-\r
+  int rec = -1;
+  int rc;
+  char *buf;
+
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd\n");
+  //EnterCriticalSection (&records_cs);
+  for (i = 0; i < records_len; i++)
+  {
+    if (records[i].s == (SOCKET) hLookup)
+    {
+      rec = i;
+      break;
+    }
+  }
+  if (rec == -1)
+  {
+    SetLastError (WSA_INVALID_HANDLE);
+    //LeaveCriticalSection (&records_cs);
+    DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: invalid handle\n");
+    return SOCKET_ERROR;
+  }
+  records[rec].state |= 2;
+  closesocket (records[rec].s);
+  while (records[rec].state & 8)
+  {
+    //LeaveCriticalSection (&records_cs);
+    Sleep (10);
+    //EnterCriticalSection (&records_cs);
+  }
+  if (records[rec].buf)
+    free (records[rec].buf);
+  records[rec].buf = NULL;
+  records[rec].state = 0;
+  if (records[rec].name)
+    free (records[rec].name);
+  //LeaveCriticalSection (&records_cs);
+  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: OK\n");
+  return NO_ERROR;
+}
+
+static int WSAAPI
+GNUNET_W32NSP_SetService (LPGUID lpProviderId,
+    LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo,
+    WSAESETSERVICEOP essOperation, DWORD dwControlFlags)
+{
+  DEBUGLOG ("GNUNET_W32NSP_SetService\n");
+  SetLastError (WSAEOPNOTSUPP);
+  return SOCKET_ERROR;
+}
+
+static int WSAAPI
+GNUNET_W32NSP_InstallServiceClass (LPGUID lpProviderId,
+    LPWSASERVICECLASSINFOW lpServiceClassInfo)
+{
+  DEBUGLOG ("GNUNET_W32NSP_InstallServiceClass\n");
+  SetLastError (WSAEOPNOTSUPP);
+  return SOCKET_ERROR;
+}
+
+
+static int WSAAPI
+GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)
+{
+  DEBUGLOG ("GNUNET_W32NSP_RemoveServiceClass\n");
+  SetLastError (WSAEOPNOTSUPP);
+  return SOCKET_ERROR;
+}
+
+static int WSAAPI
+GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize,
+  LPWSASERVICECLASSINFOW lpServiceClassInfo)
+{
+  DEBUGLOG ("GNUNET_W32NSP_GetServiceClassInfo\n");
+  SetLastError (WSAEOPNOTSUPP);
+  return SOCKET_ERROR;
+}
+
+static int WSAAPI
+GNUNET_W32NSP_Ioctl (HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer,
+    DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer,
+    LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion,
+    LPWSATHREADID lpThreadId)
+{
+  DEBUGLOG ("GNUNET_W32NSP_Ioctl\n");
+  SetLastError (WSAEOPNOTSUPP);
+  return SOCKET_ERROR;
+}
+
+/**
+ * This function is called by Winsock to hook up our provider.
+ * It is the only function that [should be/is] exported by the
+ * provider. All other routines are passed as pointers in lpnspRoutines.
+ */
+int WSAAPI
+GNUNET_W32NSP_NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
+{
+  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
+  {
+    if (!connect_to_dns_resolver ())
+    {
+      return SOCKET_ERROR;
+    }
+    /* This assumes that NSP_ROUTINE struct doesn't have a NSPIoctl member.
+     * If it does, you need to use FIELD_OFFSET() macro to get offset of NSPIoctl
+     * and use that offset as cbSize.
+     */
+    lpnspRoutines->cbSize = sizeof(NSP_ROUTINE);
+
+    lpnspRoutines->dwMajorVersion = NSPAPI_VERSION_MAJOR;
+    lpnspRoutines->dwMinorVersion = NSPAPI_VERSION_MINOR;
+    lpnspRoutines->NSPCleanup = NSPCleanup;
+    lpnspRoutines->NSPLookupServiceBegin = GNUNET_W32NSP_LookupServiceBegin;
+    lpnspRoutines->NSPLookupServiceNext = GNUNET_W32NSP_LookupServiceNext;
+    lpnspRoutines->NSPLookupServiceEnd = GNUNET_W32NSP_LookupServiceEnd;
+    lpnspRoutines->NSPSetService = GNUNET_W32NSP_SetService;
+    lpnspRoutines->NSPInstallServiceClass = GNUNET_W32NSP_InstallServiceClass;
+    lpnspRoutines->NSPRemoveServiceClass = GNUNET_W32NSP_RemoveServiceClass;
+    lpnspRoutines->NSPGetServiceClassInfo = GNUNET_W32NSP_GetServiceClassInfo;
+    /*((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;*/
+    lpnspRoutines->NSPIoctl = GNUNET_W32NSP_Ioctl;
+    return NO_ERROR;
+  }
+  SetLastError (WSAEINVALIDPROVIDER);
+  return SOCKET_ERROR;
+}
+