15 #include "mswhelper.h"
17 #include <wine/debug.h>
18 WINE_DEFAULT_DEBUG_CHANNEL(mswsock
);
20 #define NSP_CALLID_DNS 0x0001
21 #define NSP_CALLID_HOSTNAME 0x0002
22 #define NSP_CALLID_HOSTBYNAME 0x0003
23 #define NSP_CALLID_SERVICEBYNAME 0x0004
28 #ifndef WS2_INTERNAL_MAX_ALIAS
29 #define WS2_INTERNAL_MAX_ALIAS 512
30 #endif // WS2_INTERNAL_MAX_ALIAS
32 //#define NSP_REDIRECT
39 CHAR
** servaliasesA
; /* array */
41 } WSHOSTINFOINTERN
, *PWSHOSTINFOINTERN
;
44 GUID providerId
; /* Provider-ID */
45 DWORD dwControlFlags
; /* dwControlFlags (WSALookupServiceBegin) */
46 DWORD CallID
; /* List for LookupServiceNext-Calls */
47 DWORD CallIDCounter
; /* call-count of the current CallID. */
48 WCHAR
* hostnameW
; /* hostbyname */
53 } WSHANDLEINTERN
, *PWSHANDLEINTERN
;
55 static const GUID guid_NULL
= {0};
56 static const GUID guid_HOSTNAME
= SVCID_HOSTNAME
;
57 static const GUID guid_INET_HOSTADDRBYINETSTRING
= SVCID_INET_HOSTADDRBYINETSTRING
;
58 static const GUID guid_INET_HOSTADDRBYNAME
= SVCID_INET_HOSTADDRBYNAME
;
59 static const GUID guid_INET_SERVICEBYNAME
= SVCID_INET_SERVICEBYNAME
;
61 /* GUIDs - maybe they should be loaded from registry? */
63 static const GUID guid_mswsock_TcpIp
= {/*Data1:*/ 0x22059D40,
66 /*Data4:*/ {0xAE, 0x5A, 0x00, 0xAA, 0x00, 0xA7, 0x11, 0x2B}};
68 /* {6642243A-3BA8-4AA6-BAA5-2E0BD71FDD83} */
70 static const GUID guid_mswsock_NLA
= {/*Data1:*/ 0x6642243A,
73 /*Data4:*/ {0xBA, 0xA5, 0x2E, 0x0B, 0xD7, 0x1F, 0xDD, 0x83}};
78 (CALLBACK
*lpRdrNSPStartup
)(
80 LPNSP_ROUTINE lpRout
);
82 const rdrLib
= "mswsock.dll-original";
83 lpRdrNSPStartup rdrNSPStartup
;
85 NSP_ROUTINE rdrproc_tcpip
;
86 NSP_ROUTINE rdrproc_nla
;
88 #endif /* NSP_REDIRECT */
90 /* Implementations - Internal */
94 * only used by HOSTBYNAME
95 * only one should be set
99 NSP_LookupServiceBeginW(PWSHANDLEINTERN data
,
106 TRACE("NSP_LookupServiceBeginW %p %p %p %lx\n", data
, hostnameA
, hostnameW
, CallID
);
107 if (data
->CallID
!= 0)
110 data
->CallID
= CallID
;
112 if ((CallID
== NSP_CALLID_HOSTBYNAME
) ||
113 (CallID
== NSP_CALLID_SERVICEBYNAME
))
115 hHeap
= GetProcessHeap();
117 if (data
->hostnameW
!= NULL
)
118 HeapFree(hHeap
, 0, data
->hostnameW
);
120 if (hostnameA
!= NULL
)
122 data
->hostnameW
= StrA2WHeapAlloc(hHeap
, hostnameA
);
126 data
->hostnameW
= StrCpyHeapAllocW(hHeap
, hostnameW
);
131 ERR("NSP_LookupServiceBeginW unsupported CallID\n");
132 WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
133 return ERROR_CALL_NOT_IMPLEMENTED
;
136 return ERROR_SUCCESS
;
140 NSP_GetHostNameHeapAllocW(_Out_ WCHAR
** hostname
)
143 HANDLE hHeap
= GetProcessHeap();
144 DWORD bufCharLen
= 0;
146 TRACE("NSP_GetHostNameHeapAllocW %p\n", hostname
);
147 /* FIXME Use DnsGetHostName_W when available */
148 GetComputerNameExW(ComputerNameDnsHostname
, NULL
, &bufCharLen
);
151 ERR("NSP_GetHostNameHeapAllocW zero size for computername returned\n");
152 WSASetLastError(WSAEFAULT
);
155 name
= HeapAlloc(hHeap
, 0, bufCharLen
*sizeof(WCHAR
));
156 if (!GetComputerNameExW(ComputerNameDnsHostname
,
160 ERR("NSP_GetHostNameHeapAllocW error obtaining computername %lx\n", GetLastError());
161 HeapFree(hHeap
, 0, name
);
162 WSASetLastError(WSAEFAULT
);
167 return ERROR_SUCCESS
;
171 NSP_GetHostByNameHeapAllocW(_In_ PWSHANDLEINTERN data
,
172 _In_ DWORD dwControlFlags
,
173 _Out_ PWSHOSTINFOINTERN hostinfo
)
175 HANDLE hHeap
= GetProcessHeap();
176 DNS_STATUS dns_status
= { 0 };
177 /* include/WinDNS.h -- look up DNS_RECORD on MSDN */
180 INT result
= ERROR_SUCCESS
;
181 DWORD dwQueryFlags
= DNS_QUERY_STANDARD
;
182 PWCHAR Aliases
[WS2_INTERNAL_MAX_ALIAS
] = { 0 };
185 TRACE("NSP_GetHostByNameHeapAllocW %p %lx %p\n", data
, dwControlFlags
, hostinfo
);
186 /* needed to be cleaned up if != NULL */
189 if (!data
->hostnameW
)
191 result
= ERROR_INVALID_PARAMETER
;
195 if ((data
->dwControlFlags
& LUP_DEEP
) == 0)
197 TRACE("NSP_GetHostByNameHeapAllocW LUP_DEEP is not specified. Disabling recursion\n");
198 dwQueryFlags
|= DNS_QUERY_NO_RECURSION
;
201 /* DNS_TYPE_A: include/WinDNS.h */
202 /* DnsQuery -- lib/dnsapi/dnsapi/query.c */
203 dns_status
= DnsQuery_W(data
->hostnameW
,
206 NULL
/* extra dns servers */,
209 if (dns_status
== ERROR_INVALID_NAME
)
211 ERR("NSP_GetHostByNameHeapAllocW invalid name\n");
212 WSASetLastError(WSAEFAULT
);
213 result
= ERROR_INVALID_PARAMETER
;
217 if ((dns_status
!= 0) || (dp
== NULL
))
219 ERR("NSP_GetHostByNameHeapAllocW not found %lx %p\n", dns_status
, dp
);
220 result
= WSAHOST_NOT_FOUND
;
224 //ASSERT(dp->wType == DNS_TYPE_A);
225 //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA));
227 while ((curr
->pNext
!= NULL
) || (curr
->wType
!= DNS_TYPE_A
))
229 if (curr
->wType
== DNS_TYPE_CNAME
)
231 TRACE("NSP_GetHostByNameHeapAllocW found alias %ws\n", curr
->Data
.Cname
.pNameHost
);
232 Aliases
[AliasIndex
++] = curr
->Data
.Cname
.pNameHost
;
237 if (curr
->wType
!= DNS_TYPE_A
)
239 ERR("NSP_GetHostByNameHeapAllocW last record is not of type A %d\n", curr
->wType
);
240 result
= WSASERVICE_NOT_FOUND
;
243 hostinfo
->hostnameW
= StrCpyHeapAllocW(hHeap
, curr
->pName
);
244 hostinfo
->addr4
= curr
->Data
.A
.IpAddress
;
247 hostinfo
->servaliasesA
= StrAryCpyHeapAllocWToA(hHeap
, (WCHAR
**)&Aliases
);
249 result
= ERROR_SUCCESS
;
253 DnsRecordListFree(dp
, DnsFreeRecordList
);
258 #define SKIPWS(ptr, act) \
259 {while(*ptr && isspace(*ptr)) ptr++; if(!*ptr) act;}
261 #define SKIPANDMARKSTR(ptr, act) \
262 {while(*ptr && !isspace(*ptr)) ptr++; \
263 if(!*ptr) {act;} else { *ptr = 0; ptr++; }}
267 DecodeServEntFromString(IN PCHAR ServiceString
,
268 OUT PCHAR
*ServiceName
,
269 OUT PCHAR
*PortNumberStr
,
270 OUT PCHAR
*ProtocolStr
,
276 //WS_DbgPrint(MAX_TRACE, ("Parsing service ent [%s]\n", ServiceString));
278 SKIPWS(ServiceString
, return FALSE
);
279 *ServiceName
= ServiceString
;
280 SKIPANDMARKSTR(ServiceString
, return FALSE
);
281 SKIPWS(ServiceString
, return FALSE
);
282 *PortNumberStr
= ServiceString
;
283 SKIPANDMARKSTR(ServiceString
, ;);
285 while (*ServiceString
&& NAliases
< MaxAlias
- 1)
287 SKIPWS(ServiceString
, break);
290 SKIPWS(ServiceString
, ;);
291 if (strlen(ServiceString
))
293 //WS_DbgPrint(MAX_TRACE, ("Alias: %s\n", ServiceString));
294 *Aliases
++ = ServiceString
;
297 SKIPANDMARKSTR(ServiceString
, ;);
302 *ProtocolStr
= strchr(*PortNumberStr
, '/');
310 //WS_DbgPrint(MAX_TRACE, ("Parsing done: %s %s %s %d\n",
311 // *ServiceName, *ProtocolStr, *PortNumberStr,
319 OpenNetworkDatabase(_In_ LPCWSTR Name
)
330 TRACE("OpenNetworkDatabase %p\n", Name
);
331 ExpandedPath
= HeapAlloc(GetProcessHeap(), 0, MAX_PATH
*sizeof(WCHAR
));
333 return INVALID_HANDLE_VALUE
;
335 /* Open the database path key */
336 ErrorCode
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
337 L
"System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
341 if (ErrorCode
== NO_ERROR
)
343 TRACE("OpenNetworkDatabase registry key for network database exist\n");
344 /* Read the actual path */
345 ErrorCode
= RegQueryValueEx(DatabaseKey
,
354 ERR("OpenNetworkDatabase RegQueryValueEx failed to return size for DatabasePath %lx\n", ErrorCode
);
355 RegCloseKey(DatabaseKey
);
356 HeapFree(GetProcessHeap(), 0, ExpandedPath
);
357 return INVALID_HANDLE_VALUE
;
359 DatabasePath
= HeapAlloc(GetProcessHeap(), 0, RegSize
);
362 ERR("OpenNetworkDatabase could not allocate %d for DatabasePath\n", RegSize
);
363 RegCloseKey(DatabaseKey
);
364 HeapFree(GetProcessHeap(), 0, ExpandedPath
);
365 return INVALID_HANDLE_VALUE
;
368 /* Read the actual path */
369 ErrorCode
= RegQueryValueEx(DatabaseKey
,
373 (LPBYTE
)DatabasePath
,
377 RegCloseKey(DatabaseKey
);
381 ERR("OpenNetworkDatabase RegQueryValueEx failed to return value for DatabasePath %lx\n", ErrorCode
);
382 HeapFree(GetProcessHeap(), 0, DatabasePath
);
383 HeapFree(GetProcessHeap(), 0, ExpandedPath
);
384 return INVALID_HANDLE_VALUE
;
387 /* Expand the name */
388 ExpandEnvironmentStrings(DatabasePath
, ExpandedPath
, MAX_PATH
);
390 HeapFree(GetProcessHeap(), 0, DatabasePath
);
394 TRACE("OpenNetworkDatabase registry key for network database doesn't exist\n");
395 /* Use defalt path */
396 GetSystemDirectory(ExpandedPath
, MAX_PATH
);
397 StringCchLength(ExpandedPath
, MAX_PATH
, &StringLength
);
398 if (ExpandedPath
[StringLength
- 1] != L
'\\')
400 /* It isn't, so add it ourselves */
401 StringCchCat(ExpandedPath
, MAX_PATH
, L
"\\");
403 StringCchCat(ExpandedPath
, MAX_PATH
, L
"DRIVERS\\ETC\\");
406 /* Make sure that the path is backslash-terminated */
407 StringCchLength(ExpandedPath
, MAX_PATH
, &StringLength
);
408 if (ExpandedPath
[StringLength
- 1] != L
'\\')
410 /* It isn't, so add it ourselves */
411 StringCchCat(ExpandedPath
, MAX_PATH
, L
"\\");
414 /* Add the database name */
415 StringCchCat(ExpandedPath
, MAX_PATH
, Name
);
417 /* Return a handle to the file */
418 Handle
= CreateFile(ExpandedPath
,
423 FILE_ATTRIBUTE_NORMAL
,
426 HeapFree(GetProcessHeap(), 0, ExpandedPath
);
431 NSP_GetServiceByNameHeapAllocW(_In_ PWSHANDLEINTERN data
,
432 _In_ DWORD dwControlFlags
,
433 _Out_ PWSHOSTINFOINTERN hostinfo
)
437 CHAR ServiceDBData
[BUFSIZ
* sizeof(WCHAR
)] = { 0 };
438 PCHAR ThisLine
= 0, NextLine
= 0, ServiceName
= 0, PortNumberStr
= 0,
439 ProtocolStr
= 0, Comment
= 0, EndValid
;
440 PCHAR Aliases
[WS2_INTERNAL_MAX_ALIAS
] = { 0 };
446 PCHAR nameServiceA
= NULL
;
447 PCHAR nameProtoA
= NULL
;
448 INT res
= WSANO_RECOVERY
;
450 TRACE("NSP_GetServiceByNameHeapAllocW %p %lx %p\n", data
, dwControlFlags
, hostinfo
);
451 if (!data
->hostnameW
)
453 ERR("NSP_GetServiceByNameHeapAllocW service name not provided\n");
454 res
= WSANO_RECOVERY
;
458 hHeap
= GetProcessHeap();
459 nameA
= StrW2AHeapAlloc(hHeap
, data
->hostnameW
);
461 /* nameA has the form <service-name>/<protocol>
462 we split these now */
463 nameProtoA
= strchr(nameA
, '/');
464 if (nameProtoA
== NULL
)
466 ERR("NSP_GetServiceByNameHeapAllocW invalid service name %s\n", nameA
);
467 res
= WSANO_RECOVERY
;
472 i
= (DWORD
)(nameProtoA
- nameA
- 1);
473 nameServiceA
= (PCHAR
)HeapAlloc(hHeap
, 0, i
+ 1);
474 StringCbCopyA(nameServiceA
, i
+ 1, nameA
);
475 nameServiceA
[i
] = '\0';
477 ServicesFile
= OpenNetworkDatabase(L
"services");
478 if (ServicesFile
== INVALID_HANDLE_VALUE
)
480 ERR("NSP_GetServiceByNameHeapAllocW unable to open services file\n");
481 return WSANO_RECOVERY
;
484 /* Scan the services file ...
486 * We will be share the buffer on the lines. If the line does not fit in
487 * the buffer, then moving it to the beginning of the buffer and read
488 * the remnants of line from file.
492 if (!ReadFile(ServicesFile
,
494 sizeof( ServiceDBData
) - 1,
498 ERR("NSP_GetServiceByNameHeapAllocW can't read services file %lx\n", GetLastError());
499 CloseHandle(ServicesFile
);
500 return WSANO_RECOVERY
;
503 ThisLine
= NextLine
= ServiceDBData
;
504 EndValid
= ServiceDBData
+ ReadSize
;
505 ServiceDBData
[sizeof(ServiceDBData
) - 1] = '\0';
509 for (; *NextLine
!= '\r' && *NextLine
!= '\n'; NextLine
++)
511 if (NextLine
== EndValid
)
513 int LineLen
= NextLine
- ThisLine
;
515 if (ThisLine
== ServiceDBData
)
517 ERR("NSP_GetServiceByNameHeapAllocW line too long\n");
518 CloseHandle(ServicesFile
);
519 return WSANO_RECOVERY
;
522 memmove(ServiceDBData
, ThisLine
, LineLen
);
524 if (!ReadFile(ServicesFile
,
525 ServiceDBData
+ LineLen
,
526 sizeof( ServiceDBData
)-1 - LineLen
,
533 EndValid
= ServiceDBData
+ LineLen
+ ReadSize
;
534 NextLine
= ServiceDBData
+ LineLen
;
535 ThisLine
= ServiceDBData
;
537 if (!ReadSize
) break;
542 Comment
= strchr(ThisLine
, '#');
545 *Comment
= '\0'; /* Terminate at comment start */
547 if (DecodeServEntFromString(ThisLine
,
552 WS2_INTERNAL_MAX_ALIAS
) &&
553 (strlen(nameProtoA
) == 0 || strcmp(ProtocolStr
, nameProtoA
) == 0))
555 Found
= (strcmp(ServiceName
, nameServiceA
) == 0 || strcmp(PortNumberStr
, nameServiceA
) == 0);
557 while ((!Found
) && (*AliasPtr
!= NULL
))
559 Found
= (strcmp(*AliasPtr
, nameServiceA
) == 0);
569 /* This we'll do no matter what */
570 CloseHandle(ServicesFile
);
574 ERR("NSP_GetServiceByNameHeapAllocW service not found\n");
579 hostinfo
->servnameW
= StrA2WHeapAlloc(hHeap
, ServiceName
);
580 hostinfo
->servprotoW
= StrA2WHeapAlloc(hHeap
, ProtocolStr
);
581 hostinfo
->servaliasesA
= StrAryCpyHeapAllocA(hHeap
, (char**)&Aliases
);
582 hostinfo
->servport
= atoi(PortNumberStr
);
588 HeapFree(hHeap
, 0, nameA
);
591 HeapFree(hHeap
, 0, nameServiceA
);
597 NSP_LookupServiceNextW(_In_ PWSHANDLEINTERN data
,
598 _In_ DWORD dwControlFlags
,
599 _Inout_ LPWSAQUERYSETW lpRes
,
600 _Inout_ LPDWORD lpResLen
)
603 WSHOSTINFOINTERN hostinfo
;
605 HANDLE hHeap
= GetProcessHeap();
606 WCHAR
* ServiceInstanceNameW
= NULL
;
608 CHAR
* ServiceInstanceNameA
= NULL
;
609 CHAR
* ServiceProtocolNameA
= NULL
;
611 TRACE("NSP_LookupServiceNextW %p %lx %p %p\n", data
, dwControlFlags
, lpRes
, lpResLen
);
612 if (!data
|| (dwControlFlags
& (~(DWORD
)LUP_FLUSHPREVIOUS
)) != 0 || !lpRes
|| !lpResLen
|| *lpResLen
== 0)
614 RtlZeroMemory(&hostinfo
, sizeof(hostinfo
));
616 /* init and build result-buffer */
617 mswBufferInit(&buf
, (BYTE
*)lpRes
, *lpResLen
);
618 mswBufferIncUsed(&buf
, sizeof(*lpRes
));
620 /* QueryDataSet-Size without "blob-data"-size! */
621 lpRes
->dwSize
= sizeof(*lpRes
);
622 lpRes
->dwNameSpace
= NS_DNS
;
624 if ((data
->CallID
== NSP_CALLID_HOSTNAME
) ||
625 (data
->CallID
== NSP_CALLID_HOSTBYNAME
) ||
626 (data
->CallID
== NSP_CALLID_SERVICEBYNAME
))
628 /* FIXME remember what was returned and continue from there */
629 if (data
->CallIDCounter
>= 1)
631 ERR("NSP_LookupServiceNextW LUP_FLUSHPREVIOUS and more than one call not supported yet\n", data
, dwControlFlags
, lpRes
, lpResLen
);
632 result
= WSA_E_NO_MORE
;
638 ERR("NSP_LookupServiceNextW unsupported CallID %lx\n", data
->CallID
);
639 result
= WSAEOPNOTSUPP
;
642 data
->CallIDCounter
++;
644 if (data
->CallID
== NSP_CALLID_HOSTNAME
)
646 result
= NSP_GetHostNameHeapAllocW(&hostinfo
.hostnameW
);
648 if (result
!= ERROR_SUCCESS
)
653 else if (data
->CallID
== NSP_CALLID_HOSTBYNAME
)
655 result
= NSP_GetHostByNameHeapAllocW(data
,
658 if (result
!= ERROR_SUCCESS
)
663 //ASSERT(data->CallID == NSP_CALLID_SERVICEBYNAME);
664 result
= NSP_GetServiceByNameHeapAllocW(data
,
667 if (result
!= ERROR_SUCCESS
)
671 if (((LUP_RETURN_BLOB
& data
->dwControlFlags
) != 0) ||
672 ((LUP_RETURN_NAME
& data
->dwControlFlags
) != 0))
674 if (data
->CallID
== NSP_CALLID_HOSTNAME
|| data
->CallID
== NSP_CALLID_HOSTBYNAME
)
676 ServiceInstanceNameW
= hostinfo
.hostnameW
;
677 ServiceInstanceNameA
= StrW2AHeapAlloc(hHeap
, ServiceInstanceNameW
);
678 if (!ServiceInstanceNameA
)
680 ERR("NSP_LookupServiceNextW not enough memory\n");
681 result
= WSA_NOT_ENOUGH_MEMORY
;
685 if (data
->CallID
== NSP_CALLID_SERVICEBYNAME
)
687 ServiceInstanceNameW
= hostinfo
.servnameW
;
688 ServiceInstanceNameA
= StrW2AHeapAlloc(hHeap
, ServiceInstanceNameW
);
689 if (!ServiceInstanceNameA
)
691 ERR("NSP_LookupServiceNextW not enough memory\n");
692 result
= WSA_NOT_ENOUGH_MEMORY
;
695 ServiceProtocolNameA
= StrW2AHeapAlloc(hHeap
, hostinfo
.servprotoW
);
696 if (!ServiceProtocolNameA
)
698 ERR("NSP_LookupServiceNextW not enough memory\n");
699 result
= WSA_NOT_ENOUGH_MEMORY
;
705 if ((LUP_RETURN_ADDR
& data
->dwControlFlags
) != 0)
707 if (!mswBufferAppendAddr_AddrInfoW(&buf
, lpRes
, hostinfo
.addr4
))
709 ERR("NSP_LookupServiceNextW provided buffer is too small\n");
710 *lpResLen
= buf
.bytesUsed
;
716 if ((LUP_RETURN_BLOB
& data
->dwControlFlags
) != 0)
718 if (data
->CallID
== NSP_CALLID_HOSTBYNAME
)
720 /* Write data for PBLOB (hostent) */
721 if (!mswBufferAppendBlob_Hostent(&buf
,
723 (LUP_RETURN_ALIASES
& data
->dwControlFlags
) != 0 ? hostinfo
.servaliasesA
: NULL
,
724 ServiceInstanceNameA
,
727 ERR("NSP_LookupServiceNextW provided buffer is too small\n");
728 *lpResLen
= buf
.bytesUsed
;
733 else if (data
->CallID
== NSP_CALLID_SERVICEBYNAME
)
735 /* Write data for PBLOB (servent) */
736 if (!mswBufferAppendBlob_Servent(&buf
,
738 ServiceInstanceNameA
,/* ServiceName */
739 (LUP_RETURN_ALIASES
& data
->dwControlFlags
) != 0 ? hostinfo
.servaliasesA
: NULL
,
740 ServiceProtocolNameA
,
743 ERR("NSP_LookupServiceNextW provided buffer is too small\n");
744 *lpResLen
= buf
.bytesUsed
;
751 ERR("NSP_LookupServiceNextW LUP_RETURN_BLOB is supported only for NSP_CALLID_HOSTBYNAME and NSP_CALLID_SERVICEBYNAME\n");
757 if ((LUP_RETURN_NAME
& data
->dwControlFlags
) != 0)
759 /* HostByName sets the ServiceInstanceName to a
760 (UNICODE)copy of hostent.h_name */
761 lpRes
->lpszServiceInstanceName
= (LPWSTR
)mswBufferEndPtr(&buf
);
762 if (!mswBufferAppendStrW(&buf
, ServiceInstanceNameW
))
764 ERR("NSP_LookupServiceNextW provided buffer is too small\n");
765 lpRes
->lpszServiceInstanceName
= NULL
;
766 *lpResLen
= buf
.bytesUsed
;
772 *lpResLen
= buf
.bytesUsed
;
774 result
= ERROR_SUCCESS
;
777 if (ServiceInstanceNameA
!= NULL
)
778 HeapFree(hHeap
, 0, ServiceInstanceNameA
);
780 if (ServiceProtocolNameA
!= NULL
)
781 HeapFree(hHeap
, 0, ServiceProtocolNameA
);
783 if (hostinfo
.hostnameW
!= NULL
)
784 HeapFree(hHeap
, 0, hostinfo
.hostnameW
);
786 if (hostinfo
.servnameW
!= NULL
)
787 HeapFree(hHeap
, 0, hostinfo
.servnameW
);
789 if (hostinfo
.servprotoW
!= NULL
)
790 HeapFree(hHeap
, 0, hostinfo
.servprotoW
);
792 TRACE("NSP_LookupServiceNextW returns %d needed bytes %ld\n", result
, buf
.bytesUsed
);
798 mwsNSPCleanUp(_In_ LPGUID lpProviderId
)
800 return ERROR_SUCCESS
;
806 return ERROR_SUCCESS
;
811 mwsNSPLookupServiceBegin(_In_ LPGUID lpProviderId
,
812 _In_ LPWSAQUERYSETW lpqsRestrictions
,
813 _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo
,
814 _In_ DWORD dwControlFlags
,
815 _Out_ LPHANDLE lphLookup
)
817 PWSHANDLEINTERN pLook
;
820 TRACE("mwsNSPLookupServiceBegin %p %p %p %lx %p\n", lpProviderId
, lpqsRestrictions
, lpServiceClassInfo
, dwControlFlags
, lphLookup
);
821 if (IsEqualGUID(lpProviderId
, &guid_mswsock_TcpIp
))
824 TRACE("TCPIP query\n");
826 else if (IsEqualGUID(lpProviderId
, &guid_mswsock_NLA
))
828 ERR("NLA queries are not supported yet\n");
829 WSASetLastError(WSASERVICE_NOT_FOUND
);
834 ERR("Unsupported GUID\n");
835 return ERROR_CALL_NOT_IMPLEMENTED
;
838 /* allocate internal structure */
839 pLook
= HeapAlloc(GetProcessHeap(), 0, sizeof(WSHANDLEINTERN
));
842 ERR("Error allocating %d for handle\n", sizeof(WSHANDLEINTERN
));
843 WSASetLastError(WSAEFAULT
);
847 *lphLookup
= (HANDLE
)pLook
;
849 RtlZeroMemory(pLook
, sizeof(*pLook
));
851 /* Anyway the ControlFlags "should" be needed
852 in NSPLookupServiceNext. (see doku) But
853 thats not the fact ATM. */
854 pLook
->dwControlFlags
= dwControlFlags
;
855 pLook
->providerId
= *lpProviderId
;
859 if (IsEqualGUID(lpProviderId
, &guid_mswsock_TcpIp
))
861 pLook
->rdrproc
= rdrproc_tcpip
;
863 else if (IsEqualGUID(lpProviderId
, &guid_mswsock_NLA
))
865 pLook
->rdrproc
= rdrproc_nla
;
869 return ERROR_CALL_NOT_IMPLEMENTED
;
872 if (pLook
->rdrproc
.NSPLookupServiceBegin(lpProviderId
,
876 &pLook
->rdrLookup
) == NO_ERROR
)
882 wsaErr
= WSAGetLastError();
887 res = WSAGetLastError();
890 #else /* NSP_REDIRECT */
892 wsaErr
= ERROR_CALL_NOT_IMPLEMENTED
;
893 if (IsEqualGUID(lpqsRestrictions
->lpServiceClassId
, &guid_NULL
))
895 ERR("NULL GUID service class is not implemented yet\n");
896 wsaErr
= ERROR_CALL_NOT_IMPLEMENTED
;
898 else if (IsEqualGUID(lpqsRestrictions
->lpServiceClassId
, &guid_HOSTNAME
))
900 TRACE("HOSTNAME GUID\n");
901 wsaErr
= NSP_LookupServiceBeginW(pLook
,
904 NSP_CALLID_HOSTNAME
);
906 else if (IsEqualGUID(lpqsRestrictions
->lpServiceClassId
,
907 &guid_INET_HOSTADDRBYNAME
))
909 TRACE("INET_HOSTADDRBYNAME GUID\n");
910 wsaErr
= NSP_LookupServiceBeginW(pLook
,
912 lpqsRestrictions
->lpszServiceInstanceName
,
913 NSP_CALLID_HOSTBYNAME
);
915 else if (IsEqualGUID(lpqsRestrictions
->lpServiceClassId
,
916 &guid_INET_SERVICEBYNAME
))
918 TRACE("INET_SERVICEBYNAME\n");
919 wsaErr
= NSP_LookupServiceBeginW(pLook
,
921 lpqsRestrictions
->lpszServiceInstanceName
,
922 NSP_CALLID_SERVICEBYNAME
);
924 else if (IsEqualGUID(lpqsRestrictions
->lpServiceClassId
,
925 &guid_INET_HOSTADDRBYINETSTRING
))
927 ERR("INET_HOSTADDRBYINETSTRING GUID service class is not implemented yet\n");
928 wsaErr
= ERROR_CALL_NOT_IMPLEMENTED
;
931 #endif /* NSP_REDIRECT */
933 if (wsaErr
!= NO_ERROR
)
935 ERR("mwsNSPLookupServiceBegin wsaErr = %d\n", wsaErr
);
936 WSASetLastError(wsaErr
);
944 mwsNSPLookupServiceNext(_In_ HANDLE hLookup
,
945 _In_ DWORD dwControlFlags
,
946 _Inout_ LPDWORD lpdwBufferLength
,
947 //_Out_writes_bytes_to_(*lpdwBufferLength, *lpdwBufferLength)
948 LPWSAQUERYSETW lpqsResults
)
950 PWSHANDLEINTERN pLook
= hLookup
;
953 TRACE("mwsNSPLookupServiceNext %p %lx %p %p\n", pLook
, dwControlFlags
, lpdwBufferLength
, lpqsResults
);
956 INT res
= pLook
->rdrproc
.NSPLookupServiceNext(pLook
->rdrLookup
,
960 wsaErr
= WSAGetLastError();
961 if (res
!= ERROR_SUCCESS
)
963 wsaErr
= WSAGetLastError();
969 #else /* NSP_REDIRECT */
971 if ((lpdwBufferLength
== NULL
) || (*lpdwBufferLength
== 0))
973 wsaErr
= WSA_NOT_ENOUGH_MEMORY
;
977 RtlZeroMemory(lpqsResults
, *lpdwBufferLength
);
978 lpqsResults
->dwSize
= sizeof(*lpqsResults
);
980 wsaErr
= NSP_LookupServiceNextW(pLook
,
986 #endif /* NSP_REDIRECT */
991 ERR("mwsNSPLookupServiceNext wsaErr = %d\n", wsaErr
);
992 WSASetLastError(wsaErr
);
1000 mwsNSPIoCtl(_In_ HANDLE hLookup
,
1001 _In_ DWORD dwControlCode
,
1002 _In_reads_bytes_(cbInBuffer
) LPVOID lpvInBuffer
,
1003 _In_ DWORD cbInBuffer
,
1004 _Out_writes_bytes_to_(cbOutBuffer
, *lpcbBytesReturned
) LPVOID lpvOutBuffer
,
1005 _In_ DWORD cbOutBuffer
,
1006 _Out_ LPDWORD lpcbBytesReturned
,
1007 _In_opt_ LPWSACOMPLETION lpCompletion
,
1008 _In_ LPWSATHREADID lpThreadId
)
1010 ERR("mwsNSPIoCtl not implemented %p %lx %p %ld %p %ld %p %p %p\n", hLookup
, dwControlCode
, lpvInBuffer
, cbInBuffer
, lpvOutBuffer
, cbOutBuffer
, lpcbBytesReturned
, lpCompletion
, lpThreadId
);
1011 WSASetLastError(WSAEOPNOTSUPP
);
1012 return ERROR_CALL_NOT_IMPLEMENTED
;
1017 mwsNSPLookupServiceEnd(_In_ HANDLE hLookup
)
1019 PWSHANDLEINTERN pLook
= (PWSHANDLEINTERN
)hLookup
;
1020 HANDLE hHeap
= GetProcessHeap();
1023 TRACE("mwsNSPLookupServiceEnd %p\n", pLook
);
1025 res
= pLook
->rdrproc
.NSPLookupServiceEnd(pLook
->rdrLookup
);
1028 if (pLook
->hostnameW
!= NULL
)
1029 HeapFree(hHeap
, 0, pLook
->hostnameW
);
1031 HeapFree(hHeap
, 0, pLook
);
1037 mwsNSPSetService(_In_ LPGUID lpProviderId
,
1038 _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo
,
1039 _In_ LPWSAQUERYSETW lpqsRegInfo
,
1040 _In_ WSAESETSERVICEOP essOperation
,
1041 _In_ DWORD dwControlFlags
)
1043 ERR("mwsNSPSetService not implemented %p %p %p %d %lx %ld %p %p %p\n", lpProviderId
, lpServiceClassInfo
, lpqsRegInfo
, essOperation
, dwControlFlags
);
1044 WSASetLastError(WSAEOPNOTSUPP
);
1045 return ERROR_CALL_NOT_IMPLEMENTED
;
1050 mwsNSPInstallServiceClass(_In_ LPGUID lpProviderId
,
1051 _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo
)
1053 ERR("mwsNSPInstallServiceClass not implemented %p %p\n", lpProviderId
, lpServiceClassInfo
);
1054 WSASetLastError(WSAEOPNOTSUPP
);
1055 return ERROR_CALL_NOT_IMPLEMENTED
;
1060 mwsNSPRemoveServiceClass(_In_ LPGUID lpProviderId
,
1061 _In_ LPGUID lpServiceClassId
)
1063 ERR("mwsNSPRemoveServiceClass not implemented %p %p\n", lpProviderId
, lpServiceClassId
);
1064 WSASetLastError(WSAEOPNOTSUPP
);
1065 return ERROR_CALL_NOT_IMPLEMENTED
;
1070 mwsNSPGetServiceClassInfo(_In_ LPGUID lpProviderId
,
1071 _In_ LPDWORD lpdwBufSize
,
1072 _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo
)
1074 ERR("mwsNSPGetServiceClassInfo not implemented %p %p %p\n", lpProviderId
, lpdwBufSize
, lpServiceClassInfo
);
1075 WSASetLastError(WSAEOPNOTSUPP
);
1076 return ERROR_CALL_NOT_IMPLEMENTED
;
1079 /* Implementations - Exports */
1085 NSPStartup(_In_ LPGUID lpProviderId
,
1086 _Out_ LPNSP_ROUTINE lpRout
)
1090 TRACE("NSPStartup %p %p\n", lpProviderId
, lpRout
);
1091 if (!lpRout
|| (lpRout
->cbSize
!= sizeof(NSP_ROUTINE
)))
1093 ERR("NSPStartup invalid parameter\n");
1094 WSASetLastError(WSAEINVAL
);
1095 return ERROR_INVALID_PARAMETER
;
1100 /* set own Provider GUID - maybe we need
1101 here to set the original mswsock-GUID?! */
1106 - sets cbSize to 44! */
1107 lpRout
->dwMajorVersion
= 1;
1108 lpRout
->dwMinorVersion
= 1;
1109 lpRout
->cbSize
= sizeof(*lpRout
) - sizeof(lpRout
->NSPIoctl
);
1110 lpRout
->NSPCleanup
= &mwsNSPCleanUp
;
1111 lpRout
->NSPLookupServiceBegin
= &mwsNSPLookupServiceBegin
;
1112 lpRout
->NSPLookupServiceNext
= &mwsNSPLookupServiceNext
;
1113 lpRout
->NSPLookupServiceEnd
= &mwsNSPLookupServiceEnd
;
1114 lpRout
->NSPSetService
= &mwsNSPSetService
;
1115 lpRout
->NSPInstallServiceClass
= &mwsNSPInstallServiceClass
;
1116 lpRout
->NSPRemoveServiceClass
= &mwsNSPRemoveServiceClass
;
1117 lpRout
->NSPGetServiceClassInfo
= &mwsNSPGetServiceClassInfo
;
1118 lpRout
->NSPIoctl
= NULL
;// &mwsNSPIoCtl;