14 #include "mswhelper.h"
16 #define NSP_CALLID_DNS 0x0001
17 #define NSP_CALLID_HOSTNAME 0x0002
18 #define NSP_CALLID_HOSTBYNAME 0x0003
19 #define NSP_CALLID_SERVICEBYNAME 0x0004
24 #ifndef WS2_INTERNAL_MAX_ALIAS
25 #define WS2_INTERNAL_MAX_ALIAS 512
26 #endif // WS2_INTERNAL_MAX_ALIAS
28 //#define IP_LOCALHOST 0x0100007F
30 //#define NSP_REDIRECT
37 CHAR
** servaliasesA
; /* array */
39 } WSHOSTINFOINTERN
, *PWSHOSTINFOINTERN
;
42 GUID providerId
; /* Provider-ID */
43 DWORD dwControlFlags
; /* dwControlFlags (WSALookupServiceBegin) */
44 DWORD CallID
; /* List for LookupServiceNext-Calls */
45 DWORD CallIDCounter
; /* call-count of the current CallID. */
46 WCHAR
* hostnameW
; /* hostbyname */
51 } WSHANDLEINTERN
, *PWSHANDLEINTERN
;
53 static const GUID guid_NULL
= {0};
54 static const GUID guid_HOSTNAME
= SVCID_HOSTNAME
;
55 static const GUID guid_INET_HOSTADDRBYINETSTRING
= SVCID_INET_HOSTADDRBYINETSTRING
;
56 static const GUID guid_INET_HOSTADDRBYNAME
= SVCID_INET_HOSTADDRBYNAME
;
57 static const GUID guid_INET_SERVICEBYNAME
= SVCID_INET_SERVICEBYNAME
;
59 /* GUIDs - maybe they should be loaded from registry? */
61 static const GUID guid_mswsock_TcpIp
= {/*Data1:*/ 0x22059D40,
64 /*Data4:*/ {0xAE, 0x5A, 0x00, 0xAA, 0x00, 0xA7, 0x11, 0x2B}};
66 /* {6642243A-3BA8-4AA6-BAA5-2E0BD71FDD83} */
68 static const GUID guid_mswsock_NLA
= {/*Data1:*/ 0x6642243A,
71 /*Data4:*/ {0xBA, 0xA5, 0x2E, 0x0B, 0xD7, 0x1F, 0xDD, 0x83}};
76 (CALLBACK
*lpRdrNSPStartup
)(
78 LPNSP_ROUTINE lpRout
);
80 const rdrLib
= "mswsock.dll-original";
81 lpRdrNSPStartup rdrNSPStartup
;
83 NSP_ROUTINE rdrproc_tcpip
;
84 NSP_ROUTINE rdrproc_nla
;
86 #endif /* NSP_REDIRECT */
93 LPNSP_ROUTINE lpRout
);
96 NSP_LookupServiceBeginW(
103 NSP_LookupServiceNextW(
104 _In_ PWSHANDLEINTERN data
,
106 _Inout_ LPWSAQUERYSETW lpRes
,
107 _Inout_ LPDWORD lpResLen
);
110 NSP_GetHostNameHeapAllocW(
111 _Out_ WCHAR
** hostname
);
114 NSP_GetHostByNameHeapAllocW(
116 _In_ GUID
* lpProviderId
,
117 _Out_ PWSHOSTINFOINTERN hostinfo
);
120 NSP_GetServiceByNameHeapAllocW(
122 _In_ GUID
* lpProviderId
,
123 _Out_ PWSHOSTINFOINTERN hostinfo
);
125 /* Implementations - Internal */
129 mwsNSPCleanUp(_In_ LPGUID lpProviderId
)
131 //WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED);
132 //return ERROR_CALL_NOT_IMPLEMENTED;
133 return ERROR_SUCCESS
;
139 return ERROR_SUCCESS
;
144 mwsNSPLookupServiceBegin(_In_ LPGUID lpProviderId
,
145 _In_ LPWSAQUERYSETW lpqsRestrictions
,
146 _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo
,
147 _In_ DWORD dwControlFlags
,
148 _Out_ LPHANDLE lphLookup
)
150 PWSHANDLEINTERN pLook
;
153 if (IsEqualGUID(lpProviderId
, &guid_mswsock_TcpIp
))
157 else if (IsEqualGUID(lpProviderId
, &guid_mswsock_NLA
))
159 WSASetLastError(WSASERVICE_NOT_FOUND
);
164 return ERROR_CALL_NOT_IMPLEMENTED
;
167 /* allocate internal structure */
168 pLook
= HeapAlloc(GetProcessHeap(), 0, sizeof(WSHANDLEINTERN
));
171 WSASetLastError(WSAEFAULT
);
175 *lphLookup
= (HANDLE
)pLook
;
177 RtlZeroMemory(pLook
, sizeof(*pLook
));
179 /* Anyway the ControlFlags "should" be needed
180 in NSPLookupServiceNext. (see doku) But
181 thats not the fact ATM. */
182 pLook
->dwControlFlags
= dwControlFlags
;
183 pLook
->providerId
= *lpProviderId
;
187 if (IsEqualGUID(lpProviderId
, &guid_mswsock_TcpIp
))
189 pLook
->rdrproc
= rdrproc_tcpip
;
191 else if (IsEqualGUID(lpProviderId
, &guid_mswsock_NLA
))
193 pLook
->rdrproc
= rdrproc_nla
;
197 return ERROR_CALL_NOT_IMPLEMENTED
;
200 if (pLook
->rdrproc
.NSPLookupServiceBegin(lpProviderId
,
204 &pLook
->rdrLookup
) == NO_ERROR
)
210 wsaErr
= WSAGetLastError();
215 res = WSAGetLastError();
218 #else /* NSP_REDIRECT */
220 wsaErr
= ERROR_CALL_NOT_IMPLEMENTED
;
221 if (IsEqualGUID(lpqsRestrictions
->lpServiceClassId
, &guid_NULL
))
223 wsaErr
= ERROR_CALL_NOT_IMPLEMENTED
;
225 else if (IsEqualGUID(lpqsRestrictions
->lpServiceClassId
, &guid_HOSTNAME
))
227 wsaErr
= NSP_LookupServiceBeginW(pLook
,
230 NSP_CALLID_HOSTNAME
);
232 else if (IsEqualGUID(lpqsRestrictions
->lpServiceClassId
,
233 &guid_INET_HOSTADDRBYNAME
))
235 wsaErr
= NSP_LookupServiceBeginW(pLook
,
237 lpqsRestrictions
->lpszServiceInstanceName
,
238 NSP_CALLID_HOSTBYNAME
);
240 else if (IsEqualGUID(lpqsRestrictions
->lpServiceClassId
,
241 &guid_INET_SERVICEBYNAME
))
243 wsaErr
= NSP_LookupServiceBeginW(pLook
,
245 lpqsRestrictions
->lpszServiceInstanceName
,
246 NSP_CALLID_SERVICEBYNAME
);
248 else if (IsEqualGUID(lpqsRestrictions
->lpServiceClassId
,
249 &guid_INET_HOSTADDRBYINETSTRING
))
251 wsaErr
= ERROR_CALL_NOT_IMPLEMENTED
;
254 #endif /* NSP_REDIRECT */
256 if (wsaErr
!= NO_ERROR
)
258 WSASetLastError(wsaErr
);
266 mwsNSPLookupServiceNext(_In_ HANDLE hLookup
,
267 _In_ DWORD dwControlFlags
,
268 _Inout_ LPDWORD lpdwBufferLength
,
269 //_Out_writes_bytes_to_(*lpdwBufferLength, *lpdwBufferLength)
270 LPWSAQUERYSETW lpqsResults
)
272 PWSHANDLEINTERN pLook
= hLookup
;
277 INT res
= pLook
->rdrproc
.NSPLookupServiceNext(pLook
->rdrLookup
,
281 wsaErr
= WSAGetLastError();
282 if (res
!= ERROR_SUCCESS
)
284 wsaErr
= WSAGetLastError();
290 #else /* NSP_REDIRECT */
292 if ((lpdwBufferLength
== NULL
) || (*lpdwBufferLength
== 0))
294 wsaErr
= WSA_NOT_ENOUGH_MEMORY
;
298 RtlZeroMemory(lpqsResults
, *lpdwBufferLength
);
299 lpqsResults
->dwSize
= sizeof(*lpqsResults
);
301 wsaErr
= NSP_LookupServiceNextW(pLook
,
307 #endif /* NSP_REDIRECT */
312 WSASetLastError(wsaErr
);
320 mwsNSPIoCtl(_In_ HANDLE hLookup
,
321 _In_ DWORD dwControlCode
,
322 _In_reads_bytes_(cbInBuffer
) LPVOID lpvInBuffer
,
323 _In_ DWORD cbInBuffer
,
324 _Out_writes_bytes_to_(cbOutBuffer
, *lpcbBytesReturned
) LPVOID lpvOutBuffer
,
325 _In_ DWORD cbOutBuffer
,
326 _Out_ LPDWORD lpcbBytesReturned
,
327 _In_opt_ LPWSACOMPLETION lpCompletion
,
328 _In_ LPWSATHREADID lpThreadId
)
330 WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
331 return ERROR_CALL_NOT_IMPLEMENTED
;
336 mwsNSPLookupServiceEnd(_In_ HANDLE hLookup
)
338 PWSHANDLEINTERN pLook
;
343 pLook
= (PWSHANDLEINTERN
)hLookup
;
344 hHeap
= GetProcessHeap();
347 res
= pLook
->rdrproc
.NSPLookupServiceEnd(pLook
->rdrLookup
);
350 if (pLook
->hostnameW
!= NULL
)
351 HeapFree(hHeap
, 0, pLook
->hostnameW
);
353 HeapFree(hHeap
, 0, pLook
);
359 mwsNSPSetService(_In_ LPGUID lpProviderId
,
360 _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo
,
361 _In_ LPWSAQUERYSETW lpqsRegInfo
,
362 _In_ WSAESETSERVICEOP essOperation
,
363 _In_ DWORD dwControlFlags
)
365 WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
366 return ERROR_CALL_NOT_IMPLEMENTED
;
371 mwsNSPInstallServiceClass(_In_ LPGUID lpProviderId
,
372 _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo
)
374 WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
375 return ERROR_CALL_NOT_IMPLEMENTED
;
380 mwsNSPRemoveServiceClass(_In_ LPGUID lpProviderId
,
381 _In_ LPGUID lpServiceClassId
)
383 WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
384 return ERROR_CALL_NOT_IMPLEMENTED
;
389 mwsNSPGetServiceClassInfo(_In_ LPGUID lpProviderId
,
390 _In_ LPDWORD lpdwBufSize
,
391 _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo
)
393 WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
394 return ERROR_CALL_NOT_IMPLEMENTED
;
398 hostnameA / hostnameW
399 * only used by HOSTBYNAME
400 * only one should be set
404 NSP_LookupServiceBeginW(PWSHANDLEINTERN data
,
411 if (data
->CallID
!= 0)
414 data
->CallID
= CallID
;
416 if ((CallID
== NSP_CALLID_HOSTBYNAME
) ||
417 (CallID
== NSP_CALLID_SERVICEBYNAME
))
419 hHeap
= GetProcessHeap();
421 if (data
->hostnameW
!= NULL
)
422 HeapFree(hHeap
, 0, data
->hostnameW
);
424 if (hostnameA
!= NULL
)
426 data
->hostnameW
= StrA2WHeapAlloc(hHeap
, hostnameA
);
430 data
->hostnameW
= StrCpyHeapAllocW(hHeap
, hostnameW
);
436 return ERROR_SUCCESS
;
440 NSP_GetHostNameHeapAllocW(_Out_ WCHAR
** hostname
)
443 HANDLE hHeap
= GetProcessHeap();
444 DWORD bufCharLen
= MAX_COMPUTERNAME_LENGTH
+ 1;
445 DWORD bufByteLen
= bufCharLen
* sizeof(WCHAR
);
447 name
= HeapAlloc(hHeap
, 0, bufByteLen
);
449 if (!GetComputerNameExW(ComputerNameDnsHostname
,
453 HeapFree(hHeap
, 0, name
);
454 WSASetLastError(WSAEFAULT
);
459 return ERROR_SUCCESS
;
462 /* This function is far from perfect but it works enough */
464 FindEntryInHosts(IN CONST WCHAR FAR
* wname
)
468 CHAR HostsDBData
[BUFSIZ
] = {0};
469 PCHAR SystemDirectory
= HostsDBData
;
470 PCHAR HostsLocation
= "\\drivers\\etc\\hosts";
471 PCHAR AddressStr
, DnsName
= NULL
, AddrTerm
, NameSt
, NextLine
, ThisLine
, Comment
;
472 UINT SystemDirSize
= sizeof(HostsDBData
) - 1, ValidData
= 0;
475 CHAR name
[MAX_HOSTNAME_LEN
+ 1];
477 wcstombs(name
, wname
, MAX_HOSTNAME_LEN
);
479 /* We assume that the parameters are valid */
480 if (!GetSystemDirectoryA(SystemDirectory
, SystemDirSize
))
482 WSASetLastError(WSANO_RECOVERY
);
483 //WS_DbgPrint(MIN_TRACE, ("Could not get windows system directory.\n"));
484 return 0; /* Can't get system directory */
487 strncat(SystemDirectory
, HostsLocation
, SystemDirSize
);
489 HostsFile
= CreateFileA(SystemDirectory
,
494 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_SEQUENTIAL_SCAN
,
496 if (HostsFile
== INVALID_HANDLE_VALUE
)
498 WSASetLastError(WSANO_RECOVERY
);
502 while (!Found
&& ReadFile(HostsFile
,
503 HostsDBData
+ ValidData
,
504 sizeof(HostsDBData
) - ValidData
,
508 ValidData
+= ReadSize
;
510 NextLine
= ThisLine
= HostsDBData
;
512 /* Find the beginning of the next line */
513 while ((NextLine
< HostsDBData
+ ValidData
) &&
514 (*NextLine
!= '\r') &&
520 /* Zero and skip, so we can treat what we have as a string */
521 if (NextLine
> HostsDBData
+ ValidData
)
527 Comment
= strchr(ThisLine
, '#');
529 *Comment
= 0; /* Terminate at comment start */
531 AddressStr
= ThisLine
;
532 /* Find the first space separating the IP address from the DNS name */
533 AddrTerm
= strchr(ThisLine
, ' ');
536 /* Terminate the address string */
539 /* Find the last space before the DNS name */
540 NameSt
= strrchr(ThisLine
, ' ');
542 /* If there is only one space (the one we removed above), then just use the address terminator */
546 /* Move from the space to the first character of the DNS name */
551 if (!strcmp(name
, DnsName
))
558 /* Get rid of everything we read so far */
559 while (NextLine
<= HostsDBData
+ ValidData
&&
565 if (HostsDBData
+ ValidData
- NextLine
<= 0)
568 //WS_DbgPrint(MAX_TRACE,("About to move %d chars\n",
569 // HostsDBData + ValidData - NextLine));
571 memmove(HostsDBData
, NextLine
, HostsDBData
+ ValidData
- NextLine
);
572 ValidData
-= NextLine
- HostsDBData
;
573 //WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData));
576 CloseHandle(HostsFile
);
580 //WS_DbgPrint(MAX_TRACE,("Not found\n"));
581 WSASetLastError(WSANO_DATA
);
585 if (strstr(AddressStr
, ":"))
587 //DbgPrint("AF_INET6 NOT SUPPORTED!\n");
588 WSASetLastError(WSAEINVAL
);
592 Address
= inet_addr(AddressStr
);
593 if (Address
== INADDR_NONE
)
595 WSASetLastError(WSAEINVAL
);
603 NSP_GetHostByNameHeapAllocW(_In_ WCHAR
* name
,
604 _In_ GUID
* lpProviderId
,
605 _Out_ PWSHOSTINFOINTERN hostinfo
)
607 HANDLE hHeap
= GetProcessHeap();
615 typedef enum addr_type addr_type
;
619 DNS_STATUS dns_status
= {0};
620 /* include/WinDNS.h -- look up DNS_RECORD on MSDN */
626 INT result
= ERROR_SUCCESS
;
628 /* needed to be cleaned up if != NULL */
636 result
= ERROR_INVALID_PARAMETER
;
640 /* Hostname "" / "localhost"
641 - convert to "computername" */
642 if ((wcscmp(L
"", name
) == 0) /*||
643 (wcsicmp(L"localhost", name) == 0)*/)
645 ret
= NSP_GetHostNameHeapAllocW(&tmpHostnameW
);
646 if (ret
!= ERROR_SUCCESS
)
654 /* Is it an IPv6 address? */
655 found
= wcschr(name
, L
':');
662 /* Is it an IPv4 address? */
663 if (!iswalpha(name
[0]))
669 addr
= GH_RFC1123_DNS
;
671 /* Broken out in case we want to get fancy later */
676 WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
677 result
= ERROR_CALL_NOT_IMPLEMENTED
;
682 WSASetLastError(WSAEFAULT
);
683 result
= ERROR_INVALID_PARAMETER
;
687 /* Note: If passed an IP address, MSDN says that gethostbyname()
688 treats it as an unknown host.
689 This is different from the unix implementation. Use inet_addr()
693 /* DNS_TYPE_A: include/WinDNS.h */
694 /* DnsQuery -- lib/dnsapi/dnsapi/query.c */
696 /* Look for the DNS name in the hosts file */
697 if ((address
= FindEntryInHosts(name
)) != 0)
699 hostinfo
->hostnameW
= StrCpyHeapAllocW(hHeap
, name
);
700 hostinfo
->addr4
= address
;
701 result
= ERROR_SUCCESS
;
705 tmpHostnameA
= StrW2AHeapAlloc(hHeap
, name
);
706 dns_status
= DnsQuery(tmpHostnameA
,
709 /* extra dns servers */ 0,
712 HeapFree(hHeap
, 0, tmpHostnameA
);
714 if ((dns_status
!= 0) || (dp
== NULL
))
716 result
= WSAHOST_NOT_FOUND
;
720 //ASSERT(dp->wType == DNS_TYPE_A);
721 //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA));
723 while ((curr
->pNext
!= NULL
) || (curr
->wType
!= DNS_TYPE_A
))
728 if (curr
->wType
!= DNS_TYPE_A
)
730 result
= WSASERVICE_NOT_FOUND
;
734 //WS_DbgPrint(MID_TRACE,("populating hostent\n"));
735 //WS_DbgPrint(MID_TRACE,("pName is (%s)\n", curr->pName));
736 //populate_hostent(p->Hostent,
737 // (PCHAR)curr->pName,
738 // curr->Data.A.IpAddress);
739 hostinfo
->hostnameW
= StrA2WHeapAlloc(hHeap
, curr
->pName
);
740 hostinfo
->addr4
= curr
->Data
.A
.IpAddress
;
741 result
= ERROR_SUCCESS
;
744 //WS_DbgPrint(MID_TRACE,("Called DnsQuery, but host not found. Err: %i\n",
746 //WSASetLastError(WSAHOST_NOT_FOUND);
752 result
= WSANO_RECOVERY
;
757 result
= WSANO_RECOVERY
;
761 DnsRecordListFree(dp
, DnsFreeRecordList
);
763 if (tmpHostnameW
!= NULL
)
764 HeapFree(hHeap
, 0, tmpHostnameW
);
769 #define SKIPWS(ptr, act) \
770 {while(*ptr && isspace(*ptr)) ptr++; if(!*ptr) act;}
772 #define SKIPANDMARKSTR(ptr, act) \
773 {while(*ptr && !isspace(*ptr)) ptr++; \
774 if(!*ptr) {act;} else { *ptr = 0; ptr++; }}
778 DecodeServEntFromString(IN PCHAR ServiceString
,
779 OUT PCHAR
*ServiceName
,
780 OUT PCHAR
*PortNumberStr
,
781 OUT PCHAR
*ProtocolStr
,
787 //WS_DbgPrint(MAX_TRACE, ("Parsing service ent [%s]\n", ServiceString));
789 SKIPWS(ServiceString
, return FALSE
);
790 *ServiceName
= ServiceString
;
791 SKIPANDMARKSTR(ServiceString
, return FALSE
);
792 SKIPWS(ServiceString
, return FALSE
);
793 *PortNumberStr
= ServiceString
;
794 SKIPANDMARKSTR(ServiceString
, ;);
796 while (*ServiceString
&& NAliases
< MaxAlias
- 1)
798 SKIPWS(ServiceString
, break);
801 SKIPWS(ServiceString
, ;);
802 if (strlen(ServiceString
))
804 //WS_DbgPrint(MAX_TRACE, ("Alias: %s\n", ServiceString));
805 *Aliases
++ = ServiceString
;
808 SKIPANDMARKSTR(ServiceString
, ;);
813 *ProtocolStr
= strchr(*PortNumberStr
, '/');
821 //WS_DbgPrint(MAX_TRACE, ("Parsing done: %s %s %s %d\n",
822 // *ServiceName, *ProtocolStr, *PortNumberStr,
829 NSP_GetServiceByNameHeapAllocW(_In_ WCHAR
* nameW
,
830 _In_ GUID
* lpProviderId
,
831 _Out_ PWSHOSTINFOINTERN hostinfo
)
835 CHAR ServiceDBData
[BUFSIZ
* sizeof(WCHAR
)] = {0};
836 PWCHAR SystemDirectory
= (PWCHAR
)ServiceDBData
; /* Reuse this stack space */
837 PWCHAR ServicesFileLocation
= L
"\\drivers\\etc\\services";
838 PCHAR ThisLine
= 0, NextLine
= 0, ServiceName
= 0, PortNumberStr
= 0,
839 ProtocolStr
= 0, Comment
= 0, EndValid
;
840 PCHAR Aliases
[WS2_INTERNAL_MAX_ALIAS
] = {0};
843 SystemDirSize
= (sizeof(ServiceDBData
) / sizeof(WCHAR
)) - 1;
847 PCHAR nameServiceA
= NULL
;
848 PCHAR nameProtoA
= NULL
;
849 INT res
= WSANO_RECOVERY
;
853 res
= WSANO_RECOVERY
;
857 hHeap
= GetProcessHeap();
858 nameA
= StrW2AHeapAlloc(hHeap
, nameW
);
860 /* nameA has the form <service-name>/<protocol>
861 we split these now */
862 nameProtoA
= strchr(nameA
, '/');
863 if (nameProtoA
== NULL
)
865 res
= WSANO_RECOVERY
;
870 i
= (DWORD
)(nameProtoA
- nameA
- 1);
871 nameServiceA
= (PCHAR
)HeapAlloc(hHeap
, 0, i
+ 1);
872 StringCbCopyA(nameServiceA
, i
+ 1, nameA
);
873 nameServiceA
[i
] = '\0';
875 if (!GetSystemDirectoryW(SystemDirectory
, SystemDirSize
))
877 /* Can't get system directory */
878 res
= WSANO_RECOVERY
;
882 wcsncat(SystemDirectory
, ServicesFileLocation
, SystemDirSize
);
884 ServicesFile
= CreateFileW(SystemDirectory
,
889 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_SEQUENTIAL_SCAN
,
892 if (ServicesFile
== INVALID_HANDLE_VALUE
)
894 return WSANO_RECOVERY
;
897 /* Scan the services file ...
899 * We will be share the buffer on the lines. If the line does not fit in
900 * the buffer, then moving it to the beginning of the buffer and read
901 * the remnants of line from file.
905 ReadFile(ServicesFile
,
907 sizeof( ServiceDBData
) - 1,
911 ThisLine
= NextLine
= ServiceDBData
;
912 EndValid
= ServiceDBData
+ ReadSize
;
913 ServiceDBData
[sizeof(ServiceDBData
) - 1] = '\0';
917 for (; *NextLine
!= '\r' && *NextLine
!= '\n'; NextLine
++)
919 if (NextLine
== EndValid
)
921 int LineLen
= NextLine
- ThisLine
;
923 if (ThisLine
== ServiceDBData
)
925 //WS_DbgPrint(MIN_TRACE,("Line too long"));
926 return WSANO_RECOVERY
;
929 memmove(ServiceDBData
, ThisLine
, LineLen
);
931 ReadFile(ServicesFile
,
932 ServiceDBData
+ LineLen
,
933 sizeof( ServiceDBData
)-1 - LineLen
,
937 EndValid
= ServiceDBData
+ LineLen
+ ReadSize
;
938 NextLine
= ServiceDBData
+ LineLen
;
939 ThisLine
= ServiceDBData
;
941 if (!ReadSize
) break;
946 Comment
= strchr(ThisLine
, '#');
949 *Comment
= '\0'; /* Terminate at comment start */
951 if (DecodeServEntFromString(ThisLine
,
956 WS2_INTERNAL_MAX_ALIAS
) &&
957 (strlen(nameProtoA
) == 0 || strcmp(ProtocolStr
, nameProtoA
) == 0))
959 Found
= (strcmp(ServiceName
, nameServiceA
) == 0 || strcmp(PortNumberStr
, nameServiceA
) == 0);
961 while ((!Found
) && (*AliasPtr
!= NULL
))
963 Found
= (strcmp(*AliasPtr
, nameServiceA
) == 0);
973 /* This we'll do no matter what */
974 CloseHandle(ServicesFile
);
982 hostinfo
->servnameW
= StrA2WHeapAlloc(hHeap
, ServiceName
);
983 hostinfo
->servprotoW
= StrA2WHeapAlloc(hHeap
, ProtocolStr
);
984 hostinfo
->servaliasesA
= StrAryCpyHeapAllocA(hHeap
, (char**)&Aliases
);
985 hostinfo
->servport
= atoi(PortNumberStr
);
991 HeapFree(hHeap
, 0, nameA
);
993 if (nameServiceA
!= NULL
)
994 HeapFree(hHeap
, 0, nameServiceA
);
1000 NSP_LookupServiceNextW(_In_ PWSHANDLEINTERN data
,
1002 _Inout_ LPWSAQUERYSETW lpRes
,
1003 _Inout_ LPDWORD lpResLen
)
1006 WSHOSTINFOINTERN hostinfo
;
1008 HANDLE hHeap
= GetProcessHeap();
1009 WCHAR
* ServiceInstanceNameW
= NULL
;
1011 CHAR
* ServiceInstanceNameA
= NULL
;
1012 CHAR
* ServiceProtocolNameA
= NULL
;
1014 RtlZeroMemory(&hostinfo
, sizeof(hostinfo
));
1016 /* init and build result-buffer */
1017 mswBufferInit(&buf
, (BYTE
*)lpRes
, *lpResLen
);
1018 mswBufferIncUsed(&buf
, sizeof(*lpRes
));
1020 /* QueryDataSet-Size without "blob-data"-size! */
1021 lpRes
->dwSize
= sizeof(*lpRes
);
1022 lpRes
->dwNameSpace
= NS_DNS
;
1024 if ((CallID
== NSP_CALLID_HOSTNAME
) ||
1025 (CallID
== NSP_CALLID_HOSTBYNAME
) ||
1026 (CallID
== NSP_CALLID_SERVICEBYNAME
))
1028 if (data
->CallIDCounter
>= 1)
1030 result
= WSAENOMORE
;
1036 result
= WSANO_RECOVERY
;
1039 data
->CallIDCounter
++;
1041 if (CallID
== NSP_CALLID_HOSTNAME
)
1043 result
= NSP_GetHostNameHeapAllocW(&hostinfo
.hostnameW
);
1045 if (result
!= ERROR_SUCCESS
)
1050 else if (CallID
== NSP_CALLID_HOSTBYNAME
)
1052 result
= NSP_GetHostByNameHeapAllocW(data
->hostnameW
,
1055 if (result
!= ERROR_SUCCESS
)
1058 else if (CallID
== NSP_CALLID_SERVICEBYNAME
)
1060 result
= NSP_GetServiceByNameHeapAllocW(data
->hostnameW
,
1063 if (result
!= ERROR_SUCCESS
)
1068 result
= WSANO_RECOVERY
; // Internal error!
1072 if (((LUP_RETURN_BLOB
& data
->dwControlFlags
) != 0) ||
1073 ((LUP_RETURN_NAME
& data
->dwControlFlags
) != 0))
1075 if (CallID
== NSP_CALLID_HOSTNAME
|| CallID
== NSP_CALLID_HOSTBYNAME
)
1077 ServiceInstanceNameW
= hostinfo
.hostnameW
;
1078 ServiceInstanceNameA
= StrW2AHeapAlloc(hHeap
, ServiceInstanceNameW
);
1079 if (ServiceInstanceNameA
== NULL
)
1086 if (CallID
== NSP_CALLID_SERVICEBYNAME
)
1088 ServiceInstanceNameW
= hostinfo
.servnameW
;
1089 ServiceInstanceNameA
= StrW2AHeapAlloc(hHeap
, ServiceInstanceNameW
);
1090 if (ServiceInstanceNameA
== NULL
)
1096 ServiceProtocolNameA
= StrW2AHeapAlloc(hHeap
, hostinfo
.servprotoW
);
1097 if (ServiceProtocolNameA
== NULL
)
1106 if ((LUP_RETURN_ADDR
& data
->dwControlFlags
) != 0)
1108 if (!mswBufferAppendAddr_AddrInfoW(&buf
, lpRes
, hostinfo
.addr4
))
1110 *lpResLen
= buf
.bytesUsed
;
1116 if ((LUP_RETURN_BLOB
& data
->dwControlFlags
) != 0)
1118 if (CallID
== NSP_CALLID_HOSTBYNAME
)
1120 /* Write data for PBLOB (hostent) */
1121 if (!mswBufferAppendBlob_Hostent(&buf
,
1123 ServiceInstanceNameA
,
1126 *lpResLen
= buf
.bytesUsed
;
1131 else if (CallID
== NSP_CALLID_SERVICEBYNAME
)
1133 /* Write data for PBLOB (servent) */
1134 if (!mswBufferAppendBlob_Servent(&buf
,
1136 ServiceInstanceNameA
,/* ServiceName */
1137 hostinfo
.servaliasesA
,
1138 ServiceProtocolNameA
,
1141 *lpResLen
= buf
.bytesUsed
;
1148 result
= WSANO_RECOVERY
;
1153 if ((LUP_RETURN_NAME
& data
->dwControlFlags
) != 0)
1155 /* HostByName sets the ServiceInstanceName to a
1156 (UNICODE)copy of hostent.h_name */
1157 lpRes
->lpszServiceInstanceName
= (LPWSTR
)mswBufferEndPtr(&buf
);
1158 if (!mswBufferAppendStrW(&buf
, ServiceInstanceNameW
))
1160 lpRes
->lpszServiceInstanceName
= NULL
;
1161 *lpResLen
= buf
.bytesUsed
;
1167 *lpResLen
= buf
.bytesUsed
;
1169 result
= ERROR_SUCCESS
;
1172 if (ServiceInstanceNameA
!= NULL
)
1173 HeapFree(hHeap
, 0, ServiceInstanceNameA
);
1175 if (ServiceProtocolNameA
!= NULL
)
1176 HeapFree(hHeap
, 0, ServiceProtocolNameA
);
1178 if (hostinfo
.hostnameW
!= NULL
)
1179 HeapFree(hHeap
, 0, hostinfo
.hostnameW
);
1181 if (hostinfo
.servnameW
!= NULL
)
1182 HeapFree(hHeap
, 0, hostinfo
.servnameW
);
1184 if (hostinfo
.servprotoW
!= NULL
)
1185 HeapFree(hHeap
, 0, hostinfo
.servprotoW
);
1190 /* Implementations - Exports */
1196 NSPStartup(_In_ LPGUID lpProviderId
,
1197 _Out_ LPNSP_ROUTINE lpRout
)
1201 if ((lpRout
== NULL
) ||
1202 (lpRout
->cbSize
!= sizeof(NSP_ROUTINE
)))
1204 WSASetLastError(ERROR_INVALID_PARAMETER
);
1205 return ERROR_INVALID_PARAMETER
;
1210 /* set own Provider GUID - maybe we need
1211 here to set the original mswsock-GUID?! */
1216 - sets cbSize to 44! */
1217 lpRout
->dwMajorVersion
= 1;
1218 lpRout
->dwMinorVersion
= 1;
1219 lpRout
->cbSize
= sizeof(*lpRout
) - sizeof(lpRout
->NSPIoctl
);
1220 lpRout
->NSPCleanup
= &mwsNSPCleanUp
;
1221 lpRout
->NSPLookupServiceBegin
= &mwsNSPLookupServiceBegin
;
1222 lpRout
->NSPLookupServiceNext
= &mwsNSPLookupServiceNext
;
1223 lpRout
->NSPLookupServiceEnd
= &mwsNSPLookupServiceEnd
;
1224 lpRout
->NSPSetService
= &mwsNSPSetService
;
1225 lpRout
->NSPInstallServiceClass
= &mwsNSPInstallServiceClass
;
1226 lpRout
->NSPRemoveServiceClass
= &mwsNSPRemoveServiceClass
;
1227 lpRout
->NSPGetServiceClassInfo
= &mwsNSPGetServiceClassInfo
;
1228 lpRout
->NSPIoctl
= NULL
;// &mwsNSPIoCtl;