GNUnet  0.10.x
w32nsp.c
Go to the documentation of this file.
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  */
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 
81 static CRITICAL_SECTION records_cs;
82 
83 struct record {
84  _win_socket s;
85  DWORD flags;
86  uint8_t state;
87  char *buf;
88  wchar_t *name;
89 };
90 
91 static struct record *records = NULL;
92 static size_t records_len = 0;
93 static size_t records_size = 0;
94 
95 static int
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 
114 static int
115 add_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*/
149 typedef INT (WSPAPI *LPNSPIOCTL)(HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPWSACOMPLETION, LPWSATHREADID);
150 typedef struct _NSP_ROUTINE_XP {
151  DWORD cbSize;
154  LPNSPCLEANUP NSPCleanup;
155  LPNSPLOOKUPSERVICEBEGIN NSPLookupServiceBegin;
156  LPNSPLOOKUPSERVICENEXT NSPLookupServiceNext;
157  LPNSPLOOKUPSERVICEEND NSPLookupServiceEnd;
158  LPNSPSETSERVICE NSPSetService;
159  LPNSPINSTALLSERVICECLASS NSPInstallServiceClass;
160  LPNSPREMOVESERVICECLASS NSPRemoveServiceClass;
161  LPNSPGETSERVICECLASSINFO NSPGetServiceClassInfo;
164 
165 static _win_socket
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 
195 static int
196 send_name_to_ip_request(LPWSAQUERYSETW lpqsRestrictions,
197  LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
198  _win_socket *resolver)
199 {
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);
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 
261 static int WSPAPI
262 NSPCleanup(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 
273 BOOL WINAPI
274 DllMain(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 
301 static int WSPAPI
302 GNUNET_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 
360 static void
361 UnmarshallWSAQUERYSETW(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 
385 static int WSAAPI
386 GNUNET_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);
495  header.size == sizeof(header)))
496  {
497  records[rec].state |= 4;
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 
584 static int WSPAPI
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 
626 static int WSAAPI
627 GNUNET_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 
636 static int WSAAPI
638  LPWSASERVICECLASSINFOW lpServiceClassInfo)
639 {
640  DEBUGLOG("GNUNET_W32NSP_InstallServiceClass\n");
641  SetLastError(WSAEOPNOTSUPP);
642  return SOCKET_ERROR;
643 }
644 
645 
646 static int WSAAPI
647 GNUNET_W32NSP_RemoveServiceClass(LPGUID lpProviderId, LPGUID lpServiceClassId)
648 {
649  DEBUGLOG("GNUNET_W32NSP_RemoveServiceClass\n");
650  SetLastError(WSAEOPNOTSUPP);
651  return SOCKET_ERROR;
652 }
653 
654 static int WSAAPI
655 GNUNET_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 
663 static int WSAAPI
664 GNUNET_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 
679 int WSAAPI
680 GNUNET_W32NSP_NSPStartup(LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
681 {
682  if (IsEqualGUID(lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
683  {
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 
static struct record * records
Definition: w32nsp.c:91
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
Definition: w32nsp.c:274
#define NSPAPI_VERSION_MAJOR
Definition: w32nsp.c:78
static int WSAAPI GNUNET_W32NSP_SetService(LPGUID lpProviderId, LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo, WSAESETSERVICEOP essOperation, DWORD dwControlFlags)
Definition: w32nsp.c:627
static CRITICAL_SECTION records_cs
Definition: w32nsp.c:81
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
DWORD flags
Definition: w32nsp.c:85
static _win_socket connect_to_dns_resolver()
Definition: w32nsp.c:166
static int WSPAPI GNUNET_W32NSP_LookupServiceEnd(HANDLE hLookup)
Definition: w32nsp.c:585
Definition: w32nsp.c:83
DWORD dwMinorVersion
Definition: w32nsp.c:153
static int WSAAPI GNUNET_W32NSP_LookupServiceNext(HANDLE hLookup, DWORD dwControlFlags, LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
Definition: w32nsp.c:386
static int WSAAPI GNUNET_W32NSP_GetServiceClassInfo(LPGUID lpProviderId, LPDWORD lpdwBufSize, LPWSASERVICECLASSINFOW lpServiceClassInfo)
Definition: w32nsp.c:655
LPNSPIOCTL NSPIoctl
Definition: w32nsp.c:162
struct GNUNET_OS_Process * resolver
Resolver process handle.
LPNSPLOOKUPSERVICEBEGIN NSPLookupServiceBegin
Definition: w32nsp.c:155
wchar_t * name
Definition: w32nsp.c:88
static struct GNUNET_SCHEDULER_Task * t
Main task.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct _NSP_ROUTINE_XP NSP_ROUTINE_XP
static int ret
Final status code.
Definition: gnunet-arm.c:89
static void UnmarshallWSAQUERYSETW(LPWSAQUERYSETW req)
Definition: w32nsp.c:361
int WSAAPI GNUNET_W32NSP_NSPStartup(LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
This function is called by Winsock to hook up our provider.
Definition: w32nsp.c:680
char * buf
Definition: w32nsp.c:87
LPNSPREMOVESERVICECLASS NSPRemoveServiceClass
Definition: w32nsp.c:160
static int WSAAPI GNUNET_W32NSP_InstallServiceClass(LPGUID lpProviderId, LPWSASERVICECLASSINFOW lpServiceClassInfo)
Definition: w32nsp.c:637
LPNSPSETSERVICE NSPSetService
Definition: w32nsp.c:158
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
#define DEBUGLOG(s,...)
Definition: w32nsp.c:31
static int resize_records()
Definition: w32nsp.c:96
LPNSPLOOKUPSERVICENEXT NSPLookupServiceNext
Definition: w32nsp.c:156
static int send_name_to_ip_request(LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, _win_socket *resolver)
Definition: w32nsp.c:196
#define INVALID_SOCKET
Definition: network.c:39
Request for the resolver.
Definition: w32resolver.h:53
_win_socket s
Definition: w32nsp.c:84
INT(WSPAPI * LPNSPIOCTL)(HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPWSACOMPLETION, LPWSATHREADID)
Definition: w32nsp.c:149
static int WSPAPI NSPCleanup(LPGUID lpProviderId)
Definition: w32nsp.c:262
static int res
DWORD dwMajorVersion
Definition: w32nsp.c:152
DWORD cbSize
Definition: w32nsp.c:151
#define GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST
Request DNS resolution.
Definition: w32resolver.h:35
uint8_t state
Definition: w32nsp.c:86
LPNSPLOOKUPSERVICEEND NSPLookupServiceEnd
Definition: w32nsp.c:157
static unsigned int size
Size of the "table".
Definition: peer.c:66
LPNSPINSTALLSERVICECLASS NSPInstallServiceClass
Definition: w32nsp.c:159
#define UnmarshallPtr(ptr, ptrtype, base)
Definition: w32nsp.c:356
static int WSAAPI GNUNET_W32NSP_RemoveServiceClass(LPGUID lpProviderId, LPGUID lpServiceClassId)
Definition: w32nsp.c:647
static size_t records_len
Definition: w32nsp.c:92
LPNSPCLEANUP NSPCleanup
Definition: w32nsp.c:154
static int WSPAPI GNUNET_W32NSP_LookupServiceBegin(LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, LPHANDLE lphLookup)
Definition: w32nsp.c:302
static int WSAAPI GNUNET_W32NSP_Ioctl(HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion, LPWSATHREADID lpThreadId)
Definition: w32nsp.c:664
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST.
Definition: w32resolver.h:57
static int add_record(_win_socket s, const wchar_t *name, DWORD flags)
Definition: w32nsp.c:115
Header for all communications.
#define GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE
Response to a DNS resolution request.
Definition: w32resolver.h:40
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static size_t records_size
Definition: w32nsp.c:93
#define NSPAPI_VERSION_MINOR
Definition: w32nsp.c:79
LPNSPGETSERVICECLASSINFO NSPGetServiceClassInfo
Definition: w32nsp.c:161