From a59bc8597f2335de3dc16a51d41e7518b7561c40 Mon Sep 17 00:00:00 2001 From: Peter Hater <7element@mail.bg> Date: Fri, 2 Jun 2017 21:57:37 +0000 Subject: [PATCH] [MSWSOCK] Rearrange the function places to avoid forward declarations and code formatting svn path=/trunk/; revision=74755 --- reactos/dll/win32/mswsock/nsplookup.c | 1527 ++++++++++++------------- 1 file changed, 743 insertions(+), 784 deletions(-) diff --git a/reactos/dll/win32/mswsock/nsplookup.c b/reactos/dll/win32/mswsock/nsplookup.c index 24d41740565..e86f4d4f5df 100644 --- a/reactos/dll/win32/mswsock/nsplookup.c +++ b/reactos/dll/win32/mswsock/nsplookup.c @@ -23,34 +23,32 @@ WINE_DEFAULT_DEBUG_CHANNEL(mswsock); #define NSP_CALLID_SERVICEBYNAME 0x0004 #ifndef BUFSIZ -#define BUFSIZ 1024 + #define BUFSIZ 1024 #endif // BUFSIZ #ifndef WS2_INTERNAL_MAX_ALIAS -#define WS2_INTERNAL_MAX_ALIAS 512 + #define WS2_INTERNAL_MAX_ALIAS 512 #endif // WS2_INTERNAL_MAX_ALIAS -//#define IP_LOCALHOST 0x0100007F - //#define NSP_REDIRECT typedef struct { - WCHAR* hostnameW; - DWORD addr4; - WCHAR* servnameW; - WCHAR* servprotoW; - CHAR** servaliasesA; /* array */ - WORD servport; + WCHAR* hostnameW; + DWORD addr4; + WCHAR* servnameW; + WCHAR* servprotoW; + CHAR** servaliasesA; /* array */ + WORD servport; } WSHOSTINFOINTERN, *PWSHOSTINFOINTERN; typedef struct { - GUID providerId; /* Provider-ID */ - DWORD dwControlFlags; /* dwControlFlags (WSALookupServiceBegin) */ - DWORD CallID; /* List for LookupServiceNext-Calls */ - DWORD CallIDCounter; /* call-count of the current CallID. */ - WCHAR* hostnameW; /* hostbyname */ + GUID providerId; /* Provider-ID */ + DWORD dwControlFlags; /* dwControlFlags (WSALookupServiceBegin) */ + DWORD CallID; /* List for LookupServiceNext-Calls */ + DWORD CallIDCounter; /* call-count of the current CallID. */ + WCHAR* hostnameW; /* hostbyname */ #ifdef NSP_REDIRECT - HANDLE rdrLookup; - NSP_ROUTINE rdrproc; + HANDLE rdrLookup; + NSP_ROUTINE rdrproc; #endif } WSHANDLEINTERN, *PWSHANDLEINTERN; @@ -89,911 +87,589 @@ NSP_ROUTINE rdrproc_nla; #endif /* NSP_REDIRECT */ -/* Forwards */ -INT -WINAPI -mswNSPStartup( - LPGUID lpProviderId, - LPNSP_ROUTINE lpRout); +/* Implementations - Internal */ -INT -NSP_LookupServiceBeginW( - PWSHANDLEINTERN data, - CHAR* hostnameA, - WCHAR* hostnameW, - DWORD CallID); +/* + hostnameA / hostnameW + * only used by HOSTBYNAME + * only one should be set +*/ INT -NSP_LookupServiceNextW( - _In_ PWSHANDLEINTERN data, - _In_ DWORD dwControlFlags, - _Inout_ LPWSAQUERYSETW lpRes, - _Inout_ LPDWORD lpResLen); +NSP_LookupServiceBeginW(PWSHANDLEINTERN data, + CHAR* hostnameA, + WCHAR* hostnameW, + DWORD CallID) +{ + HANDLE hHeap; -INT -NSP_GetHostNameHeapAllocW( - _Out_ WCHAR** hostname); + TRACE("NSP_LookupServiceBeginW %p %p %p %lx\n", data, hostnameA, hostnameW, CallID); + if (data->CallID != 0) + return WSAEFAULT; -INT -NSP_GetHostByNameHeapAllocW( - _In_ PWSHANDLEINTERN data, - _In_ DWORD dwControlFlags, - _Out_ PWSHOSTINFOINTERN hostinfo); + data->CallID = CallID; -INT -NSP_GetServiceByNameHeapAllocW( - _In_ PWSHANDLEINTERN data, - _In_ DWORD dwControlFlags, - _Out_ PWSHOSTINFOINTERN hostinfo); + if ((CallID == NSP_CALLID_HOSTBYNAME) || + (CallID == NSP_CALLID_SERVICEBYNAME)) + { + hHeap = GetProcessHeap(); -/* Implementations - Internal */ + if (data->hostnameW != NULL) + HeapFree(hHeap, 0, data->hostnameW); -INT -WSAAPI -mwsNSPCleanUp(_In_ LPGUID lpProviderId) -{ - //WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED); - //return ERROR_CALL_NOT_IMPLEMENTED; - return ERROR_SUCCESS; -} + if (hostnameA != NULL) + { + data->hostnameW = StrA2WHeapAlloc(hHeap, hostnameA); + } + else + { + data->hostnameW = StrCpyHeapAllocW(hHeap, hostnameW); + } + } + else + { + ERR("NSP_LookupServiceBeginW unsupported CallID\n"); + WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return ERROR_CALL_NOT_IMPLEMENTED; + } -INT -mwsNSPInit(VOID) -{ return ERROR_SUCCESS; } INT -WSAAPI -mwsNSPLookupServiceBegin(_In_ LPGUID lpProviderId, - _In_ LPWSAQUERYSETW lpqsRestrictions, - _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo, - _In_ DWORD dwControlFlags, - _Out_ LPHANDLE lphLookup) +NSP_GetHostNameHeapAllocW(_Out_ WCHAR** hostname) { - PWSHANDLEINTERN pLook; - int wsaErr; + WCHAR* name; + HANDLE hHeap = GetProcessHeap(); + DWORD bufCharLen = 0; - TRACE("mwsNSPLookupServiceBegin %p %p %p %lx %p\n", lpProviderId, lpqsRestrictions, lpServiceClassInfo, dwControlFlags, lphLookup); - if (IsEqualGUID(lpProviderId, &guid_mswsock_TcpIp)) - { - //OK - TRACE("TCPIP query\n"); - } - else if (IsEqualGUID(lpProviderId, &guid_mswsock_NLA)) + TRACE("NSP_GetHostNameHeapAllocW %p\n", hostname); + /* FIXME Use DnsGetHostName_W when available */ + GetComputerNameExW(ComputerNameDnsHostname, NULL, &bufCharLen); + if (!bufCharLen) { - ERR("NLA queries are not supported yet\n"); - WSASetLastError(WSASERVICE_NOT_FOUND); + ERR("NSP_GetHostNameHeapAllocW zero size for computername returned\n"); + WSASetLastError(WSAEFAULT); return SOCKET_ERROR; } - else - { - ERR("Unsupported GUID\n"); - return ERROR_CALL_NOT_IMPLEMENTED; - } - - /* allocate internal structure */ - pLook = HeapAlloc(GetProcessHeap(), 0, sizeof(WSHANDLEINTERN)); - if (!pLook) + name = HeapAlloc(hHeap, 0, bufCharLen*sizeof(WCHAR)); + if (!GetComputerNameExW(ComputerNameDnsHostname, + name, + &bufCharLen)) { - ERR("Error allocating %d for handle\n", sizeof(WSHANDLEINTERN)); + ERR("NSP_GetHostNameHeapAllocW error obtaining computername %lx\n", GetLastError()); + HeapFree(hHeap, 0, name); WSASetLastError(WSAEFAULT); return SOCKET_ERROR; } - *lphLookup = (HANDLE)pLook; - - RtlZeroMemory(pLook, sizeof(*pLook)); + *hostname = name; + return ERROR_SUCCESS; +} - /* Anyway the ControlFlags "should" be needed - in NSPLookupServiceNext. (see doku) But - thats not the fact ATM. */ - pLook->dwControlFlags = dwControlFlags; - pLook->providerId = *lpProviderId; +INT +NSP_GetHostByNameHeapAllocW(_In_ PWSHANDLEINTERN data, + _In_ DWORD dwControlFlags, + _Out_ PWSHOSTINFOINTERN hostinfo) +{ + HANDLE hHeap = GetProcessHeap(); + DNS_STATUS dns_status = { 0 }; + /* include/WinDNS.h -- look up DNS_RECORD on MSDN */ + PDNS_RECORDW dp; + PDNS_RECORDW curr; + INT result = ERROR_SUCCESS; + DWORD dwQueryFlags = DNS_QUERY_STANDARD; + PWCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 }; + int AliasIndex = 0; -#ifdef NSP_REDIRECT + TRACE("NSP_GetHostByNameHeapAllocW %p %lx %p\n", data, dwControlFlags, hostinfo); + /* needed to be cleaned up if != NULL */ + dp = NULL; - if (IsEqualGUID(lpProviderId, &guid_mswsock_TcpIp)) - { - pLook->rdrproc = rdrproc_tcpip; - } - else if (IsEqualGUID(lpProviderId, &guid_mswsock_NLA)) - { - pLook->rdrproc = rdrproc_nla; - } - else + if (!data->hostnameW) { - return ERROR_CALL_NOT_IMPLEMENTED; + result = ERROR_INVALID_PARAMETER; + goto cleanup; } - if (pLook->rdrproc.NSPLookupServiceBegin(lpProviderId, - lpqsRestrictions, - lpServiceClassInfo, - dwControlFlags, - &pLook->rdrLookup) == NO_ERROR) - { - wsaErr = NO_ERROR; - } - else + if ((data->dwControlFlags & LUP_DEEP) == 0) { - wsaErr = WSAGetLastError(); + TRACE("NSP_GetHostByNameHeapAllocW LUP_DEEP is not specified. Disabling recursion\n"); + dwQueryFlags |= DNS_QUERY_NO_RECURSION; } - /* - if (res) - res = WSAGetLastError(); - */ - -#else /* NSP_REDIRECT */ - - wsaErr = ERROR_CALL_NOT_IMPLEMENTED; - if (IsEqualGUID(lpqsRestrictions->lpServiceClassId, &guid_NULL)) + /* DNS_TYPE_A: include/WinDNS.h */ + /* DnsQuery -- lib/dnsapi/dnsapi/query.c */ + dns_status = DnsQuery_W(data->hostnameW, + DNS_TYPE_A, + dwQueryFlags, + NULL /* extra dns servers */, + &dp, + NULL); + if (dns_status == ERROR_INVALID_NAME) { - ERR("NULL GUID service class is not implemented yet\n"); - wsaErr = ERROR_CALL_NOT_IMPLEMENTED; + ERR("NSP_GetHostByNameHeapAllocW invalid name\n"); + WSASetLastError(WSAEFAULT); + result = ERROR_INVALID_PARAMETER; + goto cleanup; } - else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId, &guid_HOSTNAME)) + + if ((dns_status != 0) || (dp == NULL)) { - TRACE("HOSTNAME GUID\n"); - wsaErr = NSP_LookupServiceBeginW(pLook, - NULL, - NULL, - NSP_CALLID_HOSTNAME); + ERR("NSP_GetHostByNameHeapAllocW not found %lx %p\n", dns_status, dp); + result = WSAHOST_NOT_FOUND; + goto cleanup; } - else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId, - &guid_INET_HOSTADDRBYNAME)) + + //ASSERT(dp->wType == DNS_TYPE_A); + //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA)); + curr = dp; + while ((curr->pNext != NULL) || (curr->wType != DNS_TYPE_A)) { - TRACE("INET_HOSTADDRBYNAME GUID\n"); - wsaErr = NSP_LookupServiceBeginW(pLook, - NULL, - lpqsRestrictions->lpszServiceInstanceName, - NSP_CALLID_HOSTBYNAME); + if (curr->wType == DNS_TYPE_CNAME) + { + TRACE("NSP_GetHostByNameHeapAllocW found alias %ws\n", curr->Data.Cname.pNameHost); + Aliases[AliasIndex++] = curr->Data.Cname.pNameHost; + } + curr = curr->pNext; } - else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId, - &guid_INET_SERVICEBYNAME)) + + if (curr->wType != DNS_TYPE_A) { - TRACE("INET_SERVICEBYNAME\n"); - wsaErr = NSP_LookupServiceBeginW(pLook, - NULL, - lpqsRestrictions->lpszServiceInstanceName, - NSP_CALLID_SERVICEBYNAME); + ERR("NSP_GetHostByNameHeapAllocW last record is not of type A %d\n", curr->wType); + result = WSASERVICE_NOT_FOUND; + goto cleanup; } - else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId, - &guid_INET_HOSTADDRBYINETSTRING)) + hostinfo->hostnameW = StrCpyHeapAllocW(hHeap, curr->pName); + hostinfo->addr4 = curr->Data.A.IpAddress; + if (AliasIndex) { - ERR("INET_HOSTADDRBYINETSTRING GUID service class is not implemented yet\n"); - wsaErr = ERROR_CALL_NOT_IMPLEMENTED; + hostinfo->servaliasesA = StrAryCpyHeapAllocWToA(hHeap, (WCHAR**)&Aliases); } + result = ERROR_SUCCESS; -#endif /* NSP_REDIRECT */ +cleanup: + if (dp != NULL) + DnsRecordListFree(dp, DnsFreeRecordList); - if (wsaErr != NO_ERROR) - { - ERR("mwsNSPLookupServiceBegin wsaErr = %d\n", wsaErr); - WSASetLastError(wsaErr); - return SOCKET_ERROR; - } - return NO_ERROR; + return result; } -INT -WSAAPI -mwsNSPLookupServiceNext(_In_ HANDLE hLookup, - _In_ DWORD dwControlFlags, - _Inout_ LPDWORD lpdwBufferLength, - //_Out_writes_bytes_to_(*lpdwBufferLength, *lpdwBufferLength) - LPWSAQUERYSETW lpqsResults) -{ - PWSHANDLEINTERN pLook = hLookup; - int wsaErr = 0; - - TRACE("mwsNSPLookupServiceNext %p %lx %p %p\n", pLook, dwControlFlags, lpdwBufferLength, lpqsResults); -#ifdef NSP_REDIRECT +#define SKIPWS(ptr, act) \ +{while(*ptr && isspace(*ptr)) ptr++; if(!*ptr) act;} - INT res = pLook->rdrproc.NSPLookupServiceNext(pLook->rdrLookup, - dwControlFlags, - lpdwBufferLength, - lpqsResults); - wsaErr = WSAGetLastError(); - if (res != ERROR_SUCCESS) - { - wsaErr = WSAGetLastError(); - - if (wsaErr == 0) - wsaErr = 0xFFFFFFFF; - } - -#else /* NSP_REDIRECT */ - - if ((lpdwBufferLength == NULL) || (*lpdwBufferLength == 0)) - { - wsaErr = WSA_NOT_ENOUGH_MEMORY; - goto End; - } - - RtlZeroMemory(lpqsResults, *lpdwBufferLength); - lpqsResults->dwSize = sizeof(*lpqsResults); +#define SKIPANDMARKSTR(ptr, act) \ +{while(*ptr && !isspace(*ptr)) ptr++; \ + if(!*ptr) {act;} else { *ptr = 0; ptr++; }} - wsaErr = NSP_LookupServiceNextW(pLook, - dwControlFlags, - lpqsResults, - lpdwBufferLength); +static +BOOL +DecodeServEntFromString(IN PCHAR ServiceString, + OUT PCHAR *ServiceName, + OUT PCHAR *PortNumberStr, + OUT PCHAR *ProtocolStr, + IN PCHAR *Aliases, + IN DWORD MaxAlias) +{ + UINT NAliases = 0; + //WS_DbgPrint(MAX_TRACE, ("Parsing service ent [%s]\n", ServiceString)); -#endif /* NSP_REDIRECT */ + SKIPWS(ServiceString, return FALSE); + *ServiceName = ServiceString; + SKIPANDMARKSTR(ServiceString, return FALSE); + SKIPWS(ServiceString, return FALSE); + *PortNumberStr = ServiceString; + SKIPANDMARKSTR(ServiceString, ;); -End: - if (wsaErr != 0) + while (*ServiceString && NAliases < MaxAlias - 1) { - ERR("mwsNSPLookupServiceNext wsaErr = %d\n", wsaErr); - WSASetLastError(wsaErr); - return SOCKET_ERROR; + SKIPWS(ServiceString, break); + if (*ServiceString) + { + SKIPWS(ServiceString, ;); + if (strlen(ServiceString)) + { + //WS_DbgPrint(MAX_TRACE, ("Alias: %s\n", ServiceString)); + *Aliases++ = ServiceString; + NAliases++; + } + SKIPANDMARKSTR(ServiceString, ;); + } } - return NO_ERROR; -} - -INT -WSAAPI -mwsNSPIoCtl(_In_ HANDLE hLookup, - _In_ DWORD dwControlCode, - _In_reads_bytes_(cbInBuffer) LPVOID lpvInBuffer, - _In_ DWORD cbInBuffer, - _Out_writes_bytes_to_(cbOutBuffer, *lpcbBytesReturned) LPVOID lpvOutBuffer, - _In_ DWORD cbOutBuffer, - _Out_ LPDWORD lpcbBytesReturned, - _In_opt_ LPWSACOMPLETION lpCompletion, - _In_ LPWSATHREADID lpThreadId) -{ - ERR("mwsNSPIoCtl not implemented %p %lx %p %ld %p %ld %p %p %p\n", hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion, lpThreadId); - WSASetLastError(WSAEOPNOTSUPP); - return ERROR_CALL_NOT_IMPLEMENTED; -} - -INT -WSAAPI -mwsNSPLookupServiceEnd(_In_ HANDLE hLookup) -{ - PWSHANDLEINTERN pLook = (PWSHANDLEINTERN)hLookup; - HANDLE hHeap = GetProcessHeap(); - INT res = NO_ERROR; - - TRACE("mwsNSPLookupServiceEnd %p\n", pLook); -#ifdef NSP_REDIRECT - res = pLook->rdrproc.NSPLookupServiceEnd(pLook->rdrLookup); -#endif + *Aliases = NULL; - if (pLook->hostnameW != NULL) - HeapFree(hHeap, 0, pLook->hostnameW); + *ProtocolStr = strchr(*PortNumberStr, '/'); - HeapFree(hHeap, 0, pLook); - return res; -} + if (!*ProtocolStr) + return FALSE; -INT -WSAAPI -mwsNSPSetService(_In_ LPGUID lpProviderId, - _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo, - _In_ LPWSAQUERYSETW lpqsRegInfo, - _In_ WSAESETSERVICEOP essOperation, - _In_ DWORD dwControlFlags) -{ - ERR("mwsNSPSetService not implemented %p %p %p %d %lx %ld %p %p %p\n", lpProviderId, lpServiceClassInfo, lpqsRegInfo, essOperation, dwControlFlags); - WSASetLastError(WSAEOPNOTSUPP); - return ERROR_CALL_NOT_IMPLEMENTED; -} + **ProtocolStr = 0; + (*ProtocolStr)++; -INT -WSAAPI -mwsNSPInstallServiceClass(_In_ LPGUID lpProviderId, - _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo) -{ - ERR("mwsNSPInstallServiceClass not implemented %p %p\n", lpProviderId, lpServiceClassInfo); - WSASetLastError(WSAEOPNOTSUPP); - return ERROR_CALL_NOT_IMPLEMENTED; -} + //WS_DbgPrint(MAX_TRACE, ("Parsing done: %s %s %s %d\n", + // *ServiceName, *ProtocolStr, *PortNumberStr, + // NAliases)); -INT -WSAAPI -mwsNSPRemoveServiceClass(_In_ LPGUID lpProviderId, - _In_ LPGUID lpServiceClassId) -{ - ERR("mwsNSPRemoveServiceClass not implemented %p %p\n", lpProviderId, lpServiceClassId); - WSASetLastError(WSAEOPNOTSUPP); - return ERROR_CALL_NOT_IMPLEMENTED; + return TRUE; } -INT +HANDLE WSAAPI -mwsNSPGetServiceClassInfo(_In_ LPGUID lpProviderId, - _In_ LPDWORD lpdwBufSize, - _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo) -{ - ERR("mwsNSPGetServiceClassInfo not implemented %p %p %p\n", lpProviderId, lpdwBufSize, lpServiceClassInfo); - WSASetLastError(WSAEOPNOTSUPP); - return ERROR_CALL_NOT_IMPLEMENTED; -} - -/* - hostnameA / hostnameW - * only used by HOSTBYNAME - * only one should be set - -*/ -INT -NSP_LookupServiceBeginW(PWSHANDLEINTERN data, - CHAR* hostnameA, - WCHAR* hostnameW, - DWORD CallID) +OpenNetworkDatabase(_In_ LPCWSTR Name) { - HANDLE hHeap; - - TRACE("NSP_LookupServiceBeginW %p %p %p %lx\n", data, hostnameA, hostnameW, CallID); - if (data->CallID != 0) - return WSAEFAULT; + PWSTR ExpandedPath; + PWSTR DatabasePath; + INT ErrorCode; + HKEY DatabaseKey; + DWORD RegType; + DWORD RegSize = 0; + size_t StringLength; + HANDLE Handle; - data->CallID = CallID; + TRACE("OpenNetworkDatabase %p\n", Name); + ExpandedPath = HeapAlloc(GetProcessHeap(), 0, MAX_PATH*sizeof(WCHAR)); + if (!ExpandedPath) + return INVALID_HANDLE_VALUE; - if ((CallID == NSP_CALLID_HOSTBYNAME) || - (CallID == NSP_CALLID_SERVICEBYNAME)) + /* Open the database path key */ + ErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters", + 0, + KEY_READ, + &DatabaseKey); + if (ErrorCode == NO_ERROR) { - hHeap = GetProcessHeap(); - - if (data->hostnameW != NULL) - HeapFree(hHeap, 0, data->hostnameW); + TRACE("OpenNetworkDatabase registry key for network database exist\n"); + /* Read the actual path */ + ErrorCode = RegQueryValueEx(DatabaseKey, + L"DatabasePath", + NULL, + &RegType, + NULL, + &RegSize); - if (hostnameA != NULL) + if (!RegSize) { - data->hostnameW = StrA2WHeapAlloc(hHeap, hostnameA); + ERR("OpenNetworkDatabase RegQueryValueEx failed to return size for DatabasePath %lx\n", ErrorCode); + RegCloseKey(DatabaseKey); + HeapFree(GetProcessHeap(), 0, ExpandedPath); + return INVALID_HANDLE_VALUE; } - else + DatabasePath = HeapAlloc(GetProcessHeap(), 0, RegSize); + if (!DatabasePath) { - data->hostnameW = StrCpyHeapAllocW(hHeap, hostnameW); + ERR("OpenNetworkDatabase could not allocate %d for DatabasePath\n", RegSize); + RegCloseKey(DatabaseKey); + HeapFree(GetProcessHeap(), 0, ExpandedPath); + return INVALID_HANDLE_VALUE; + } + + /* Read the actual path */ + ErrorCode = RegQueryValueEx(DatabaseKey, + L"DatabasePath", + NULL, + &RegType, + (LPBYTE)DatabasePath, + &RegSize); + + /* Close the key */ + RegCloseKey(DatabaseKey); + + if (ErrorCode) + { + ERR("OpenNetworkDatabase RegQueryValueEx failed to return value for DatabasePath %lx\n", ErrorCode); + HeapFree(GetProcessHeap(), 0, DatabasePath); + HeapFree(GetProcessHeap(), 0, ExpandedPath); + return INVALID_HANDLE_VALUE; } + + /* Expand the name */ + ExpandEnvironmentStrings(DatabasePath, ExpandedPath, MAX_PATH); + + HeapFree(GetProcessHeap(), 0, DatabasePath); } else { - ERR("NSP_LookupServiceBeginW unsupported CallID\n"); - WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + TRACE("OpenNetworkDatabase registry key for network database doesn't exist\n"); + /* Use defalt path */ + GetSystemDirectory(ExpandedPath, MAX_PATH); + StringCchLength(ExpandedPath, MAX_PATH, &StringLength); + if (ExpandedPath[StringLength - 1] != L'\\') + { + /* It isn't, so add it ourselves */ + StringCchCat(ExpandedPath, MAX_PATH, L"\\"); + } + StringCchCat(ExpandedPath, MAX_PATH, L"DRIVERS\\ETC\\"); } - return ERROR_SUCCESS; -} - -INT -NSP_GetHostNameHeapAllocW(_Out_ WCHAR** hostname) -{ - WCHAR* name; - HANDLE hHeap = GetProcessHeap(); - DWORD bufCharLen = 0; - - TRACE("NSP_GetHostNameHeapAllocW %p\n", hostname); - /* FIXME Use DnsGetHostName_W when available */ - GetComputerNameExW(ComputerNameDnsHostname, NULL, &bufCharLen); - if (!bufCharLen) - { - ERR("NSP_GetHostNameHeapAllocW zero size for computername returned\n"); - WSASetLastError(WSAEFAULT); - return SOCKET_ERROR; - } - name = HeapAlloc(hHeap, 0, bufCharLen*sizeof(WCHAR)); - if (!GetComputerNameExW(ComputerNameDnsHostname, - name, - &bufCharLen)) + /* Make sure that the path is backslash-terminated */ + StringCchLength(ExpandedPath, MAX_PATH, &StringLength); + if (ExpandedPath[StringLength - 1] != L'\\') { - ERR("NSP_GetHostNameHeapAllocW error obtaining computername %lx\n", GetLastError()); - HeapFree(hHeap, 0, name); - WSASetLastError(WSAEFAULT); - return SOCKET_ERROR; + /* It isn't, so add it ourselves */ + StringCchCat(ExpandedPath, MAX_PATH, L"\\"); } - *hostname = name; - return ERROR_SUCCESS; + /* Add the database name */ + StringCchCat(ExpandedPath, MAX_PATH, Name); + + /* Return a handle to the file */ + Handle = CreateFile(ExpandedPath, + FILE_READ_DATA, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + HeapFree(GetProcessHeap(), 0, ExpandedPath); + return Handle; } INT -NSP_GetHostByNameHeapAllocW(_In_ PWSHANDLEINTERN data, - _In_ DWORD dwControlFlags, - _Out_ PWSHOSTINFOINTERN hostinfo) +NSP_GetServiceByNameHeapAllocW(_In_ PWSHANDLEINTERN data, + _In_ DWORD dwControlFlags, + _Out_ PWSHOSTINFOINTERN hostinfo) { - HANDLE hHeap = GetProcessHeap(); - DNS_STATUS dns_status = { 0 }; - /* include/WinDNS.h -- look up DNS_RECORD on MSDN */ - PDNS_RECORDW dp; - PDNS_RECORDW curr; - INT result = ERROR_SUCCESS; - DWORD dwQueryFlags = DNS_QUERY_STANDARD; - PWCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 }; - int AliasIndex = 0; - - TRACE("NSP_GetHostByNameHeapAllocW %p %lx %p\n", data, dwControlFlags, hostinfo); - /* needed to be cleaned up if != NULL */ - dp = NULL; - + BOOL Found = FALSE; + HANDLE ServicesFile; + CHAR ServiceDBData[BUFSIZ * sizeof(WCHAR)] = { 0 }; + PCHAR ThisLine = 0, NextLine = 0, ServiceName = 0, PortNumberStr = 0, + ProtocolStr = 0, Comment = 0, EndValid; + PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 }; + PCHAR* AliasPtr; + UINT i = 0; + DWORD ReadSize = 0; + HANDLE hHeap; + PCHAR nameA = NULL; + PCHAR nameServiceA = NULL; + PCHAR nameProtoA = NULL; + INT res = WSANO_RECOVERY; + + TRACE("NSP_GetServiceByNameHeapAllocW %p %lx %p\n", data, dwControlFlags, hostinfo); if (!data->hostnameW) { - result = ERROR_INVALID_PARAMETER; - goto cleanup; + ERR("NSP_GetServiceByNameHeapAllocW service name not provided\n"); + res = WSANO_RECOVERY; + goto End; } - if ((data->dwControlFlags & LUP_DEEP) == 0) - { - TRACE("NSP_GetHostByNameHeapAllocW LUP_DEEP is not specified. Disabling recursion\n"); - dwQueryFlags |= DNS_QUERY_NO_RECURSION; - } + hHeap = GetProcessHeap(); + nameA = StrW2AHeapAlloc(hHeap, data->hostnameW); - /* DNS_TYPE_A: include/WinDNS.h */ - /* DnsQuery -- lib/dnsapi/dnsapi/query.c */ - dns_status = DnsQuery_W(data->hostnameW, - DNS_TYPE_A, - dwQueryFlags, - NULL /* extra dns servers */, - &dp, - NULL); - if (dns_status == ERROR_INVALID_NAME) + /* nameA has the form / + we split these now */ + nameProtoA = strchr(nameA, '/'); + if (nameProtoA == NULL) { - ERR("NSP_GetHostByNameHeapAllocW invalid name\n"); - WSASetLastError(WSAEFAULT); - result = ERROR_INVALID_PARAMETER; - goto cleanup; + ERR("NSP_GetServiceByNameHeapAllocW invalid service name %s\n", nameA); + res = WSANO_RECOVERY; + goto End; } - if ((dns_status != 0) || (dp == NULL)) - { - ERR("NSP_GetHostByNameHeapAllocW not found %lx %p\n", dns_status, dp); - result = WSAHOST_NOT_FOUND; - goto cleanup; - } + nameProtoA++; + i = (DWORD)(nameProtoA - nameA - 1); + nameServiceA = (PCHAR)HeapAlloc(hHeap, 0, i + 1); + StringCbCopyA(nameServiceA, i + 1, nameA); + nameServiceA[i] = '\0'; - //ASSERT(dp->wType == DNS_TYPE_A); - //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA)); - curr = dp; - while ((curr->pNext != NULL) || (curr->wType != DNS_TYPE_A)) + ServicesFile = OpenNetworkDatabase(L"services"); + if (ServicesFile == INVALID_HANDLE_VALUE) { - if (curr->wType == DNS_TYPE_CNAME) - { - TRACE("NSP_GetHostByNameHeapAllocW found alias %ws\n", curr->Data.Cname.pNameHost); - Aliases[AliasIndex++] = curr->Data.Cname.pNameHost; - } - curr = curr->pNext; + ERR("NSP_GetServiceByNameHeapAllocW unable to open services file\n"); + return WSANO_RECOVERY; } - if (curr->wType != DNS_TYPE_A) + /* Scan the services file ... + * + * We will be share the buffer on the lines. If the line does not fit in + * the buffer, then moving it to the beginning of the buffer and read + * the remnants of line from file. + */ + + /* Initial Read */ + if (!ReadFile(ServicesFile, + ServiceDBData, + sizeof( ServiceDBData ) - 1, + &ReadSize, + NULL)) { - ERR("NSP_GetHostByNameHeapAllocW last record is not of type A %d\n", curr->wType); - result = WSASERVICE_NOT_FOUND; - goto cleanup; + ERR("NSP_GetServiceByNameHeapAllocW can't read services file %lx\n", GetLastError()); + CloseHandle(ServicesFile); + return WSANO_RECOVERY; } - hostinfo->hostnameW = StrCpyHeapAllocW(hHeap, curr->pName); - hostinfo->addr4 = curr->Data.A.IpAddress; - if (AliasIndex) + + ThisLine = NextLine = ServiceDBData; + EndValid = ServiceDBData + ReadSize; + ServiceDBData[sizeof(ServiceDBData) - 1] = '\0'; + + while (ReadSize) { - hostinfo->servaliasesA = StrAryCpyHeapAllocWToA(hHeap, (WCHAR**)&Aliases); - } - result = ERROR_SUCCESS; + for (; *NextLine != '\r' && *NextLine != '\n'; NextLine++) + { + if (NextLine == EndValid) + { + int LineLen = NextLine - ThisLine; -cleanup: - if (dp != NULL) - DnsRecordListFree(dp, DnsFreeRecordList); + if (ThisLine == ServiceDBData) + { + ERR("NSP_GetServiceByNameHeapAllocW line too long\n"); + CloseHandle(ServicesFile); + return WSANO_RECOVERY; + } - return result; -} + memmove(ServiceDBData, ThisLine, LineLen); -#define SKIPWS(ptr, act) \ -{while(*ptr && isspace(*ptr)) ptr++; if(!*ptr) act;} + if (!ReadFile(ServicesFile, + ServiceDBData + LineLen, + sizeof( ServiceDBData )-1 - LineLen, + &ReadSize, + NULL)) + { + break; + } -#define SKIPANDMARKSTR(ptr, act) \ -{while(*ptr && !isspace(*ptr)) ptr++; \ - if(!*ptr) {act;} else { *ptr = 0; ptr++; }} + EndValid = ServiceDBData + LineLen + ReadSize; + NextLine = ServiceDBData + LineLen; + ThisLine = ServiceDBData; -static -BOOL -DecodeServEntFromString(IN PCHAR ServiceString, - OUT PCHAR *ServiceName, - OUT PCHAR *PortNumberStr, - OUT PCHAR *ProtocolStr, - IN PCHAR *Aliases, - IN DWORD MaxAlias) -{ - UINT NAliases = 0; + if (!ReadSize) break; + } + } - //WS_DbgPrint(MAX_TRACE, ("Parsing service ent [%s]\n", ServiceString)); + *NextLine = '\0'; + Comment = strchr(ThisLine, '#'); - SKIPWS(ServiceString, return FALSE); - *ServiceName = ServiceString; - SKIPANDMARKSTR(ServiceString, return FALSE); - SKIPWS(ServiceString, return FALSE); - *PortNumberStr = ServiceString; - SKIPANDMARKSTR(ServiceString, ;); + if (Comment) + *Comment = '\0'; /* Terminate at comment start */ - while (*ServiceString && NAliases < MaxAlias - 1) - { - SKIPWS(ServiceString, break); - if (*ServiceString) + if (DecodeServEntFromString(ThisLine, + &ServiceName, + &PortNumberStr, + &ProtocolStr, + Aliases, + WS2_INTERNAL_MAX_ALIAS) && + (strlen(nameProtoA) == 0 || strcmp(ProtocolStr, nameProtoA) == 0)) { - SKIPWS(ServiceString, ;); - if (strlen(ServiceString)) + Found = (strcmp(ServiceName, nameServiceA) == 0 || strcmp(PortNumberStr, nameServiceA) == 0); + AliasPtr = Aliases; + while ((!Found) && (*AliasPtr != NULL)) { - //WS_DbgPrint(MAX_TRACE, ("Alias: %s\n", ServiceString)); - *Aliases++ = ServiceString; - NAliases++; + Found = (strcmp(*AliasPtr, nameServiceA) == 0); + AliasPtr++; } - SKIPANDMARKSTR(ServiceString, ;); + if (Found) + break; } + NextLine++; + ThisLine = NextLine; } - *Aliases = NULL; - *ProtocolStr = strchr(*PortNumberStr, '/'); - - if (!*ProtocolStr) - return FALSE; - - **ProtocolStr = 0; - (*ProtocolStr)++; + /* This we'll do no matter what */ + CloseHandle(ServicesFile); - //WS_DbgPrint(MAX_TRACE, ("Parsing done: %s %s %s %d\n", - // *ServiceName, *ProtocolStr, *PortNumberStr, - // NAliases)); + if (!Found) + { + ERR("NSP_GetServiceByNameHeapAllocW service not found\n"); + return WSANO_DATA; + } - return TRUE; -} + hostinfo->addr4 = 0; + hostinfo->servnameW = StrA2WHeapAlloc(hHeap, ServiceName); + hostinfo->servprotoW = StrA2WHeapAlloc(hHeap, ProtocolStr); + hostinfo->servaliasesA = StrAryCpyHeapAllocA(hHeap, (char**)&Aliases); + hostinfo->servport = atoi(PortNumberStr); -HANDLE -WSAAPI -OpenNetworkDatabase(_In_ LPCWSTR Name) -{ - PWSTR ExpandedPath; - PWSTR DatabasePath; - INT ErrorCode; - HKEY DatabaseKey; - DWORD RegType; - DWORD RegSize = 0; - size_t StringLength; - HANDLE Handle; + res = NO_ERROR; - TRACE("OpenNetworkDatabase %p\n", Name); - ExpandedPath = HeapAlloc(GetProcessHeap(), 0, MAX_PATH*sizeof(WCHAR)); - if (!ExpandedPath) - return INVALID_HANDLE_VALUE; +End: + if (nameA) + HeapFree(hHeap, 0, nameA); - /* Open the database path key */ - ErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters", - 0, - KEY_READ, - &DatabaseKey); - if (ErrorCode == NO_ERROR) - { - TRACE("OpenNetworkDatabase registry key for network database exist\n"); - /* Read the actual path */ - ErrorCode = RegQueryValueEx(DatabaseKey, - L"DatabasePath", - NULL, - &RegType, - NULL, - &RegSize); + if (nameServiceA) + HeapFree(hHeap, 0, nameServiceA); - if (!RegSize) - { - ERR("OpenNetworkDatabase RegQueryValueEx failed to return size for DatabasePath %lx\n", ErrorCode); - RegCloseKey(DatabaseKey); - HeapFree(GetProcessHeap(), 0, ExpandedPath); - return INVALID_HANDLE_VALUE; - } - DatabasePath = HeapAlloc(GetProcessHeap(), 0, RegSize); - if (!DatabasePath) - { - ERR("OpenNetworkDatabase could not allocate %d for DatabasePath\n", RegSize); - RegCloseKey(DatabaseKey); - HeapFree(GetProcessHeap(), 0, ExpandedPath); - return INVALID_HANDLE_VALUE; - } + return res; +} - /* Read the actual path */ - ErrorCode = RegQueryValueEx(DatabaseKey, - L"DatabasePath", - NULL, - &RegType, - (LPBYTE)DatabasePath, - &RegSize); +INT +NSP_LookupServiceNextW(_In_ PWSHANDLEINTERN data, + _In_ DWORD dwControlFlags, + _Inout_ LPWSAQUERYSETW lpRes, + _Inout_ LPDWORD lpResLen) +{ + MSW_BUFFER buf; + WSHOSTINFOINTERN hostinfo; + INT result; + HANDLE hHeap = GetProcessHeap(); + WCHAR* ServiceInstanceNameW = NULL; + /* cleanup-vars */ + CHAR* ServiceInstanceNameA = NULL; + CHAR* ServiceProtocolNameA = NULL; - /* Close the key */ - RegCloseKey(DatabaseKey); + TRACE("NSP_LookupServiceNextW %p %lx %p %p\n", data, dwControlFlags, lpRes, lpResLen); + if (!data || (dwControlFlags & (~(DWORD)LUP_FLUSHPREVIOUS)) != 0 || !lpRes || !lpResLen || *lpResLen == 0) + return WSAEINVAL; + RtlZeroMemory(&hostinfo, sizeof(hostinfo)); - if (ErrorCode) - { - ERR("OpenNetworkDatabase RegQueryValueEx failed to return value for DatabasePath %lx\n", ErrorCode); - HeapFree(GetProcessHeap(), 0, DatabasePath); - HeapFree(GetProcessHeap(), 0, ExpandedPath); - return INVALID_HANDLE_VALUE; - } + /* init and build result-buffer */ + mswBufferInit(&buf, (BYTE*)lpRes, *lpResLen); + mswBufferIncUsed(&buf, sizeof(*lpRes)); - /* Expand the name */ - ExpandEnvironmentStrings(DatabasePath, ExpandedPath, MAX_PATH); + /* QueryDataSet-Size without "blob-data"-size! */ + lpRes->dwSize = sizeof(*lpRes); + lpRes->dwNameSpace = NS_DNS; - HeapFree(GetProcessHeap(), 0, DatabasePath); - } - else + if ((data->CallID == NSP_CALLID_HOSTNAME) || + (data->CallID == NSP_CALLID_HOSTBYNAME) || + (data->CallID == NSP_CALLID_SERVICEBYNAME)) { - TRACE("OpenNetworkDatabase registry key for network database doesn't exist\n"); - /* Use defalt path */ - GetSystemDirectory(ExpandedPath, MAX_PATH); - StringCchLength(ExpandedPath, MAX_PATH, &StringLength); - if (ExpandedPath[StringLength - 1] != L'\\') + /* FIXME remember what was returned and continue from there */ + if (data->CallIDCounter >= 1) { - /* It isn't, so add it ourselves */ - StringCchCat(ExpandedPath, MAX_PATH, L"\\"); + ERR("NSP_LookupServiceNextW LUP_FLUSHPREVIOUS and more than one call not supported yet\n", data, dwControlFlags, lpRes, lpResLen); + result = WSA_E_NO_MORE; + goto End; } - StringCchCat(ExpandedPath, MAX_PATH, L"DRIVERS\\ETC\\"); - } - - /* Make sure that the path is backslash-terminated */ - StringCchLength(ExpandedPath, MAX_PATH, &StringLength); - if (ExpandedPath[StringLength - 1] != L'\\') - { - /* It isn't, so add it ourselves */ - StringCchCat(ExpandedPath, MAX_PATH, L"\\"); } - - /* Add the database name */ - StringCchCat(ExpandedPath, MAX_PATH, Name); - - /* Return a handle to the file */ - Handle = CreateFile(ExpandedPath, - FILE_READ_DATA, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - HeapFree(GetProcessHeap(), 0, ExpandedPath); - return Handle; -} - -INT -NSP_GetServiceByNameHeapAllocW(_In_ PWSHANDLEINTERN data, - _In_ DWORD dwControlFlags, - _Out_ PWSHOSTINFOINTERN hostinfo) -{ - BOOL Found = FALSE; - HANDLE ServicesFile; - CHAR ServiceDBData[BUFSIZ * sizeof(WCHAR)] = { 0 }; - PCHAR ThisLine = 0, NextLine = 0, ServiceName = 0, PortNumberStr = 0, - ProtocolStr = 0, Comment = 0, EndValid; - PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 }; - PCHAR* AliasPtr; - UINT i = 0; - DWORD ReadSize = 0; - HANDLE hHeap; - PCHAR nameA = NULL; - PCHAR nameServiceA = NULL; - PCHAR nameProtoA = NULL; - INT res = WSANO_RECOVERY; - - TRACE("NSP_GetServiceByNameHeapAllocW %p %lx %p\n", data, dwControlFlags, hostinfo); - if (!data->hostnameW) + else { - ERR("NSP_GetServiceByNameHeapAllocW service name not provided\n"); - res = WSANO_RECOVERY; + ERR("NSP_LookupServiceNextW unsupported CallID %lx\n", data->CallID); + result = WSAEOPNOTSUPP; goto End; } + data->CallIDCounter++; - hHeap = GetProcessHeap(); - nameA = StrW2AHeapAlloc(hHeap, data->hostnameW); - - /* nameA has the form / - we split these now */ - nameProtoA = strchr(nameA, '/'); - if (nameProtoA == NULL) + if (data->CallID == NSP_CALLID_HOSTNAME) { - ERR("NSP_GetServiceByNameHeapAllocW invalid service name %s\n", nameA); - res = WSANO_RECOVERY; - goto End; - } + result = NSP_GetHostNameHeapAllocW(&hostinfo.hostnameW); - nameProtoA++; - i = (DWORD)(nameProtoA - nameA - 1); - nameServiceA = (PCHAR)HeapAlloc(hHeap, 0, i + 1); - StringCbCopyA(nameServiceA, i + 1, nameA); - nameServiceA[i] = '\0'; + if (result != ERROR_SUCCESS) + goto End; - ServicesFile = OpenNetworkDatabase(L"services"); - if (ServicesFile == INVALID_HANDLE_VALUE) + hostinfo.addr4 = 0; + } + else if (data->CallID == NSP_CALLID_HOSTBYNAME) { - ERR("NSP_GetServiceByNameHeapAllocW unable to open services file\n"); - return WSANO_RECOVERY; + result = NSP_GetHostByNameHeapAllocW(data, + dwControlFlags, + &hostinfo); + if (result != ERROR_SUCCESS) + goto End; } - - /* Scan the services file ... - * - * We will be share the buffer on the lines. If the line does not fit in - * the buffer, then moving it to the beginning of the buffer and read - * the remnants of line from file. - */ - - /* Initial Read */ - if (!ReadFile(ServicesFile, - ServiceDBData, - sizeof( ServiceDBData ) - 1, - &ReadSize, - NULL)) + else { - ERR("NSP_GetServiceByNameHeapAllocW can't read services file %lx\n", GetLastError()); - CloseHandle(ServicesFile); - return WSANO_RECOVERY; + //ASSERT(data->CallID == NSP_CALLID_SERVICEBYNAME); + result = NSP_GetServiceByNameHeapAllocW(data, + dwControlFlags, + &hostinfo); + if (result != ERROR_SUCCESS) + goto End; } - ThisLine = NextLine = ServiceDBData; - EndValid = ServiceDBData + ReadSize; - ServiceDBData[sizeof(ServiceDBData) - 1] = '\0'; - - while (ReadSize) - { - for (; *NextLine != '\r' && *NextLine != '\n'; NextLine++) - { - if (NextLine == EndValid) - { - int LineLen = NextLine - ThisLine; - - if (ThisLine == ServiceDBData) - { - ERR("NSP_GetServiceByNameHeapAllocW line too long\n"); - CloseHandle(ServicesFile); - return WSANO_RECOVERY; - } - - memmove(ServiceDBData, ThisLine, LineLen); - - if (!ReadFile(ServicesFile, - ServiceDBData + LineLen, - sizeof( ServiceDBData )-1 - LineLen, - &ReadSize, - NULL)) - { - break; - } - - EndValid = ServiceDBData + LineLen + ReadSize; - NextLine = ServiceDBData + LineLen; - ThisLine = ServiceDBData; - - if (!ReadSize) break; - } - } - - *NextLine = '\0'; - Comment = strchr(ThisLine, '#'); - - if (Comment) - *Comment = '\0'; /* Terminate at comment start */ - - if (DecodeServEntFromString(ThisLine, - &ServiceName, - &PortNumberStr, - &ProtocolStr, - Aliases, - WS2_INTERNAL_MAX_ALIAS) && - (strlen(nameProtoA) == 0 || strcmp(ProtocolStr, nameProtoA) == 0)) - { - Found = (strcmp(ServiceName, nameServiceA) == 0 || strcmp(PortNumberStr, nameServiceA) == 0); - AliasPtr = Aliases; - while ((!Found) && (*AliasPtr != NULL)) - { - Found = (strcmp(*AliasPtr, nameServiceA) == 0); - AliasPtr++; - } - if (Found) - break; - } - NextLine++; - ThisLine = NextLine; - } - - /* This we'll do no matter what */ - CloseHandle(ServicesFile); - - if (!Found) - { - ERR("NSP_GetServiceByNameHeapAllocW service not found\n"); - return WSANO_DATA; - } - - hostinfo->addr4 = 0; - hostinfo->servnameW = StrA2WHeapAlloc(hHeap, ServiceName); - hostinfo->servprotoW = StrA2WHeapAlloc(hHeap, ProtocolStr); - hostinfo->servaliasesA = StrAryCpyHeapAllocA(hHeap, (char**)&Aliases); - hostinfo->servport = atoi(PortNumberStr); - - res = NO_ERROR; - -End: - if (nameA) - HeapFree(hHeap, 0, nameA); - - if (nameServiceA) - HeapFree(hHeap, 0, nameServiceA); - - return res; -} - -INT -NSP_LookupServiceNextW(_In_ PWSHANDLEINTERN data, - _In_ DWORD dwControlFlags, - _Inout_ LPWSAQUERYSETW lpRes, - _Inout_ LPDWORD lpResLen) -{ - MSW_BUFFER buf; - WSHOSTINFOINTERN hostinfo; - INT result; - HANDLE hHeap = GetProcessHeap(); - WCHAR* ServiceInstanceNameW = NULL; - /* cleanup-vars */ - CHAR* ServiceInstanceNameA = NULL; - CHAR* ServiceProtocolNameA = NULL; - - TRACE("NSP_LookupServiceNextW %p %lx %p %p\n", data, dwControlFlags, lpRes, lpResLen); - if (!data || (dwControlFlags & (~(DWORD)LUP_FLUSHPREVIOUS)) != 0 || !lpRes || !lpResLen || *lpResLen == 0) - return WSAEINVAL; - RtlZeroMemory(&hostinfo, sizeof(hostinfo)); - - /* init and build result-buffer */ - mswBufferInit(&buf, (BYTE*)lpRes, *lpResLen); - mswBufferIncUsed(&buf, sizeof(*lpRes)); - - /* QueryDataSet-Size without "blob-data"-size! */ - lpRes->dwSize = sizeof(*lpRes); - lpRes->dwNameSpace = NS_DNS; - - if ((data->CallID == NSP_CALLID_HOSTNAME) || - (data->CallID == NSP_CALLID_HOSTBYNAME) || - (data->CallID == NSP_CALLID_SERVICEBYNAME)) - { - /* FIXME remember what was returned and continue from there */ - if (data->CallIDCounter >= 1) - { - ERR("NSP_LookupServiceNextW LUP_FLUSHPREVIOUS and more than one call not supported yet\n", data, dwControlFlags, lpRes, lpResLen); - result = WSA_E_NO_MORE; - goto End; - } - } - else - { - ERR("NSP_LookupServiceNextW unsupported CallID %lx\n", data->CallID); - result = WSAEOPNOTSUPP; - goto End; - } - data->CallIDCounter++; - - if (data->CallID == NSP_CALLID_HOSTNAME) - { - result = NSP_GetHostNameHeapAllocW(&hostinfo.hostnameW); - - if (result != ERROR_SUCCESS) - goto End; - - hostinfo.addr4 = 0; - } - else if (data->CallID == NSP_CALLID_HOSTBYNAME) - { - result = NSP_GetHostByNameHeapAllocW(data, - dwControlFlags, - &hostinfo); - if (result != ERROR_SUCCESS) - goto End; - } - else - { - //ASSERT(data->CallID == NSP_CALLID_SERVICEBYNAME); - result = NSP_GetServiceByNameHeapAllocW(data, - dwControlFlags, - &hostinfo); - if (result != ERROR_SUCCESS) - goto End; - } - - if (((LUP_RETURN_BLOB & data->dwControlFlags) != 0) || - ((LUP_RETURN_NAME & data->dwControlFlags) != 0)) + if (((LUP_RETURN_BLOB & data->dwControlFlags) != 0) || + ((LUP_RETURN_NAME & data->dwControlFlags) != 0)) { if (data->CallID == NSP_CALLID_HOSTNAME || data->CallID == NSP_CALLID_HOSTBYNAME) { @@ -1117,6 +793,289 @@ End: return result; } +INT +WSAAPI +mwsNSPCleanUp(_In_ LPGUID lpProviderId) +{ + return ERROR_SUCCESS; +} + +INT +mwsNSPInit(VOID) +{ + return ERROR_SUCCESS; +} + +INT +WSAAPI +mwsNSPLookupServiceBegin(_In_ LPGUID lpProviderId, + _In_ LPWSAQUERYSETW lpqsRestrictions, + _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo, + _In_ DWORD dwControlFlags, + _Out_ LPHANDLE lphLookup) +{ + PWSHANDLEINTERN pLook; + int wsaErr; + + TRACE("mwsNSPLookupServiceBegin %p %p %p %lx %p\n", lpProviderId, lpqsRestrictions, lpServiceClassInfo, dwControlFlags, lphLookup); + if (IsEqualGUID(lpProviderId, &guid_mswsock_TcpIp)) + { + //OK + TRACE("TCPIP query\n"); + } + else if (IsEqualGUID(lpProviderId, &guid_mswsock_NLA)) + { + ERR("NLA queries are not supported yet\n"); + WSASetLastError(WSASERVICE_NOT_FOUND); + return SOCKET_ERROR; + } + else + { + ERR("Unsupported GUID\n"); + return ERROR_CALL_NOT_IMPLEMENTED; + } + + /* allocate internal structure */ + pLook = HeapAlloc(GetProcessHeap(), 0, sizeof(WSHANDLEINTERN)); + if (!pLook) + { + ERR("Error allocating %d for handle\n", sizeof(WSHANDLEINTERN)); + WSASetLastError(WSAEFAULT); + return SOCKET_ERROR; + } + + *lphLookup = (HANDLE)pLook; + + RtlZeroMemory(pLook, sizeof(*pLook)); + + /* Anyway the ControlFlags "should" be needed + in NSPLookupServiceNext. (see doku) But + thats not the fact ATM. */ + pLook->dwControlFlags = dwControlFlags; + pLook->providerId = *lpProviderId; + +#ifdef NSP_REDIRECT + + if (IsEqualGUID(lpProviderId, &guid_mswsock_TcpIp)) + { + pLook->rdrproc = rdrproc_tcpip; + } + else if (IsEqualGUID(lpProviderId, &guid_mswsock_NLA)) + { + pLook->rdrproc = rdrproc_nla; + } + else + { + return ERROR_CALL_NOT_IMPLEMENTED; + } + + if (pLook->rdrproc.NSPLookupServiceBegin(lpProviderId, + lpqsRestrictions, + lpServiceClassInfo, + dwControlFlags, + &pLook->rdrLookup) == NO_ERROR) + { + wsaErr = NO_ERROR; + } + else + { + wsaErr = WSAGetLastError(); + } + + /* + if (res) + res = WSAGetLastError(); + */ + +#else /* NSP_REDIRECT */ + + wsaErr = ERROR_CALL_NOT_IMPLEMENTED; + if (IsEqualGUID(lpqsRestrictions->lpServiceClassId, &guid_NULL)) + { + ERR("NULL GUID service class is not implemented yet\n"); + wsaErr = ERROR_CALL_NOT_IMPLEMENTED; + } + else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId, &guid_HOSTNAME)) + { + TRACE("HOSTNAME GUID\n"); + wsaErr = NSP_LookupServiceBeginW(pLook, + NULL, + NULL, + NSP_CALLID_HOSTNAME); + } + else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId, + &guid_INET_HOSTADDRBYNAME)) + { + TRACE("INET_HOSTADDRBYNAME GUID\n"); + wsaErr = NSP_LookupServiceBeginW(pLook, + NULL, + lpqsRestrictions->lpszServiceInstanceName, + NSP_CALLID_HOSTBYNAME); + } + else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId, + &guid_INET_SERVICEBYNAME)) + { + TRACE("INET_SERVICEBYNAME\n"); + wsaErr = NSP_LookupServiceBeginW(pLook, + NULL, + lpqsRestrictions->lpszServiceInstanceName, + NSP_CALLID_SERVICEBYNAME); + } + else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId, + &guid_INET_HOSTADDRBYINETSTRING)) + { + ERR("INET_HOSTADDRBYINETSTRING GUID service class is not implemented yet\n"); + wsaErr = ERROR_CALL_NOT_IMPLEMENTED; + } + +#endif /* NSP_REDIRECT */ + + if (wsaErr != NO_ERROR) + { + ERR("mwsNSPLookupServiceBegin wsaErr = %d\n", wsaErr); + WSASetLastError(wsaErr); + return SOCKET_ERROR; + } + return NO_ERROR; +} + +INT +WSAAPI +mwsNSPLookupServiceNext(_In_ HANDLE hLookup, + _In_ DWORD dwControlFlags, + _Inout_ LPDWORD lpdwBufferLength, + //_Out_writes_bytes_to_(*lpdwBufferLength, *lpdwBufferLength) + LPWSAQUERYSETW lpqsResults) +{ + PWSHANDLEINTERN pLook = hLookup; + int wsaErr = 0; + + TRACE("mwsNSPLookupServiceNext %p %lx %p %p\n", pLook, dwControlFlags, lpdwBufferLength, lpqsResults); +#ifdef NSP_REDIRECT + + INT res = pLook->rdrproc.NSPLookupServiceNext(pLook->rdrLookup, + dwControlFlags, + lpdwBufferLength, + lpqsResults); + wsaErr = WSAGetLastError(); + if (res != ERROR_SUCCESS) + { + wsaErr = WSAGetLastError(); + + if (wsaErr == 0) + wsaErr = 0xFFFFFFFF; + } + +#else /* NSP_REDIRECT */ + + if ((lpdwBufferLength == NULL) || (*lpdwBufferLength == 0)) + { + wsaErr = WSA_NOT_ENOUGH_MEMORY; + goto End; + } + + RtlZeroMemory(lpqsResults, *lpdwBufferLength); + lpqsResults->dwSize = sizeof(*lpqsResults); + + wsaErr = NSP_LookupServiceNextW(pLook, + dwControlFlags, + lpqsResults, + lpdwBufferLength); + + +#endif /* NSP_REDIRECT */ + +End: + if (wsaErr != 0) + { + ERR("mwsNSPLookupServiceNext wsaErr = %d\n", wsaErr); + WSASetLastError(wsaErr); + return SOCKET_ERROR; + } + return NO_ERROR; +} + +INT +WSAAPI +mwsNSPIoCtl(_In_ HANDLE hLookup, + _In_ DWORD dwControlCode, + _In_reads_bytes_(cbInBuffer) LPVOID lpvInBuffer, + _In_ DWORD cbInBuffer, + _Out_writes_bytes_to_(cbOutBuffer, *lpcbBytesReturned) LPVOID lpvOutBuffer, + _In_ DWORD cbOutBuffer, + _Out_ LPDWORD lpcbBytesReturned, + _In_opt_ LPWSACOMPLETION lpCompletion, + _In_ LPWSATHREADID lpThreadId) +{ + ERR("mwsNSPIoCtl not implemented %p %lx %p %ld %p %ld %p %p %p\n", hLookup, dwControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpCompletion, lpThreadId); + WSASetLastError(WSAEOPNOTSUPP); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +INT +WSAAPI +mwsNSPLookupServiceEnd(_In_ HANDLE hLookup) +{ + PWSHANDLEINTERN pLook = (PWSHANDLEINTERN)hLookup; + HANDLE hHeap = GetProcessHeap(); + INT res = NO_ERROR; + + TRACE("mwsNSPLookupServiceEnd %p\n", pLook); +#ifdef NSP_REDIRECT + res = pLook->rdrproc.NSPLookupServiceEnd(pLook->rdrLookup); +#endif + + if (pLook->hostnameW != NULL) + HeapFree(hHeap, 0, pLook->hostnameW); + + HeapFree(hHeap, 0, pLook); + return res; +} + +INT +WSAAPI +mwsNSPSetService(_In_ LPGUID lpProviderId, + _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo, + _In_ LPWSAQUERYSETW lpqsRegInfo, + _In_ WSAESETSERVICEOP essOperation, + _In_ DWORD dwControlFlags) +{ + ERR("mwsNSPSetService not implemented %p %p %p %d %lx %ld %p %p %p\n", lpProviderId, lpServiceClassInfo, lpqsRegInfo, essOperation, dwControlFlags); + WSASetLastError(WSAEOPNOTSUPP); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +INT +WSAAPI +mwsNSPInstallServiceClass(_In_ LPGUID lpProviderId, + _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo) +{ + ERR("mwsNSPInstallServiceClass not implemented %p %p\n", lpProviderId, lpServiceClassInfo); + WSASetLastError(WSAEOPNOTSUPP); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +INT +WSAAPI +mwsNSPRemoveServiceClass(_In_ LPGUID lpProviderId, + _In_ LPGUID lpServiceClassId) +{ + ERR("mwsNSPRemoveServiceClass not implemented %p %p\n", lpProviderId, lpServiceClassId); + WSASetLastError(WSAEOPNOTSUPP); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +INT +WSAAPI +mwsNSPGetServiceClassInfo(_In_ LPGUID lpProviderId, + _In_ LPDWORD lpdwBufSize, + _In_ LPWSASERVICECLASSINFOW lpServiceClassInfo) +{ + ERR("mwsNSPGetServiceClassInfo not implemented %p %p %p\n", lpProviderId, lpdwBufSize, lpServiceClassInfo); + WSASetLastError(WSAEOPNOTSUPP); + return ERROR_CALL_NOT_IMPLEMENTED; +} + /* Implementations - Exports */ /* * @implemented -- 2.17.1