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 {
86  DWORD flags;
87  uint8_t state;
88  char *buf;
89  wchar_t *name;
90 };
91 
92 static struct record *records = NULL;
93 static size_t records_len = 0;
94 static size_t records_size = 0;
95 
96 static int
98 {
99  size_t new_size = records_len > 0 ? records_len * 2 : 5;
100  struct record *new_records = malloc (new_size * sizeof (struct record));
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 (SOCKET s, const wchar_t *name, DWORD flags)
116 {
117  int res = 1;
118  int i;
119  int empty = -1;
120  //EnterCriticalSection (&records_cs);
121  for (i = 0; i < records_len; i++)
122  if (records[i].state == 0)
123  break;
124  empty = i;
125  if (i == records_len)
126  {
127  res = resize_records ();
128  if (res)
129  empty = records_len++;
130  }
131  if (res)
132  {
133  struct record r;
134  r.s = s;
135  r.flags = flags;
136  r.name = (wchar_t *) name;
137  r.state = 1;
138  r.buf = NULL;
139  if (name)
140  r.name = wcsdup (name);
141  records[empty] = r;
142  }
143  //LeaveCriticalSection (&records_cs);
144  return res;
145 }
146 
147 /* These are not defined by mingw.org headers at the moment*/
148 typedef INT (WSPAPI *LPNSPIOCTL) (HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPWSACOMPLETION,LPWSATHREADID);
149 typedef struct _NSP_ROUTINE_XP {
150  DWORD cbSize;
153  LPNSPCLEANUP NSPCleanup;
154  LPNSPLOOKUPSERVICEBEGIN NSPLookupServiceBegin;
155  LPNSPLOOKUPSERVICENEXT NSPLookupServiceNext;
156  LPNSPLOOKUPSERVICEEND NSPLookupServiceEnd;
157  LPNSPSETSERVICE NSPSetService;
158  LPNSPINSTALLSERVICECLASS NSPInstallServiceClass;
159  LPNSPREMOVESERVICECLASS NSPRemoveServiceClass;
160  LPNSPGETSERVICECLASSINFO NSPGetServiceClassInfo;
163 
164 static SOCKET
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 
194 static int
195 send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,
196  LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
197  SOCKET *resolver)
198 {
200  int af4 = 0;
201  int af6 = 0;
202  char *buf;
203  int ret = 1;
204  int i;
205  size_t size = sizeof (struct GNUNET_W32RESOLVER_GetMessage);
206  size_t namelen = 0;
207  if (lpqsRestrictions->lpszServiceInstanceName)
208  namelen = sizeof (wchar_t) * (wcslen (lpqsRestrictions->lpszServiceInstanceName) + 1);
209  size += namelen;
210  buf = malloc (size);
211  msg = (struct GNUNET_W32RESOLVER_GetMessage *) buf;
212  msg->header.size = htons (size);
214  if (lpqsRestrictions->dwNumberOfProtocols > 0)
215  {
216  int i;
217  for (i = 0; i < lpqsRestrictions->dwNumberOfProtocols; i++)
218  {
219  if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET)
220  af4 = 1;
221  if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET6)
222  af6 = 1;
223  }
224  }
225  if (af4 && !af6)
226  msg->af = htonl (AF_INET);
227  else if (af6 && !af4)
228  msg->af = htonl (AF_INET6);
229  else
230  msg->af = htonl (AF_UNSPEC);
231  if (lpqsRestrictions->lpszServiceInstanceName)
232  GNUNET_memcpy (&msg[1], lpqsRestrictions->lpszServiceInstanceName, namelen);
233  msg->sc_data1 = htonl (lpqsRestrictions->lpServiceClassId->Data1);
234  msg->sc_data2 = htons (lpqsRestrictions->lpServiceClassId->Data2);
235  msg->sc_data3 = htons (lpqsRestrictions->lpServiceClassId->Data3);
236  for (i = 0; i < 8; i++)
237  msg->sc_data4[i] = lpqsRestrictions->lpServiceClassId->Data4[i];
238  *resolver = connect_to_dns_resolver ();
239  if (*resolver != INVALID_SOCKET)
240  {
241  if (size != send (*resolver, buf, size, 0))
242  {
243 #if VERBOSE
244  DWORD err = GetLastError ();
245 #endif
246  closesocket (*resolver);
247  *resolver = INVALID_SOCKET;
248  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to send request: %lu\n", err);
249  SetLastError (WSATRY_AGAIN);
250  ret = 0;
251  }
252  }
253  else
254  ret = 0;
255  free (buf);
256  return ret;
257 }
258 
259 static int WSPAPI
260 NSPCleanup (LPGUID lpProviderId)
261 {
262  DEBUGLOG ("NSPCleanup\n");
263  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
264  {
265  return NO_ERROR;
266  }
267  SetLastError (WSAEINVALIDPROVIDER);
268  return SOCKET_ERROR;
269 }
270 
271 BOOL WINAPI
272 DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
273 {
274  switch (fdwReason)
275  {
276  case DLL_PROCESS_ATTACH:
277  if (!InitializeCriticalSectionAndSpinCount (&records_cs, 0x00000400))
278  {
279  return FALSE;
280  }
281  break;
282  case DLL_THREAD_ATTACH:
283  break;
284  case DLL_THREAD_DETACH:
285  break;
286  case DLL_PROCESS_DETACH:
287  DeleteCriticalSection (&records_cs);
288  break;
289  }
290  return TRUE;
291 }
292 
293 
294 
295 
296 static int WSPAPI
297 GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions,
298  LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
299  LPHANDLE lphLookup)
300 {
301  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin\n");
302  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
303  {
304  SOCKET s;
305  if (lpqsRestrictions->dwNameSpace != NS_DNS && lpqsRestrictions->dwNameSpace != NS_ALL)
306  {
307  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong namespace\n");
308  SetLastError (WSAEINVAL);
309  return SOCKET_ERROR;
310  }
311  if (lpqsRestrictions->lpszServiceInstanceName != NULL)
312  {
313  wchar_t *s = lpqsRestrictions->lpszServiceInstanceName;
314  size_t len = wcslen (s);
315  if (len >= 5 && wcscmp (&s[len - 5], L".zkey") == 0)
316  {
317  }
318  else if (len >= 4 && wcscmp (&s[len - 4], L".gnu") == 0)
319  {
320  }
321  else
322  {
323  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n");
324  SetLastError (WSAEINVAL);
325  return SOCKET_ERROR;
326  }
327  }
328 
329  if (send_name_to_ip_request (lpqsRestrictions,
330  lpServiceClassInfo, dwControlFlags, &s))
331  {
332  if (!(add_record (s, lpqsRestrictions->lpszServiceInstanceName, dwControlFlags)))
333  {
334  DWORD err = GetLastError ();
335  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to add a record\n");
336  closesocket (s);
337  SetLastError (err);
338  return SOCKET_ERROR;
339  }
340  *lphLookup = (HANDLE) s;
341  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: OK (%lu)\n", GetLastError ());
342  return NO_ERROR;
343  }
344  return SOCKET_ERROR;
345  }
346  DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong provider\n");
347  SetLastError (WSAEINVALIDPROVIDER);
348  return SOCKET_ERROR;
349 }
350 
351 #define UnmarshallPtr(ptr, ptrtype, base) \
352  if (ptr) \
353  ptr = (ptrtype *) (base + (uintptr_t) ptr)
354 
355 static void
356 UnmarshallWSAQUERYSETW (LPWSAQUERYSETW req)
357 {
358  int i;
359  char *base = (char *) req;
360  UnmarshallPtr (req->lpszServiceInstanceName, wchar_t, base);
361  UnmarshallPtr (req->lpServiceClassId, GUID, base);
362  UnmarshallPtr (req->lpVersion, WSAVERSION, base);
363  UnmarshallPtr (req->lpszComment, wchar_t, base);
364  UnmarshallPtr (req->lpNSProviderId, GUID, base);
365  UnmarshallPtr (req->lpszContext, wchar_t, base);
366  UnmarshallPtr (req->lpafpProtocols, AFPROTOCOLS, base);
367  UnmarshallPtr (req->lpszQueryString, wchar_t, base);
368  UnmarshallPtr (req->lpcsaBuffer, CSADDR_INFO, base);
369  for (i = 0; i < req->dwNumberOfCsAddrs; i++)
370  {
371  UnmarshallPtr (req->lpcsaBuffer[i].LocalAddr.lpSockaddr, SOCKADDR, base);
372  UnmarshallPtr (req->lpcsaBuffer[i].RemoteAddr.lpSockaddr, SOCKADDR, base);
373  }
374  UnmarshallPtr (req->lpBlob, BLOB, base);
375  if (req->lpBlob)
376  UnmarshallPtr (req->lpBlob->pBlobData, BYTE, base);
377 }
378 
379 static int WSAAPI
380 GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
381  LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
382 {
383  /*DWORD effective_flags;*/
384  int i;
385  struct GNUNET_MessageHeader header = {0, 0};
386  int rec = -1;
387  int rc;
388  int to_receive;
389  int t;
390  char *buf;
391 
392  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext\n");
393  //EnterCriticalSection (&records_cs);
394  for (i = 0; i < records_len; i++)
395  {
396  if (records[i].s == (SOCKET) hLookup)
397  {
398  rec = i;
399  break;
400  }
401  }
402  if (rec == -1)
403  {
404  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: invalid handle\n");
405  SetLastError (WSA_INVALID_HANDLE);
406  //LeaveCriticalSection (&records_cs);
407  return SOCKET_ERROR;
408  }
409  if (records[rec].state & 4)
410  {
411  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: session is closed\n");
412  SetLastError (WSA_E_NO_MORE);
413  //LeaveCriticalSection (&records_cs);
414  return SOCKET_ERROR;
415  }
416  /*effective_flags = dwControlFlags & records[rec].flags;*/
417  if (records[rec].buf)
418  {
419  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: checking buffer\n");
420  header = *((struct GNUNET_MessageHeader *) records[rec].buf);
421  if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
422  {
423  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
424  SetLastError (WSAEFAULT);
425  //LeaveCriticalSection (&records_cs);
426  return SOCKET_ERROR;
427  }
428  GNUNET_memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)records[rec].buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
429  free (records[rec].buf);
430  records[rec].buf = NULL;
431  //LeaveCriticalSection (&records_cs);
432  UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
433  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n");
434  return NO_ERROR;
435  }
436  records[rec].state |= 8;
437  //LeaveCriticalSection (&records_cs);
438  to_receive = sizeof (header);
439  rc = 0;
440 #if VERBOSE
441  {
442  unsigned long have;
443  int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
444  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a header from %p, %lu bytes available\n", to_receive, hLookup, have);
445  }
446 #endif
447  while (to_receive > 0)
448  {
449  t = recv ((SOCKET) hLookup, &((char *) &header)[rc], to_receive, 0);
450  if (t > 0)
451  {
452  rc += t;
453  to_receive -= t;
454  }
455  else
456  break;
457  }
458 #if VERBOSE
459  {
460  unsigned long have;
461  int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
462  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a header from %p, %lu bytes available\n", rc, hLookup, have);
463  }
464 #endif
465  //EnterCriticalSection (&records_cs);
466  records[rec].state &= ~8;
467  if (rc != sizeof (header))
468  {
469  if (records[rec].state & 2)
470  {
471  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
472  SetLastError (WSA_E_CANCELLED);
473  }
474  else
475  {
476  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);
477  SetLastError (WSA_E_NO_MORE);
478  }
479  records[rec].state |= 4;
480  //LeaveCriticalSection (&records_cs);
481  return SOCKET_ERROR;
482  }
483  records[rec].state &= ~8;
484  header.type = ntohs (header.type);
485  header.size = ntohs (header.size);
486  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header type %d, header size %u\n", header.type, header.size);
489  header.size == sizeof (header)))
490  {
491  records[rec].state |= 4;
493  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header type is wrong\n");
494  else
495  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: empty header - no data\n");
496  //LeaveCriticalSection (&records_cs);
497  SetLastError (WSA_E_NO_MORE);
498  return SOCKET_ERROR;
499  }
500  buf = malloc (header.size);
501  if (buf == NULL)
502  {
503  records[rec].state |= 4;
504  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: malloc() failed\n");
505  //LeaveCriticalSection (&records_cs);
506  SetLastError (WSA_E_NO_MORE);
507  return SOCKET_ERROR;
508  }
509  records[rec].state |= 8;
510  //LeaveCriticalSection (&records_cs);
511  GNUNET_memcpy (buf, &header, sizeof (header));
512  to_receive = header.size - sizeof (header);
513  rc = 0;
514 #if VERBOSE
515  {
516  unsigned long have;
517  int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
518  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a body from %p, %lu bytes available\n", to_receive, hLookup, have);
519  }
520 #endif
521  while (to_receive > 0)
522  {
523  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: recv (%d)\n", to_receive);
524  t = recv ((SOCKET) hLookup, &((char *) &((struct GNUNET_MessageHeader *) buf)[1])[rc], to_receive, 0);
525  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: recv returned %d\n", t);
526  if (t > 0)
527  {
528  rc += t;
529  to_receive -= t;
530  }
531  else
532  break;
533  }
534 #if VERBOSE
535  {
536  unsigned long have;
537  int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
538  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a body from %p, %lu bytes available\n", rc, hLookup, have);
539  }
540 #endif
541  //EnterCriticalSection (&records_cs);
542  records[rec].state &= ~8;
543  if (rc != header.size - sizeof (header))
544  {
545  free (buf);
546  if (records[rec].state & 2)
547  {
548  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
549  SetLastError (WSA_E_CANCELLED);
550  }
551  else
552  {
553  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);
554  SetLastError (WSA_E_NO_MORE);
555  }
556  records[rec].state |= 4;
557  //LeaveCriticalSection (&records_cs);
558  return SOCKET_ERROR;
559  }
560  if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
561  {
562  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
563  SetLastError (WSAEFAULT);
564  records[rec].buf = buf;
565  //LeaveCriticalSection (&records_cs);
566  return SOCKET_ERROR;
567  }
568  //LeaveCriticalSection (&records_cs);
569  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: writing %d bytes into result buffer\n", header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
570  GNUNET_memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
571  free (buf);
572  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK\n");
573  UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
574  DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: returning (%lu)\n", GetLastError ());
575  return NO_ERROR;
576 }
577 
578 static int WSPAPI
580 {
581  int i;
582  int rec = -1;
583 
584  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd\n");
585  //EnterCriticalSection (&records_cs);
586  for (i = 0; i < records_len; i++)
587  {
588  if (records[i].s == (SOCKET) hLookup)
589  {
590  rec = i;
591  break;
592  }
593  }
594  if (rec == -1)
595  {
596  SetLastError (WSA_INVALID_HANDLE);
597  //LeaveCriticalSection (&records_cs);
598  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: invalid handle\n");
599  return SOCKET_ERROR;
600  }
601  records[rec].state |= 2;
602  closesocket (records[rec].s);
603  while (records[rec].state & 8)
604  {
605  //LeaveCriticalSection (&records_cs);
606  Sleep (10);
607  //EnterCriticalSection (&records_cs);
608  }
609  if (records[rec].buf)
610  free (records[rec].buf);
611  records[rec].buf = NULL;
612  records[rec].state = 0;
613  if (records[rec].name)
614  free (records[rec].name);
615  //LeaveCriticalSection (&records_cs);
616  DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: OK\n");
617  return NO_ERROR;
618 }
619 
620 static int WSAAPI
621 GNUNET_W32NSP_SetService (LPGUID lpProviderId,
622  LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo,
623  WSAESETSERVICEOP essOperation, DWORD dwControlFlags)
624 {
625  DEBUGLOG ("GNUNET_W32NSP_SetService\n");
626  SetLastError (WSAEOPNOTSUPP);
627  return SOCKET_ERROR;
628 }
629 
630 static int WSAAPI
632  LPWSASERVICECLASSINFOW lpServiceClassInfo)
633 {
634  DEBUGLOG ("GNUNET_W32NSP_InstallServiceClass\n");
635  SetLastError (WSAEOPNOTSUPP);
636  return SOCKET_ERROR;
637 }
638 
639 
640 static int WSAAPI
641 GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)
642 {
643  DEBUGLOG ("GNUNET_W32NSP_RemoveServiceClass\n");
644  SetLastError (WSAEOPNOTSUPP);
645  return SOCKET_ERROR;
646 }
647 
648 static int WSAAPI
649 GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize,
650  LPWSASERVICECLASSINFOW lpServiceClassInfo)
651 {
652  DEBUGLOG ("GNUNET_W32NSP_GetServiceClassInfo\n");
653  SetLastError (WSAEOPNOTSUPP);
654  return SOCKET_ERROR;
655 }
656 
657 static int WSAAPI
658 GNUNET_W32NSP_Ioctl (HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer,
659  DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer,
660  LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion,
661  LPWSATHREADID lpThreadId)
662 {
663  DEBUGLOG ("GNUNET_W32NSP_Ioctl\n");
664  SetLastError (WSAEOPNOTSUPP);
665  return SOCKET_ERROR;
666 }
667 
673 int WSAAPI
674 GNUNET_W32NSP_NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
675 {
676  if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
677  {
678  if (!connect_to_dns_resolver ())
679  {
680  return SOCKET_ERROR;
681  }
682  /* This assumes that NSP_ROUTINE struct doesn't have a NSPIoctl member.
683  * If it does, you need to use FIELD_OFFSET() macro to get offset of NSPIoctl
684  * and use that offset as cbSize.
685  */
686  lpnspRoutines->cbSize = sizeof(NSP_ROUTINE);
687 
688  lpnspRoutines->dwMajorVersion = NSPAPI_VERSION_MAJOR;
689  lpnspRoutines->dwMinorVersion = NSPAPI_VERSION_MINOR;
690  lpnspRoutines->NSPCleanup = NSPCleanup;
691  lpnspRoutines->NSPLookupServiceBegin = GNUNET_W32NSP_LookupServiceBegin;
692  lpnspRoutines->NSPLookupServiceNext = GNUNET_W32NSP_LookupServiceNext;
693  lpnspRoutines->NSPLookupServiceEnd = GNUNET_W32NSP_LookupServiceEnd;
694  lpnspRoutines->NSPSetService = GNUNET_W32NSP_SetService;
695  lpnspRoutines->NSPInstallServiceClass = GNUNET_W32NSP_InstallServiceClass;
696  lpnspRoutines->NSPRemoveServiceClass = GNUNET_W32NSP_RemoveServiceClass;
697  lpnspRoutines->NSPGetServiceClassInfo = GNUNET_W32NSP_GetServiceClassInfo;
698  /*((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;*/
699  lpnspRoutines->NSPIoctl = GNUNET_W32NSP_Ioctl;
700  return NO_ERROR;
701  }
702  SetLastError (WSAEINVALIDPROVIDER);
703  return SOCKET_ERROR;
704 }
705 
static struct record * records
Definition: w32nsp.c:92
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
Definition: w32nsp.c:272
#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:621
static CRITICAL_SECTION records_cs
Definition: w32nsp.c:81
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
DWORD flags
Definition: w32nsp.c:86
static int WSPAPI GNUNET_W32NSP_LookupServiceEnd(HANDLE hLookup)
Definition: w32nsp.c:579
Definition: w32nsp.c:83
DWORD dwMinorVersion
Definition: w32nsp.c:152
static int WSAAPI GNUNET_W32NSP_LookupServiceNext(HANDLE hLookup, DWORD dwControlFlags, LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
Definition: w32nsp.c:380
static int WSAAPI GNUNET_W32NSP_GetServiceClassInfo(LPGUID lpProviderId, LPDWORD lpdwBufSize, LPWSASERVICECLASSINFOW lpServiceClassInfo)
Definition: w32nsp.c:649
LPNSPIOCTL NSPIoctl
Definition: w32nsp.c:161
struct GNUNET_OS_Process * resolver
Resolver process handle.
LPNSPLOOKUPSERVICEBEGIN NSPLookupServiceBegin
Definition: w32nsp.c:154
SOCKET s
Definition: w32nsp.c:85
wchar_t * name
Definition: w32nsp.c:89
static SOCKET connect_to_dns_resolver()
Definition: w32nsp.c:165
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:356
int WSAAPI GNUNET_W32NSP_NSPStartup(LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
This function is called by Winsock to hook up our provider.
Definition: w32nsp.c:674
char * buf
Definition: w32nsp.c:88
LPNSPREMOVESERVICECLASS NSPRemoveServiceClass
Definition: w32nsp.c:159
static int WSAAPI GNUNET_W32NSP_InstallServiceClass(LPGUID lpProviderId, LPWSASERVICECLASSINFOW lpServiceClassInfo)
Definition: w32nsp.c:631
LPNSPSETSERVICE NSPSetService
Definition: w32nsp.c:157
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:97
LPNSPLOOKUPSERVICENEXT NSPLookupServiceNext
Definition: w32nsp.c:155
#define INVALID_SOCKET
Definition: network.c:39
#define SOCKET(a, t, p)
Definition: plibc.h:711
Request for the resolver.
Definition: w32resolver.h:53
INT(WSPAPI * LPNSPIOCTL)(HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPWSACOMPLETION, LPWSATHREADID)
Definition: w32nsp.c:148
static int WSPAPI NSPCleanup(LPGUID lpProviderId)
Definition: w32nsp.c:260
static int res
DWORD dwMajorVersion
Definition: w32nsp.c:151
DWORD cbSize
Definition: w32nsp.c:150
#define GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST
Request DNS resolution.
Definition: w32resolver.h:35
uint8_t state
Definition: w32nsp.c:87
LPNSPLOOKUPSERVICEEND NSPLookupServiceEnd
Definition: w32nsp.c:156
static unsigned int size
Size of the "table".
Definition: peer.c:67
LPNSPINSTALLSERVICECLASS NSPInstallServiceClass
Definition: w32nsp.c:158
#define UnmarshallPtr(ptr, ptrtype, base)
Definition: w32nsp.c:351
static int WSAAPI GNUNET_W32NSP_RemoveServiceClass(LPGUID lpProviderId, LPGUID lpServiceClassId)
Definition: w32nsp.c:641
static size_t records_len
Definition: w32nsp.c:93
LPNSPCLEANUP NSPCleanup
Definition: w32nsp.c:153
static int WSPAPI GNUNET_W32NSP_LookupServiceBegin(LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, LPHANDLE lphLookup)
Definition: w32nsp.c:297
static int send_name_to_ip_request(LPWSAQUERYSETW lpqsRestrictions, LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags, SOCKET *resolver)
Definition: w32nsp.c:195
static int add_record(SOCKET s, const wchar_t *name, DWORD flags)
Definition: w32nsp.c:115
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:658
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST.
Definition: w32resolver.h:58
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:94
#define NSPAPI_VERSION_MINOR
Definition: w32nsp.c:79
LPNSPGETSERVICECLASSINFO NSPGetServiceClassInfo
Definition: w32nsp.c:160