123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705 |
- /*
- This file is part of GNUnet.
- Copyright (C) 2012 GNUnet e.V.
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- or (at your option) any later version.
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- SPDX-License-Identifier: AGPL3.0-or-later
- */
- /**
- * @file gns/w32nsp.c
- * @brief W32 integration for GNS
- * @author LRN
- */
- /* This code is partially based upon samples from the book
- * "Network Programming For Microsoft Windows, 2Nd Edition".
- */
- #define VERBOSE 0
- #if !VERBOSE
- # define DEBUGLOG(s, ...)
- #endif
- #if VERBOSE
- # define __printf__ printf
- # define DEBUGLOG(s, ...) printf (s, ##__VA_ARGS__)
- #endif
- #include <stdint.h>
- #include <ws2tcpip.h>
- #include <ws2spi.h>
- #include <windows.h>
- #include <nspapi.h>
- #define WINDOWS 1
- #define MINGW 1
- #ifndef __BYTE_ORDER
- #ifdef _BYTE_ORDER
- #define __BYTE_ORDER _BYTE_ORDER
- #else
- #ifdef BYTE_ORDER
- #define __BYTE_ORDER BYTE_ORDER
- #endif
- #endif
- #endif
- #ifndef __BIG_ENDIAN
- #ifdef _BIG_ENDIAN
- #define __BIG_ENDIAN _BIG_ENDIAN
- #else
- #ifdef BIG_ENDIAN
- #define __BIG_ENDIAN BIG_ENDIAN
- #endif
- #endif
- #endif
- #ifndef __LITTLE_ENDIAN
- #ifdef _LITTLE_ENDIAN
- #define __LITTLE_ENDIAN _LITTLE_ENDIAN
- #else
- #ifdef LITTLE_ENDIAN
- #define __LITTLE_ENDIAN LITTLE_ENDIAN
- #endif
- #endif
- #endif
- #include "w32resolver.h"
- #include <initguid.h>
- #include "gnunet_w32nsp_lib.h"
- #undef INITGUID
- #define NSPAPI_VERSION_MAJOR 4
- #define NSPAPI_VERSION_MINOR 4
- static CRITICAL_SECTION records_cs;
- struct record
- {
- SOCKET s;
- DWORD flags;
- uint8_t state;
- char *buf;
- wchar_t *name;
- };
- static struct record *records = NULL;
- static size_t records_len = 0;
- static size_t records_size = 0;
- static int
- resize_records ()
- {
- size_t new_size = records_len > 0 ? records_len * 2 : 5;
- struct record *new_records = malloc (new_size * sizeof (struct record));
- if (new_records == NULL)
- {
- SetLastError (WSA_NOT_ENOUGH_MEMORY);
- return 0;
- }
- GNUNET_memcpy (new_records, records, records_len * sizeof (struct record));
- memset (&new_records[records_len], 0, sizeof (struct record) * (new_size - records_len));
- records_size = new_size;
- free (records);
- records = new_records;
- return 1;
- }
- static int
- add_record (SOCKET s, const wchar_t *name, DWORD flags)
- {
- int res = 1;
- int i;
- int empty = -1;
- //EnterCriticalSection (&records_cs);
- for (i = 0; i < records_len; i++)
- if (records[i].state == 0)
- break;
- empty = i;
- if (i == records_len)
- {
- res = resize_records ();
- if (res)
- empty = records_len++;
- }
- if (res)
- {
- struct record r;
- r.s = s;
- r.flags = flags;
- r.name = (wchar_t *) name;
- r.state = 1;
- r.buf = NULL;
- if (name)
- r.name = wcsdup (name);
- records[empty] = r;
- }
- //LeaveCriticalSection (&records_cs);
- return res;
- }
- /* These are not defined by mingw.org headers at the moment*/
- typedef INT (WSPAPI *LPNSPIOCTL) (HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPWSACOMPLETION,LPWSATHREADID);
- typedef struct _NSP_ROUTINE_XP {
- DWORD cbSize;
- DWORD dwMajorVersion;
- DWORD dwMinorVersion;
- LPNSPCLEANUP NSPCleanup;
- LPNSPLOOKUPSERVICEBEGIN NSPLookupServiceBegin;
- LPNSPLOOKUPSERVICENEXT NSPLookupServiceNext;
- LPNSPLOOKUPSERVICEEND NSPLookupServiceEnd;
- LPNSPSETSERVICE NSPSetService;
- LPNSPINSTALLSERVICECLASS NSPInstallServiceClass;
- LPNSPREMOVESERVICECLASS NSPRemoveServiceClass;
- LPNSPGETSERVICECLASSINFO NSPGetServiceClassInfo;
- LPNSPIOCTL NSPIoctl;
- } NSP_ROUTINE_XP;
- static SOCKET
- connect_to_dns_resolver ()
- {
- struct sockaddr_in addr;
- SOCKET r;
- int ret;
- r = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (INVALID_SOCKET == r)
- {
- SetLastError (16004);
- return r;
- }
- addr.sin_family = AF_INET;
- addr.sin_port = htons (5353); /* TCP 5353 is not registered; UDP 5353 is */
- addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
- ret = connect (r, (struct sockaddr *) &addr, sizeof (addr));
- if (SOCKET_ERROR == ret)
- {
- DWORD err = GetLastError ();
- closesocket (r);
- SetLastError (err);
- SetLastError (16005);
- r = INVALID_SOCKET;
- }
- return r;
- }
- static int
- send_name_to_ip_request (LPWSAQUERYSETW lpqsRestrictions,
- LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
- SOCKET *resolver)
- {
- struct GNUNET_W32RESOLVER_GetMessage *msg;
- int af4 = 0;
- int af6 = 0;
- char *buf;
- int ret = 1;
- int i;
- size_t size = sizeof (struct GNUNET_W32RESOLVER_GetMessage);
- size_t namelen = 0;
- if (lpqsRestrictions->lpszServiceInstanceName)
- namelen = sizeof (wchar_t) * (wcslen (lpqsRestrictions->lpszServiceInstanceName) + 1);
- size += namelen;
- buf = malloc (size);
- msg = (struct GNUNET_W32RESOLVER_GetMessage *) buf;
- msg->header.size = htons (size);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST);
- if (lpqsRestrictions->dwNumberOfProtocols > 0)
- {
- int i;
- for (i = 0; i < lpqsRestrictions->dwNumberOfProtocols; i++)
- {
- if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET)
- af4 = 1;
- if (lpqsRestrictions->lpafpProtocols[0].iAddressFamily == AF_INET6)
- af6 = 1;
- }
- }
- if (af4 && !af6)
- msg->af = htonl (AF_INET);
- else if (af6 && !af4)
- msg->af = htonl (AF_INET6);
- else
- msg->af = htonl (AF_UNSPEC);
- if (lpqsRestrictions->lpszServiceInstanceName)
- GNUNET_memcpy (&msg[1], lpqsRestrictions->lpszServiceInstanceName, namelen);
- msg->sc_data1 = htonl (lpqsRestrictions->lpServiceClassId->Data1);
- msg->sc_data2 = htons (lpqsRestrictions->lpServiceClassId->Data2);
- msg->sc_data3 = htons (lpqsRestrictions->lpServiceClassId->Data3);
- for (i = 0; i < 8; i++)
- msg->sc_data4[i] = lpqsRestrictions->lpServiceClassId->Data4[i];
- *resolver = connect_to_dns_resolver ();
- if (*resolver != INVALID_SOCKET)
- {
- if (size != send (*resolver, buf, size, 0))
- {
- #if VERBOSE
- DWORD err = GetLastError ();
- #endif
- closesocket (*resolver);
- *resolver = INVALID_SOCKET;
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to send request: %lu\n", err);
- SetLastError (WSATRY_AGAIN);
- ret = 0;
- }
- }
- else
- ret = 0;
- free (buf);
- return ret;
- }
- static int WSPAPI
- NSPCleanup (LPGUID lpProviderId)
- {
- DEBUGLOG ("NSPCleanup\n");
- if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
- {
- return NO_ERROR;
- }
- SetLastError (WSAEINVALIDPROVIDER);
- return SOCKET_ERROR;
- }
- BOOL WINAPI
- DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
- {
- switch (fdwReason)
- {
- case DLL_PROCESS_ATTACH:
- if (!InitializeCriticalSectionAndSpinCount (&records_cs, 0x00000400))
- {
- return FALSE;
- }
- break;
- case DLL_THREAD_ATTACH:
- break;
- case DLL_THREAD_DETACH:
- break;
- case DLL_PROCESS_DETACH:
- DeleteCriticalSection (&records_cs);
- break;
- }
- return TRUE;
- }
- static int WSPAPI
- GNUNET_W32NSP_LookupServiceBegin (LPGUID lpProviderId, LPWSAQUERYSETW lpqsRestrictions,
- LPWSASERVICECLASSINFOW lpServiceClassInfo, DWORD dwControlFlags,
- LPHANDLE lphLookup)
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin\n");
- if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
- {
- SOCKET s;
- if (lpqsRestrictions->dwNameSpace != NS_DNS && lpqsRestrictions->dwNameSpace != NS_ALL)
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong namespace\n");
- SetLastError (WSAEINVAL);
- return SOCKET_ERROR;
- }
- if (lpqsRestrictions->lpszServiceInstanceName != NULL)
- {
- wchar_t *s = lpqsRestrictions->lpszServiceInstanceName;
- size_t len = wcslen (s);
- if (len >= 5 && wcscmp (&s[len - 5], L".zkey") == 0)
- {
- }
- else if (len >= 4 && wcscmp (&s[len - 4], L".gnu") == 0)
- {
- }
- else
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: unsupported TLD\n");
- SetLastError (WSAEINVAL);
- return SOCKET_ERROR;
- }
- }
- if (send_name_to_ip_request (lpqsRestrictions,
- lpServiceClassInfo, dwControlFlags, &s))
- {
- if (!(add_record (s, lpqsRestrictions->lpszServiceInstanceName, dwControlFlags)))
- {
- DWORD err = GetLastError ();
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: failed to add a record\n");
- closesocket (s);
- SetLastError (err);
- return SOCKET_ERROR;
- }
- *lphLookup = (HANDLE) s;
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: OK (%lu)\n", GetLastError ());
- return NO_ERROR;
- }
- return SOCKET_ERROR;
- }
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceBegin: wrong provider\n");
- SetLastError (WSAEINVALIDPROVIDER);
- return SOCKET_ERROR;
- }
- #define UnmarshallPtr(ptr, ptrtype, base) \
- if (ptr) \
- ptr = (ptrtype *) (base + (uintptr_t) ptr)
- static void
- UnmarshallWSAQUERYSETW (LPWSAQUERYSETW req)
- {
- int i;
- char *base = (char *) req;
- UnmarshallPtr (req->lpszServiceInstanceName, wchar_t, base);
- UnmarshallPtr (req->lpServiceClassId, GUID, base);
- UnmarshallPtr (req->lpVersion, WSAVERSION, base);
- UnmarshallPtr (req->lpszComment, wchar_t, base);
- UnmarshallPtr (req->lpNSProviderId, GUID, base);
- UnmarshallPtr (req->lpszContext, wchar_t, base);
- UnmarshallPtr (req->lpafpProtocols, AFPROTOCOLS, base);
- UnmarshallPtr (req->lpszQueryString, wchar_t, base);
- UnmarshallPtr (req->lpcsaBuffer, CSADDR_INFO, base);
- for (i = 0; i < req->dwNumberOfCsAddrs; i++)
- {
- UnmarshallPtr (req->lpcsaBuffer[i].LocalAddr.lpSockaddr, SOCKADDR, base);
- UnmarshallPtr (req->lpcsaBuffer[i].RemoteAddr.lpSockaddr, SOCKADDR, base);
- }
- UnmarshallPtr (req->lpBlob, BLOB, base);
- if (req->lpBlob)
- UnmarshallPtr (req->lpBlob->pBlobData, BYTE, base);
- }
- static int WSAAPI
- GNUNET_W32NSP_LookupServiceNext (HANDLE hLookup, DWORD dwControlFlags,
- LPDWORD lpdwBufferLength, LPWSAQUERYSETW lpqsResults)
- {
- /*DWORD effective_flags;*/
- int i;
- struct GNUNET_MessageHeader header = {0, 0};
- int rec = -1;
- int rc;
- int to_receive;
- int t;
- char *buf;
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext\n");
- //EnterCriticalSection (&records_cs);
- for (i = 0; i < records_len; i++)
- {
- if (records[i].s == (SOCKET) hLookup)
- {
- rec = i;
- break;
- }
- }
- if (rec == -1)
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: invalid handle\n");
- SetLastError (WSA_INVALID_HANDLE);
- //LeaveCriticalSection (&records_cs);
- return SOCKET_ERROR;
- }
- if (records[rec].state & 4)
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: session is closed\n");
- SetLastError (WSA_E_NO_MORE);
- //LeaveCriticalSection (&records_cs);
- return SOCKET_ERROR;
- }
- /*effective_flags = dwControlFlags & records[rec].flags;*/
- if (records[rec].buf)
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: checking buffer\n");
- header = *((struct GNUNET_MessageHeader *) records[rec].buf);
- if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
- SetLastError (WSAEFAULT);
- //LeaveCriticalSection (&records_cs);
- return SOCKET_ERROR;
- }
- GNUNET_memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)records[rec].buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
- free (records[rec].buf);
- records[rec].buf = NULL;
- //LeaveCriticalSection (&records_cs);
- UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK (from buffer)\n");
- return NO_ERROR;
- }
- records[rec].state |= 8;
- //LeaveCriticalSection (&records_cs);
- to_receive = sizeof (header);
- rc = 0;
- #if VERBOSE
- {
- unsigned long have;
- int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a header from %p, %lu bytes available\n", to_receive, hLookup, have);
- }
- #endif
- while (to_receive > 0)
- {
- t = recv ((SOCKET) hLookup, &((char *) &header)[rc], to_receive, 0);
- if (t > 0)
- {
- rc += t;
- to_receive -= t;
- }
- else
- break;
- }
- #if VERBOSE
- {
- unsigned long have;
- int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a header from %p, %lu bytes available\n", rc, hLookup, have);
- }
- #endif
- //EnterCriticalSection (&records_cs);
- records[rec].state &= ~8;
- if (rc != sizeof (header))
- {
- if (records[rec].state & 2)
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
- SetLastError (WSA_E_CANCELLED);
- }
- else
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data for a header (rc %d != %u, state is 0x%0X)\n", rc, sizeof (header), records[rec].state);
- SetLastError (WSA_E_NO_MORE);
- }
- records[rec].state |= 4;
- //LeaveCriticalSection (&records_cs);
- return SOCKET_ERROR;
- }
- records[rec].state &= ~8;
- header.type = ntohs (header.type);
- header.size = ntohs (header.size);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header type %d, header size %u\n", header.type, header.size);
- if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE ||
- (header.type == GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE &&
- header.size == sizeof (header)))
- {
- records[rec].state |= 4;
- if (header.type != GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE)
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: header type is wrong\n");
- else
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: empty header - no data\n");
- //LeaveCriticalSection (&records_cs);
- SetLastError (WSA_E_NO_MORE);
- return SOCKET_ERROR;
- }
- buf = malloc (header.size);
- if (buf == NULL)
- {
- records[rec].state |= 4;
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: malloc() failed\n");
- //LeaveCriticalSection (&records_cs);
- SetLastError (WSA_E_NO_MORE);
- return SOCKET_ERROR;
- }
- records[rec].state |= 8;
- //LeaveCriticalSection (&records_cs);
- GNUNET_memcpy (buf, &header, sizeof (header));
- to_receive = header.size - sizeof (header);
- rc = 0;
- #if VERBOSE
- {
- unsigned long have;
- int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: reading %d bytes as a body from %p, %lu bytes available\n", to_receive, hLookup, have);
- }
- #endif
- while (to_receive > 0)
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: recv (%d)\n", to_receive);
- t = recv ((SOCKET) hLookup, &((char *) &((struct GNUNET_MessageHeader *) buf)[1])[rc], to_receive, 0);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: recv returned %d\n", t);
- if (t > 0)
- {
- rc += t;
- to_receive -= t;
- }
- else
- break;
- }
- #if VERBOSE
- {
- unsigned long have;
- int ior = ioctlsocket ((SOCKET) hLookup, FIONREAD, &have);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: read %d bytes as a body from %p, %lu bytes available\n", rc, hLookup, have);
- }
- #endif
- //EnterCriticalSection (&records_cs);
- records[rec].state &= ~8;
- if (rc != header.size - sizeof (header))
- {
- free (buf);
- if (records[rec].state & 2)
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: call cancelled\n");
- SetLastError (WSA_E_CANCELLED);
- }
- else
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: failed to receive enough data for the rest (rc %d != %d, state is 0x%0X)\n", rc, header.size - sizeof (header), records[rec].state);
- SetLastError (WSA_E_NO_MORE);
- }
- records[rec].state |= 4;
- //LeaveCriticalSection (&records_cs);
- return SOCKET_ERROR;
- }
- if (*lpdwBufferLength < header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage))
- {
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: client buffer is too small\n");
- SetLastError (WSAEFAULT);
- records[rec].buf = buf;
- //LeaveCriticalSection (&records_cs);
- return SOCKET_ERROR;
- }
- //LeaveCriticalSection (&records_cs);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: writing %d bytes into result buffer\n", header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
- GNUNET_memcpy (lpqsResults, &((struct GNUNET_W32RESOLVER_GetMessage *)buf)[1], header.size - sizeof (struct GNUNET_W32RESOLVER_GetMessage));
- free (buf);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: OK\n");
- UnmarshallWSAQUERYSETW ((LPWSAQUERYSETW) lpqsResults);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceNext: returning (%lu)\n", GetLastError ());
- return NO_ERROR;
- }
- static int WSPAPI
- GNUNET_W32NSP_LookupServiceEnd (HANDLE hLookup)
- {
- int i;
- int rec = -1;
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd\n");
- //EnterCriticalSection (&records_cs);
- for (i = 0; i < records_len; i++)
- {
- if (records[i].s == (SOCKET) hLookup)
- {
- rec = i;
- break;
- }
- }
- if (rec == -1)
- {
- SetLastError (WSA_INVALID_HANDLE);
- //LeaveCriticalSection (&records_cs);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: invalid handle\n");
- return SOCKET_ERROR;
- }
- records[rec].state |= 2;
- closesocket (records[rec].s);
- while (records[rec].state & 8)
- {
- //LeaveCriticalSection (&records_cs);
- Sleep (10);
- //EnterCriticalSection (&records_cs);
- }
- if (records[rec].buf)
- free (records[rec].buf);
- records[rec].buf = NULL;
- records[rec].state = 0;
- if (records[rec].name)
- free (records[rec].name);
- //LeaveCriticalSection (&records_cs);
- DEBUGLOG ("GNUNET_W32NSP_LookupServiceEnd: OK\n");
- return NO_ERROR;
- }
- static int WSAAPI
- GNUNET_W32NSP_SetService (LPGUID lpProviderId,
- LPWSASERVICECLASSINFOW lpServiceClassInfo, LPWSAQUERYSETW lpqsRegInfo,
- WSAESETSERVICEOP essOperation, DWORD dwControlFlags)
- {
- DEBUGLOG ("GNUNET_W32NSP_SetService\n");
- SetLastError (WSAEOPNOTSUPP);
- return SOCKET_ERROR;
- }
- static int WSAAPI
- GNUNET_W32NSP_InstallServiceClass (LPGUID lpProviderId,
- LPWSASERVICECLASSINFOW lpServiceClassInfo)
- {
- DEBUGLOG ("GNUNET_W32NSP_InstallServiceClass\n");
- SetLastError (WSAEOPNOTSUPP);
- return SOCKET_ERROR;
- }
- static int WSAAPI
- GNUNET_W32NSP_RemoveServiceClass (LPGUID lpProviderId, LPGUID lpServiceClassId)
- {
- DEBUGLOG ("GNUNET_W32NSP_RemoveServiceClass\n");
- SetLastError (WSAEOPNOTSUPP);
- return SOCKET_ERROR;
- }
- static int WSAAPI
- GNUNET_W32NSP_GetServiceClassInfo (LPGUID lpProviderId, LPDWORD lpdwBufSize,
- LPWSASERVICECLASSINFOW lpServiceClassInfo)
- {
- DEBUGLOG ("GNUNET_W32NSP_GetServiceClassInfo\n");
- SetLastError (WSAEOPNOTSUPP);
- return SOCKET_ERROR;
- }
- static int WSAAPI
- GNUNET_W32NSP_Ioctl (HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer,
- DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer,
- LPDWORD lpcbBytesReturned, LPWSACOMPLETION lpCompletion,
- LPWSATHREADID lpThreadId)
- {
- DEBUGLOG ("GNUNET_W32NSP_Ioctl\n");
- SetLastError (WSAEOPNOTSUPP);
- return SOCKET_ERROR;
- }
- /**
- * This function is called by Winsock to hook up our provider.
- * It is the only function that [should be/is] exported by the
- * provider. All other routines are passed as pointers in lpnspRoutines.
- */
- int WSAAPI
- GNUNET_W32NSP_NSPStartup (LPGUID lpProviderId, LPNSP_ROUTINE lpnspRoutines)
- {
- if (IsEqualGUID (lpProviderId, &GNUNET_NAMESPACE_PROVIDER_DNS))
- {
- if (!connect_to_dns_resolver ())
- {
- return SOCKET_ERROR;
- }
- /* This assumes that NSP_ROUTINE struct doesn't have a NSPIoctl member.
- * If it does, you need to use FIELD_OFFSET() macro to get offset of NSPIoctl
- * and use that offset as cbSize.
- */
- lpnspRoutines->cbSize = sizeof(NSP_ROUTINE);
- lpnspRoutines->dwMajorVersion = NSPAPI_VERSION_MAJOR;
- lpnspRoutines->dwMinorVersion = NSPAPI_VERSION_MINOR;
- lpnspRoutines->NSPCleanup = NSPCleanup;
- lpnspRoutines->NSPLookupServiceBegin = GNUNET_W32NSP_LookupServiceBegin;
- lpnspRoutines->NSPLookupServiceNext = GNUNET_W32NSP_LookupServiceNext;
- lpnspRoutines->NSPLookupServiceEnd = GNUNET_W32NSP_LookupServiceEnd;
- lpnspRoutines->NSPSetService = GNUNET_W32NSP_SetService;
- lpnspRoutines->NSPInstallServiceClass = GNUNET_W32NSP_InstallServiceClass;
- lpnspRoutines->NSPRemoveServiceClass = GNUNET_W32NSP_RemoveServiceClass;
- lpnspRoutines->NSPGetServiceClassInfo = GNUNET_W32NSP_GetServiceClassInfo;
- /*((NSP_ROUTINE_XP *) lpnspRoutines)->NSPIoctl = GNUNET_W32NSP_Ioctl;*/
- lpnspRoutines->NSPIoctl = GNUNET_W32NSP_Ioctl;
- return NO_ERROR;
- }
- SetLastError (WSAEINVALIDPROVIDER);
- return SOCKET_ERROR;
- }
|