aboutsummaryrefslogtreecommitdiff
path: root/src/gns/w32nsp.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-07-06 07:39:24 +0000
committerChristian Grothoff <christian@grothoff.org>2012-07-06 07:39:24 +0000
commitec59e6a4f56f68916cf8ec8fefca3282a70d16d2 (patch)
treee9fce0d2f7b8dceb717ba434731bde4db594eb0a /src/gns/w32nsp.c
parent2dda2c0e3a7c3813fc334d983b65d9f698953143 (diff)
downloadgnunet-ec59e6a4f56f68916cf8ec8fefca3282a70d16d2.tar.gz
gnunet-ec59e6a4f56f68916cf8ec8fefca3282a70d16d2.zip
-LRN: W32 NS provider for GNS
Also a helper service. A couple tools for installing/removing the provder. And a resolver tool that loads the provider directly.
Diffstat (limited to 'src/gns/w32nsp.c')
-rw-r--r--src/gns/w32nsp.c681
1 files changed, 681 insertions, 0 deletions
diff --git a/src/gns/w32nsp.c b/src/gns/w32nsp.c
new file mode 100644
index 000000000..b3604271e
--- /dev/null
+++ b/src/gns/w32nsp.c
@@ -0,0 +1,681 @@
1/* This code is partially based upon samples from the book
2 * "Network Programming For Microsoft Windows, 2Nd Edition".
3 */
4
5#define INITGUID
6#include <windows.h>
7#include <nspapi.h>
8#include <stdint.h>
9#include <ws2tcpip.h>
10#include <ws2spi.h>
11
12#if 1
13# define DEBUGLOG(s, ...)
14#endif
15#if 0
16# define DEBUGLOG(s, ...) printf (s, ##__VA_ARGS__)
17#endif
18
19#define WINDOWS 1
20#define MINGW 1
21#ifndef __BYTE_ORDER
22#ifdef _BYTE_ORDER
23#define __BYTE_ORDER _BYTE_ORDER
24#else
25#ifdef BYTE_ORDER
26#define __BYTE_ORDER BYTE_ORDER
27#endif
28#endif
29#endif
30#ifndef __BIG_ENDIAN
31#ifdef _BIG_ENDIAN
32#define __BIG_ENDIAN _BIG_ENDIAN
33#else
34#ifdef BIG_ENDIAN
35#define __BIG_ENDIAN BIG_ENDIAN
36#endif
37#endif
38#endif
39#ifndef __LITTLE_ENDIAN
40#ifdef _LITTLE_ENDIAN
41#define __LITTLE_ENDIAN _LITTLE_ENDIAN
42#else
43#ifdef LITTLE_ENDIAN
44#define __LITTLE_ENDIAN LITTLE_ENDIAN
45#endif
46#endif
47#endif
48#include <gnunet_w32nsp_lib.h>
49#include <w32resolver.h>
50
51#define NSPAPI_VERSION_MAJOR 4
52#define NSPAPI_VERSION_MINOR 4
53
54#define REPLY_LIFETIME 60*5
55
56#define STATE_BEGIN 0x01
57#define STATE_END 0x02
58#define STATE_REPLY 0x04
59#define STATE_GHBN 0x08
60
61uint64_t
62GNUNET_htonll (uint64_t n)
63{
64#if __BYTE_ORDER == __BIG_ENDIAN
65 return n;
66#elif __BYTE_ORDER == __LITTLE_ENDIAN
67 return (((uint64_t) htonl (n)) << 32) + htonl (n >> 32);
68#else
69 #error byteorder undefined
70#endif
71}
72
73CRITICAL_SECTION records_cs;
74
75struct record
76{
77 SOCKET s;
78 DWORD flags;
79 uint8_t state;
80 char *buf;
81 wchar_t *name;
82};
83
84static struct record *records = NULL;
85static size_t records_len = 0;
86static size_t records_size = 0;
87
88int
89resize_records ()
90{
91 size_t new_size = records_len > 0 ? records_len * 2 : 5;
92 struct record *new_records = malloc (new_size * sizeof (struct record));
93 if (new_records == NULL)
94 {
95 SetLastError (WSA_NOT_ENOUGH_MEMORY);
96 return 0;
97 }
98 memcpy (new_records, records, records_len * sizeof (struct record));
99 memset (&new_records[records_len], 0, sizeof (struct record) * (new_size - records_len));
100 records_size = new_size;
101 free (records);
102 records = new_records;
103 return 1;
104}
105
106int
107add_record (SOCKET s, const wchar_t *name, DWORD flags)
108{
109 int res = 1;
110 int i;
111 int empty = -1;
112 //EnterCriticalSection (&records_cs);
113 for (i = 0; i < records_len; i++)
114 if (records[i].state == 0)
115 break;
116 empty = i;
117 if (i == records_len)
118 {
119 res = resize_records ();
120 if (res)
121 empty = records_len++;
122 }
123 if (res)
124 {
125 struct record r;
126 r.s = s;
127 r.flags = flags;
128 r.name = (wchar_t *) name;
129 r.state = 1;
130 r.buf = NULL;
131 if (name)
132 r.name = wcsdup (name);
133 records[empty] = r;
134 }
135 //LeaveCriticalSection (&records_cs);
136 return res;
137}
138
139void
140free_record (int i)
141{
142 if (records[i].name)
143 free (records[i].name);
144 records[i].state = 0;
145}
146
147/* These are not defined by mingw.org headers at the moment*/
148typedef INT (WSPAPI *LPNSPIOCTL) (HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPWSACOMPLETION,LPWSATHREADID);
149typedef struct _NSP_ROUTINE_XP {
150 DWORD cbSize;
151 DWORD dwMajorVersion;
152 DWORD dwMinorVersion;
153 LPNSPCLEANUP NSPCleanup;
154 LPNSPLOOKUPSERVICEBEGIN NSPLookupServiceBegin;
155 LPNSPLOOKUPSERVICENEXT NSPLookupServiceNext;
156 LPNSPLOOKUPSERVICEEND NSPLookupServiceEnd;
157 LPNSPSETSERVICE NSPSetService;
158 LPNSPINSTALLSERVICECLASS NSPInstallServiceClass;
159 LPNSPREMOVESERVICECLASS NSPRemoveServiceClass;
160 LPNSPGETSERVICECLASSINFO NSPGetServiceClassInfo;
161 LPNSPIOCTL NSPIoctl;
162} NSP_ROUTINE_XP, *PNSP_ROUTINE_XP, *LPNSP_ROUTINE_XP;
163
164static SOCKET
165connect_to_dns_resolver ()
166{
167 struct sockaddr_in addr;
168 SOCKET r;
169 int ret;
170
171 r = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
172 if (INVALID_SOCKET == r)
173 {
174 SetLastError (16004);
175 return r;
176 }
177
178 addr.sin_family = AF_INET;
179 addr.sin_port = htons (5353); /* TCP 5353 is not registered; UDP 5353 is */
180 addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
181
182 ret = connect (r, (struct sockaddr *) &addr, sizeof (addr));
183 if (SOCKET_ERROR == ret)
184 {
185 DWORD err = GetLastError ();
186 closesocket (r);
187 SetLastError (err);
188 SetLastError (16005);
189 r = INVALID_SOCKET;
190 }
191 return r;
192}
193
194static int
195send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,
196 LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
197 SOCKET *resolver)
198{
199 struct GNUNET_W32RESOLVER_GetMessage *msg;
200 int af4 = 0;
201 int af6 = 0;
202 char *buf;
203 int ret = 1;
204 int i;
205 uint32_t id;
206 size_t size = sizeof (struct GNUNET_W32RESOLVER_GetMessage);
207 size_t namelen = 0;
208 if (lpqsRestrictions->lpszServiceInstanceName)
209 namelen = sizeof (wchar_t) * (wcslen (lpqsRestrictions->lpszServiceInstanceName) + 1);
210 size += namelen;
211 buf = malloc (size);
212 msg = (struct GNUNET_W32RESOLVER_GetMessage *) buf;
213 msg->header.size = htons (size);
214 msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST);
215 if (lpqsRestrictions->dwNumberOfProtocols > 0)
216 {
217 int i;
218 for (i = 0; i < lpqsRestrictions->dwNumberOfProtocols; i++)
219 {
220 if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET)
221 af4 = 1;
222 if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET6)
223 af6 = 1;
224 }
225 }
226 if (af4 && !af6)
227 msg->af = htonl (AF_INET);
228 else if (af6 && !af4)
229 msg->af = htonl (AF_INET6);
230 else
231 msg->af = htonl (AF_UNSPEC);
232 if (lpqsRestrictions->lpszServiceInstanceName)
233 memcpy (&msg[1], lpqsRestrictions->lpszServiceInstanceName, namelen);
234 msg->sc_data1 = htonl (lpqsRestrictions->lpServiceClassId->Data1);
235 msg->sc_data2 = htons (lpqsRestrictions->lpServiceClassId->Data2);
236 msg->sc_data3 = htons (lpqsRestrictions->lpServiceClassId->Data3);
237 msg->sc_data4 = 0;
238 for (i = 0; i < 8; i++)
239 msg->sc_data4 |= ((uint64_t) lpqsRestrictions->lpServiceClassId->Data4[i]) << ((7 - i) * 8);
240 msg->sc_data4 = GNUNET_htonll (msg->sc_data4);
241 *resolver = connect_to_dns_resolver ();
242 if (*resolver != INVALID_SOCKET)
243 {
244 if (size != send (*resolver, buf, size, 0))
245 {
246 DWORD err = GetLastError ();
247 closesocket (*resolver);
248 *resolver = INVALID_SOCKET;
249 DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to send request: %lu\n", err);
250 SetLastError (WSATRY_AGAIN);
251 ret = 0;
252 }
253 }
254 else
255 ret = 0;
256 free (buf);
257 return ret;
258}
259
260int WSPAPI
261NSPCleanup (LPGUID lpProviderId)
262{
263 DEBUGLOG ("NSPCleanup\n");
264 if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
265 {
266 return NO_ERROR;
267 }
268 SetLastError (WSAEINVALIDPROVIDER);
269 return SOCKET_ERROR;
270}
271
272BOOL WINAPI
273DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
274{
275 switch (fdwReason)
276 {
277 case DLL_PROCESS_ATTACH:
278 if (!InitializeCriticalSectionAndSpinCount (&records_cs, 0x00000400))
279 {
280 return FALSE;
281 }
282 break;
283 case DLL_THREAD_ATTACH:
284 break;
285 case DLL_THREAD_DETACH:
286 break;
287 case DLL_PROCESS_DETACH:
288 DeleteCriticalSection (&records_cs);
289 break;
290 }
291 return TRUE;
292}
293
294
295
296
297int WSPAPI
298GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions,
299 LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
300 LPHANDLE lphLookup)
301{
302 DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin\n");
303 if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
304 {
305 SOCKET s;
306 if (lpqsRestrictions->dwNameSpace != NS_DNS && lpqsRestrictions->dwNameSpace != NS_ALL)
307 {
308 DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong namespace\n");
309 SetLastError (WSANO_DATA);
310 return SOCKET_ERROR;
311 }
312 if (lpqsRestrictions->lpszServiceInstanceName != NULL)
313 {
314 wchar_t *s = lpqsRestrictions->lpszServiceInstanceName;
315 size_t len = wcslen (s);
316 if (len >= 4 && wcscmp (&s[len - 4], L"zkey") == 0)
317 {
318 }
319 else if (len >= 6 && wcscmp (&s[len - 6], L"gnunet") == 0)
320 {
321 }
322 else
323 {
324 DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n");
325 SetLastError (WSANO_DATA);
326 return SOCKET_ERROR;
327 }
328 }
329
330 if (send_name_to_ip_request (lpqsRestrictions,
331 lpServiceClassInfo, dwControlFlags, &s))
332 {
333 if (!(add_record (s, lpqsRestrictions->lpszServiceInstanceName, dwControlFlags)))
334 {
335 DWORD err = GetLastError ();
336 DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to add a record\n");
337 closesocket (s);
338 SetLastError (err);
339 return SOCKET_ERROR;
340 }
341 *lphLookup = (HANDLE) s;
342 DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: OK (%lu)\n", GetLastError ());
343 return NO_ERROR;
344 }
345 return SOCKET_ERROR;
346 }
347 DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong provider\n");
348 SetLastError (WSAEINVALIDPROVIDER);
349 return SOCKET_ERROR;
350}
351
352#define UnmarshallPtr(ptr, ptrtype, base) \
353 if (ptr) \
354 ptr = (ptrtype *) (base + (uintptr_t) ptr)
355
356void
357UnmarshallWSAQUERYSETW (LPWSAQUERYSETW req)
358{
359 int i;
360 char *base = (char *) req;
361 UnmarshallPtr (req->lpszServiceInstanceName, wchar_t, base);
362 UnmarshallPtr (req->lpServiceClassId, GUID, base);
363 UnmarshallPtr (req->lpVersion, WSAVERSION, base);
364 UnmarshallPtr (req->lpszComment, wchar_t, base);
365 UnmarshallPtr (req->lpNSProviderId, GUID, base);
366 UnmarshallPtr (req->lpszContext, wchar_t, base);
367 UnmarshallPtr (req->lpafpProtocols, AFPROTOCOLS, base);
368 UnmarshallPtr (req->lpszQueryString, wchar_t, base);
369 UnmarshallPtr (req->lpcsaBuffer, CSADDR_INFO, base);
370 for (i = 0; i < req->dwNumberOfCsAddrs; i++)
371 {
372 UnmarshallPtr (req->lpcsaBuffer[i].LocalAddr.lpSockaddr, SOCKADDR, base);
373 UnmarshallPtr (req->lpcsaBuffer[i].RemoteAddr.lpSockaddr, SOCKADDR, base);
374 }
375 UnmarshallPtr (req->lpBlob, BLOB, base);
376 if (req->lpBlob)
377 UnmarshallPtr (req->lpBlob->pBlobData, BYTE, base);
378}
379
380int WSAAPI
381GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
382 LPDWORD lpdwBufferLength, LPWSAQUERYSET lpqsResults)
383{
384 DWORD effective_flags;
385 int i;
386 struct GNUNET_MessageHeader header = {0, 0};
387 int rec = -1;
388 int rc;
389 int to_receive;
390 int t;
391 char *buf;
392
393 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext\n");
394 //EnterCriticalSection (&records_cs);
395 for (i = 0; i < records_len; i++)
396 {
397 if (records[i].s == (SOCKET) hLookup)
398 {
399 rec = i;
400 break;
401 }
402 }
403 if (rec == -1)
404 {
405 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: invalid handle\n");
406 SetLastError (WSA_INVALID_HANDLE);
407 //LeaveCriticalSection (&records_cs);
408 return SOCKET_ERROR;
409 }
410 if (records[rec].state & 4)
411 {
412 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: session is closed\n");
413 SetLastError (WSA_E_NO_MORE);
414 //LeaveCriticalSection (&records_cs);
415 return SOCKET_ERROR;
416 }
417 effective_flags = dwControlFlags & records[rec].flags;
418 if (records[rec].buf)
419 {
420 header = *((struct GNUNET_MessageHeader *) records[rec].buf);
421 if (dwControlFlags & LUP_FLUSHCACHE)
422 {
423 free (records[rec].buf);
424 records[rec].buf = NULL;
425 }
426 else
427 {
428 if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
429 {
430 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
431 SetLastError (WSAEFAULT);
432 //LeaveCriticalSection (&records_cs);
433 return SOCKET_ERROR;
434 }
435 memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)records[rec].buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
436 free (records[rec].buf);
437 records[rec].buf = NULL;
438 //LeaveCriticalSection (&records_cs);
439 UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
440 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n");
441 return NO_ERROR;
442 }
443 }
444 records[rec].state |= 8;
445 //LeaveCriticalSection (&records_cs);
446 to_receive = sizeof (header);
447 rc = 0;
448 while (to_receive > 0)
449 {
450 t = recv ((SOCKET) hLookup, &((char *) &header)[rc], to_receive, 0);
451 if (t > 0)
452 {
453 rc += t;
454 to_receive -= t;
455 }
456 else
457 break;
458 }
459 //EnterCriticalSection (&records_cs);
460 records[rec].state &= ~8;
461 if (rc != sizeof (header))
462 {
463 if (records[rec].state & 2)
464 {
465 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
466 SetLastError (WSA_E_CANCELLED);
467 }
468 else
469 {
470 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data\n");
471 SetLastError (WSA_E_NO_MORE);
472 }
473 records[rec].state |= 4;
474 //LeaveCriticalSection (&records_cs);
475 return SOCKET_ERROR;
476 }
477 records[rec].state &= ~8;
478 header.type = ntohs (header.type);
479 header.size = ntohs (header.size);
480 if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE ||
481 (header.type == GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE &&
482 header.size == sizeof (header)))
483 {
484 records[rec].state |= 4;
485 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header is wrong or type is wrong or no data\n");
486 //LeaveCriticalSection (&records_cs);
487 SetLastError (WSA_E_NO_MORE);
488 return SOCKET_ERROR;
489 }
490 buf = malloc (header.size);
491 if (buf == NULL)
492 {
493 records[rec].state |= 4;
494 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: malloc() failed\n");
495 //LeaveCriticalSection (&records_cs);
496 SetLastError (WSA_E_NO_MORE);
497 return SOCKET_ERROR;
498 }
499 records[rec].state |= 8;
500 //LeaveCriticalSection (&records_cs);
501 memcpy (buf, &header, sizeof (header));
502 to_receive = header.size - sizeof (header);
503 rc = 0;
504 while (to_receive > 0)
505 {
506 t = recv ((SOCKET) hLookup, &((char *) &((struct GNUNET_MessageHeader *) buf)[1])[rc], to_receive, 0);
507 if (t > 0)
508 {
509 rc += t;
510 to_receive -= t;
511 }
512 else
513 break;
514 }
515 //EnterCriticalSection (&records_cs);
516 records[rec].state &= ~8;
517 if (rc != header.size - sizeof (header))
518 {
519 free (buf);
520 if (records[rec].state & 2)
521 {
522 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
523 SetLastError (WSA_E_CANCELLED);
524 }
525 else
526 {
527 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data\n");
528 SetLastError (WSA_E_NO_MORE);
529 }
530 records[rec].state |= 4;
531 //LeaveCriticalSection (&records_cs);
532 return SOCKET_ERROR;
533 }
534 if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
535 {
536 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
537 SetLastError (WSAEFAULT);
538 records[rec].buf = buf;
539 //LeaveCriticalSection (&records_cs);
540 return SOCKET_ERROR;
541 }
542 //LeaveCriticalSection (&records_cs);
543 memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
544 free (buf);
545 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK\n");
546 UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
547 DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: returning (%lu)\n", GetLastError ());
548 return NO_ERROR;
549}
550
551int WSPAPI
552GNUNET_W32NSP_LookupServiceEnd (HANDLE hLookup)
553{
554 DWORD effective_flags;
555 int i;
556 struct GNUNET_MessageHeader header = {0, 0};
557 int rec = -1;
558 int rc;
559 char *buf;
560
561 DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd\n");
562 //EnterCriticalSection (&records_cs);
563 for (i = 0; i < records_len; i++)
564 {
565 if (records[i].s == (SOCKET) hLookup)
566 {
567 rec = i;
568 break;
569 }
570 }
571 if (rec == -1)
572 {
573 SetLastError (WSA_INVALID_HANDLE);
574 //LeaveCriticalSection (&records_cs);
575 DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: invalid handle\n");
576 return SOCKET_ERROR;
577 }
578 records[rec].state |= 2;
579 closesocket (records[rec].s);
580 while (records[rec].state & 8)
581 {
582 //LeaveCriticalSection (&records_cs);
583 Sleep (10);
584 //EnterCriticalSection (&records_cs);
585 }
586 if (records[rec].buf)
587 free (records[rec].buf);
588 records[rec].buf = NULL;
589 records[rec].state = 0;
590 if (records[rec].name)
591 free (records[rec].name);
592 //LeaveCriticalSection (&records_cs);
593 DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: OK\n");
594 return NO_ERROR;
595}
596
597int WSAAPI
598GNUNET_W32NSP_SetService (LPGUID lpProviderId,
599 LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo,
600 WSAESETSERVICEOP essOperation, DWORD dwControlFlags)
601{
602 DEBUGLOG ("GNUNET_W32NSP_SetService\n");
603 SetLastError (WSAEOPNOTSUPP);
604 return SOCKET_ERROR;
605}
606
607int WSAAPI
608GNUNET_W32NSP_InstallServiceClass (LPGUID lpProviderId,
609 LPWSASERVICECLASSINFOW lpServiceClassInfo)
610{
611 DEBUGLOG ("GNUNET_W32NSP_InstallServiceClass\n");
612 SetLastError (WSAEOPNOTSUPP);
613 return SOCKET_ERROR;
614}
615
616
617int WSAAPI
618GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)
619{
620 DEBUGLOG ("GNUNET_W32NSP_RemoveServiceClass\n");
621 SetLastError (WSAEOPNOTSUPP);
622 return SOCKET_ERROR;
623}
624
625int WSAAPI
626GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize,
627 LPWSASERVICECLASSINFOW lpServiceClassInfo)
628{
629 DEBUGLOG ("GNUNET_W32NSP_GetServiceClassInfo\n");
630 SetLastError (WSAEOPNOTSUPP);
631 return SOCKET_ERROR;
632}
633
634int WSAAPI
635GNUNET_W32NSP_Ioctl (HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer,
636 DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer,
637 LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion,
638 LPWSATHREADID lpThreadId)
639{
640 DEBUGLOG ("GNUNET_W32NSP_Ioctl\n");
641 SetLastError (WSAEOPNOTSUPP);
642 return SOCKET_ERROR;
643}
644
645/**
646 * This function is called by Winsock to hook up our provider.
647 * It is the only function that [should be/is] exported by the
648 * provider. All other routines are passed as pointers in lpnspRoutines.
649 */
650int WSPAPI
651NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
652{
653 if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
654 {
655 if (!connect_to_dns_resolver ())
656 {
657 return SOCKET_ERROR;
658 }
659 /* This assumes that NSP_ROUTINE struct doesn't have a NSPIoctl member.
660 * If it does, you need to use FIELD_OFFSET() macro to get offset of NSPIoctl
661 * and use that offset as cbSize.
662 */
663 lpnspRoutines->cbSize = sizeof(NSP_ROUTINE_XP);
664
665 lpnspRoutines->dwMajorVersion = NSPAPI_VERSION_MAJOR;
666 lpnspRoutines->dwMinorVersion = NSPAPI_VERSION_MINOR;
667 lpnspRoutines->NSPCleanup = NSPCleanup;
668 lpnspRoutines->NSPLookupServiceBegin = GNUNET_W32NSP_LookupServiceBegin;
669 lpnspRoutines->NSPLookupServiceNext = GNUNET_W32NSP_LookupServiceNext;
670 lpnspRoutines->NSPLookupServiceEnd = GNUNET_W32NSP_LookupServiceEnd;
671 lpnspRoutines->NSPSetService = GNUNET_W32NSP_SetService;
672 lpnspRoutines->NSPInstallServiceClass = GNUNET_W32NSP_InstallServiceClass;
673 lpnspRoutines->NSPRemoveServiceClass = GNUNET_W32NSP_RemoveServiceClass;
674 lpnspRoutines->NSPGetServiceClassInfo = GNUNET_W32NSP_GetServiceClassInfo;
675 ((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;
676 return NO_ERROR;
677 }
678 SetLastError (WSAEINVALIDPROVIDER);
679 return SOCKET_ERROR;
680}
681