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