-/* 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".
+ */
+
+#define INITGUID
+#include <stdint.h>
+#include <ws2tcpip.h>
+#include <ws2spi.h>
+#include <windows.h>
+#include <nspapi.h>
+
+#if 1
+# define DEBUGLOG(s, ...)
+#endif
+#if 0
+# define DEBUGLOG(s, ...) printf (s, ##__VA_ARGS__)
+#endif
+
+#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
+#include "gnunet_w32nsp_lib.h"
+#include "w32resolver.h"
+
+#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
+
uint64_t
GNUNET_htonll (uint64_t n)
{
#error byteorder undefined
#endif
}
-\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
+
+CRITICAL_SECTION records_cs;
+
+struct record
+{
+ 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;
+
+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;
+}
+
+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;
+}
+
+void
+free_record (int i)
+{
+ if (records[i].name)
+ free (records[i].name);
+ records[i].state = 0;
+}
+
+/* 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;
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)
*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;
+}
+
+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;
+}
+
+
+
+
+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 >= 4 && wcscmp (&s[len - 4], 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)
+
+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);
+}
+
+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)
+ {
+ header = *((struct GNUNET_MessageHeader *) records[rec].buf);
+ if (dwControlFlags & LUP_FLUSHCACHE)
+ {
+ free (records[rec].buf);
+ records[rec].buf = NULL;
+ }
+ else
+ {
+ 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;
+ while (to_receive > 0)
+ {
+ t = recv ((SOCKET) hLookup, &((char *) &header)[rc], to_receive, 0);
+ if (t > 0)
+ {
+ rc += t;
+ to_receive -= t;
+ }
+ else
+ break;
+ }
+ //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\n");
+ 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);
+ if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE ||
+ (header.type == GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE &&
+ header.size == sizeof (header)))
+ {
+ records[rec].state |= 4;
+ DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header is wrong or type is wrong or 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;
+ while (to_receive > 0)
+ {
+ t = recv ((SOCKET) hLookup, &((char *) &((struct GNUNET_MessageHeader *) buf)[1])[rc], to_receive, 0);
+ if (t > 0)
+ {
+ rc += t;
+ to_receive -= t;
+ }
+ else
+ break;
+ }
+ //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\n");
+ 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);
+ 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;
+}
+
+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;
+}
+
+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;
+}
+
+int WSAAPI
+GNUNET_W32NSP_InstallServiceClass (LPGUID lpProviderId,
+ LPWSASERVICECLASSINFOW lpServiceClassInfo)
+{
+ DEBUGLOG ("GNUNET_W32NSP_InstallServiceClass\n");
+ SetLastError (WSAEOPNOTSUPP);
+ return SOCKET_ERROR;
+}
+
+
+int WSAAPI
+GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)
+{
+ DEBUGLOG ("GNUNET_W32NSP_RemoveServiceClass\n");
+ SetLastError (WSAEOPNOTSUPP);
+ return SOCKET_ERROR;
+}
+
+int WSAAPI
+GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize,
+ LPWSASERVICECLASSINFOW lpServiceClassInfo)
+{
+ DEBUGLOG ("GNUNET_W32NSP_GetServiceClassInfo\n");
+ SetLastError (WSAEOPNOTSUPP);
+ return SOCKET_ERROR;
+}
+
+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 WSPAPI
+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_XP);
+
+ 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;
+ return NO_ERROR;
+ }
+ SetLastError (WSAEINVALIDPROVIDER);
+ return SOCKET_ERROR;
+}
+