L
O
L
On Tue, Sep 20, 2016 at 6:32 PM, Alex Ionescu <ionucu(a)videotron.ca
<mailto:ionucu@videotron.ca>> wrote:
My winsock branch already has full support for an NSP. It's 8 years
old now, maybe someone should mergei t.
Best regards,
Alex Ionescu
On Sun, Sep 18, 2016 at 2:21 PM, <akhaldi(a)svn.reactos.org
<mailto:akhaldi@svn.reactos.org>> wrote:
Author: akhaldi
Date: Sun Sep 18 21:21:28 2016
New Revision: 72735
URL:
http://svn.reactos.org/svn/reactos?rev=72735&view=rev
<http://svn.reactos.org/svn/reactos?rev=72735&view=rev>
Log:
[MSWSOCK] Partially implement Name Service Provider in mswsock.
Brought to you
by Andreas Maier aka andy-123 with small fixes by
Peter Hater and formatting by me. CORE-10024 CORE-10440
Added:
trunk/reactos/dll/win32/mswsock/mswhelper.c (with props)
trunk/reactos/dll/win32/mswsock/mswhelper.h (with props)
trunk/reactos/dll/win32/mswsock/nsplookup.c (with props)
Modified:
trunk/reactos/dll/win32/mswsock/CMakeLists.txt
trunk/reactos/dll/win32/mswsock/stubs.c
Modified: trunk/reactos/dll/win32/mswsock/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/CMakeLis…
<http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/CMakeLists.txt?rev=72735&r1=72734&r2=72735&view=diff>
==============================================================================
---
trunk/reactos/dll/win32/mswsock/CMakeLists.txt
[iso-8859-1] (original)
+++
trunk/reactos/dll/win32/mswsock/CMakeLists.txt
[iso-8859-1] Sun Sep 18
21:21:28 2016
> @@ -5,6 +5,8 @@
> list(APPEND SOURCE
> extensions.c
> + mswhelper.c
> + nsplookup.c
> stubs.c
> precomp.h)
> @@ -13,7 +15,7 @@
> mswsock.rc
> ${CMAKE_CURRENT_BINARY_DIR}/mswsock.def)
> -set_module_type(mswsock win32dll
UNICODE)
> -add_importlibs(mswsock ws2_32 msvcrt kernel32)
> +set_module_type(mswsock win32dll)
> +add_importlibs(mswsock ws2_32 dnsapi msvcrt kernel32)
> add_pch(mswsock precomp.h SOURCE)
> add_cd_file(TARGET mswsock DESTINATION reactos/system32 FOR all)
> Added:
trunk/reactos/dll/win32/mswsock/mswhelper.c
> URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/mswhelpe…
<http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/mswhelper.c?rev=72735>
==============================================================================
--- trunk/reactos/dll/win32/mswsock/mswhelper.c
(added)
+++ trunk/reactos/dll/win32/mswsock/mswhelper.c [iso-8859-1] Sun
Sep 18
21:21:28 2016
@@ -0,0 +1,576 @@
+
+#include "precomp.h"
+
+#include <winuser.h>
+#include <winnls.h>
+#include <wchar.h>
+#include <sal.h>
+
+#include "mswhelper.h"
+
+#define MSW_BUFSIZE 512
+#define MAX_ARRAY_SIZE 5
+
+void
+mswBufferInit(_Inout_ PMSW_BUFFER mswBuf,
+ _In_ BYTE* buffer,
+ _In_ DWORD bufferSize)
+{
+ RtlZeroMemory(mswBuf, sizeof(*mswBuf));
+ RtlZeroMemory(buffer, bufferSize);
+ mswBuf->bytesMax = bufferSize;
+ mswBuf->buffer = buffer;
+ mswBuf->bufendptr = buffer;
+ mswBuf->bufok = TRUE;
+}
+
+BOOL
+mswBufferCheck(_Inout_ PMSW_BUFFER mswBuf,
+ _In_ DWORD count)
+{
+ if (mswBuf->bytesUsed + count <= mswBuf->bytesMax)
+ return TRUE;
+
+ mswBuf->bufok = FALSE;
+ return FALSE;
+}
+
+BOOL
+mswBufferIncUsed(_Inout_ PMSW_BUFFER mswBuf,
+ _In_ DWORD count)
+{
+ if (!mswBufferCheck(mswBuf, count))
+ return FALSE;
+
+ mswBuf->bytesUsed += count;
+ mswBuf->bufendptr += count;
+ return TRUE;
+}
+
+inline
+BYTE*
+mswBufferEndPtr(_Inout_ PMSW_BUFFER mswBuf)
+{
+ return mswBuf->bufendptr;
+}
+
+BOOL
+mswBufferAppend(_Inout_ PMSW_BUFFER mswBuf,
+ _In_ void *dataToAppend,
+ _In_ DWORD dataSize)
+{
+ if (!mswBufferCheck(mswBuf, dataSize))
+ return FALSE;
+
+ RtlCopyMemory(mswBuf->bufendptr, dataToAppend, dataSize);
+ mswBuf->bytesUsed += dataSize;
+ mswBuf->bufendptr += dataSize;
+
+ return TRUE;
+}
+
+BOOL mswBufferAppendStrA(_Inout_ PMSW_BUFFER mswBuf,
+ _In_ char* str)
+{
+ return mswBufferAppend(mswBuf, str, strlen(str) +
sizeof(char));
+}
+
+BOOL
+mswBufferAppendStrW(_Inout_ PMSW_BUFFER mswBuf,
+ _In_ WCHAR* str)
+{
+ int bytelen = (wcslen(str) + 1) * sizeof(WCHAR);
+ return mswBufferAppend(mswBuf, str, bytelen);
+}
+
+BOOL
+mswBufferAppendPtr(_Inout_ PMSW_BUFFER mswBuf,
+ _In_ void* ptr)
+{
+ return mswBufferAppend(mswBuf, &ptr, sizeof(ptr));
+}
+
+/* lst = pointer to pointer of items
+
+ *lst[0] = 1st item
+ *lst[1] = 2nd item
+ ...
+ lst[n] = NULL = End of List
+
+ itemLength = data in Bytes for each item.
+
+ ptrofs = delta relative to mswBuf.buffer
+*/
+BOOL
+mswBufferAppendLst(_Inout_ PMSW_BUFFER mswBuf,
+ _In_ void **lst,
+ _In_ DWORD itemByteLength,
+ _In_opt_ int ptrofs)
+{
+ DWORD lstItemCount;
+ DWORD lstByteSize;
+ DWORD lstDataPos;
+ DWORD i1;
+ UINT_PTR *ptrSrcLstPos;
+
+ /* calculate size of list */
+ ptrSrcLstPos = (UINT_PTR*)lst;
+ lstItemCount = 0;
+ while (*ptrSrcLstPos != (UINT_PTR)NULL)
+ {
+ lstItemCount++;
+ ptrSrcLstPos++;
+ }
+
+ lstByteSize = ((lstItemCount + 1) * sizeof(UINT_PTR)) + /*
item-pointer +
null-ptr (for end) */
+ (lstItemCount *
itemByteLength); /* item-data */
+
+ if (mswBuf->bytesUsed + lstByteSize > mswBuf->bytesMax)
+ return FALSE;
+
+ /* calculate position for the data of the first item */
+ lstDataPos = ((lstItemCount + 1) * sizeof(UINT_PTR)) +
+ (DWORD)mswBufferEndPtr(mswBuf);
+ /* add ptrofs */
+ lstDataPos += ptrofs;
+
+ /* write array of Pointer to data */
+ for (i1 = 0; i1 < lstItemCount; i1++)
+ {
+ if (!mswBufferAppendPtr(mswBuf, (void*)lstDataPos))
+ return FALSE;
+
+ lstDataPos += sizeof(UINT_PTR);
+ }
+
+ /* end of list */
+ if (!mswBufferAppendPtr(mswBuf, NULL))
+ return FALSE;
+
+ /* write data */
+ ptrSrcLstPos = (UINT_PTR*)lst;
+ for (i1 = 0; i1 < lstItemCount; i1++)
+ {
+ mswBufferAppend(mswBuf, *(BYTE**)ptrSrcLstPos,
itemByteLength);
+ ptrSrcLstPos++;
+ }
+ return mswBuf->bufok;
+}
+
+BOOL
+mswBufferAppendStrLstA(_Inout_ PMSW_BUFFER mswBuf,
+ _In_ void **lst,
+ _In_opt_ int ptrofs)
+{
+ DWORD lstItemLen[MAX_ARRAY_SIZE];
+ DWORD lstItemCount;
+ DWORD lstByteSize;
+ DWORD lstDataPos;
+ DWORD lstDataSize;
+ DWORD i1;
+ UINT_PTR *ptrSrcLstPos;
+
+ /* calculate size of list */
+ ptrSrcLstPos = (UINT_PTR*)lst;
+ lstItemCount = 0;
+ lstDataSize = 0;
+
+ while (*ptrSrcLstPos != (UINT_PTR)NULL)
+ {
+ if (lstItemCount >= MAX_ARRAY_SIZE)
+ return FALSE;
+
+ i1 = strlen((char*)*ptrSrcLstPos) + sizeof(char);
+ lstItemLen[lstItemCount] = i1;
+ lstItemCount++;
+ lstDataSize += i1;
+ ptrSrcLstPos++;
+ }
+
+ lstByteSize = ((lstItemCount + 1) * sizeof(UINT_PTR)) + /*
item-pointer +
null-ptr (for end) */
+ lstDataSize; /* item-data */
+
+ if (mswBuf->bytesUsed + lstByteSize > mswBuf->bytesMax)
+ return FALSE;
+
+ /* calculate position for the data of the first item */
+ lstDataPos = ((lstItemCount + 1) * sizeof(UINT_PTR)) +
+ (DWORD)mswBufferEndPtr(mswBuf);
+
+ /* add ptrofs */
+ lstDataPos += ptrofs;
+
+ for (i1 = 0; i1 < lstItemCount; i1++)
+ {
+ if (!mswBufferAppendPtr(mswBuf, (void*)lstDataPos))
+ return FALSE;
+
+ lstDataPos += lstItemLen[i1];
+ }
+
+ /* end of list */
+ if (!mswBufferAppendPtr(mswBuf, NULL))
+ return FALSE;
+
+ /* write data */
+ ptrSrcLstPos = (UINT_PTR*)lst;
+ for (i1 = 0; i1 < lstItemCount; i1++)
+ {
+ if (!mswBufferAppendStrA(mswBuf, *(char**)ptrSrcLstPos))
+ return FALSE;
+
+ ptrSrcLstPos++;
+ }
+ return mswBuf->bufok;
+}
+
+BOOL
+mswBufferAppendBlob_Hostent(_Inout_ PMSW_BUFFER mswBuf,
+ _Inout_ LPWSAQUERYSETW lpRes,
+ _In_ char* hostnameA,
+ _In_ DWORD ip4addr)
+{
+ PHOSTENT phe;
+ void* lst[2];
+ BYTE* bytesOfs;
+
+ /* blob */
+ lpRes->lpBlob = (LPBLOB)mswBufferEndPtr(mswBuf);
+
+ if (!mswBufferIncUsed(mswBuf, sizeof(*lpRes->lpBlob)))
+ return FALSE;
+
+ /* cbSize will be set later */
+ lpRes->lpBlob->cbSize = 0;
+ lpRes->lpBlob->pBlobData = mswBufferEndPtr(mswBuf);
+
+ /* hostent */
+ phe = (PHOSTENT)lpRes->lpBlob->pBlobData;
+ bytesOfs = mswBufferEndPtr(mswBuf);
+
+ if (!mswBufferIncUsed(mswBuf, sizeof(*phe)))
+ return FALSE;
+
+ phe->h_addrtype = AF_INET;
+ phe->h_length = 4; /* 4 Byte (IPv4) */
+
+ /* aliases */
+ phe->h_aliases = (char**)(mswBufferEndPtr(mswBuf) - bytesOfs);
+
+ if (!mswBufferAppendPtr(mswBuf, NULL))
+ return FALSE;
+
+ /* addr_list */
+ RtlZeroMemory(lst, sizeof(lst));
+
+ if (ip4addr != 0)
+ lst[0] = (void*)&ip4addr;
+
+ phe->h_addr_list = (char**)(mswBufferEndPtr(mswBuf) -
bytesOfs);
+
+ if (!mswBufferAppendLst(mswBuf, lst, 4, -(DWORD)bytesOfs))
+ return FALSE;
+
+ /* name */
+ phe->h_name = (char*)(mswBufferEndPtr(mswBuf) - bytesOfs);
+
+ if (!mswBufferAppendStrA(mswBuf, hostnameA))
+ return FALSE;
+
+ lpRes->lpBlob->cbSize = (DWORD)(mswBufferEndPtr(mswBuf) -
bytesOfs);
+ return mswBuf->bufok;
+}
+
+BOOL
+mswBufferAppendBlob_Servent(_Inout_ PMSW_BUFFER mswBuf,
+ _Inout_ LPWSAQUERYSETW lpRes,
+ _In_ char* serviceNameA,
+ _In_ char** serviceAliasesA,
+ _In_ char* protocolNameA,
+ _In_ WORD port)
+{
+ PSERVENT pse;
+ BYTE* bytesOfs;
+
+ /* blob */
+ lpRes->lpBlob = (LPBLOB)mswBufferEndPtr(mswBuf);
+
+ if (!mswBufferIncUsed(mswBuf, sizeof(*lpRes->lpBlob)))
+ return FALSE;
+
+ lpRes->lpBlob->cbSize = 0;//later
+ lpRes->lpBlob->pBlobData = mswBufferEndPtr(mswBuf);
+
+ /* servent */
+ pse = (LPSERVENT)lpRes->lpBlob->pBlobData;
+ bytesOfs = mswBufferEndPtr(mswBuf);
+
+ if (!mswBufferIncUsed(mswBuf, sizeof(*pse)))
+ return FALSE;
+
+ pse->s_aliases = (char**)(mswBufferEndPtr(mswBuf) - bytesOfs);
+
+ if (!mswBufferAppendStrLstA(mswBuf,
+ (void**)serviceAliasesA,
+ -(DWORD)bytesOfs))
+ return FALSE;
+
+ pse->s_name = (char*)(mswBufferEndPtr(mswBuf) - bytesOfs);
+
+ if (!mswBufferAppendStrA(mswBuf, serviceNameA))
+ return FALSE;
+
+ pse->s_port = htons(port);
+
+ pse->s_proto = (char*)(mswBufferEndPtr(mswBuf) - bytesOfs);
+
+ if (!mswBufferAppendStrA(mswBuf, protocolNameA))
+ return FALSE;
+
+ lpRes->lpBlob->cbSize = (DWORD)(mswBufferEndPtr(mswBuf) -
bytesOfs);
+ return mswBuf->bufok;
+}
+
+BOOL
+mswBufferAppendAddr_AddrInfoW(_Inout_ PMSW_BUFFER mswBuf,
+ _Inout_ LPWSAQUERYSETW lpRes,
+ _In_ DWORD ip4addr)
+{
+ LPCSADDR_INFO paddrinfo;
+ LPSOCKADDR_IN psa;
+
+ lpRes->dwNumberOfCsAddrs = 1;
+ lpRes->lpcsaBuffer = (LPCSADDR_INFO)mswBufferEndPtr(mswBuf);
+
+ paddrinfo = lpRes->lpcsaBuffer;
+
+ if (!mswBufferIncUsed(mswBuf, sizeof(*paddrinfo)))
+ return FALSE;
+
+ paddrinfo->LocalAddr.lpSockaddr =
(LPSOCKADDR)mswBufferEndPtr(mswBuf);
+
+ if (!mswBufferIncUsed(mswBuf,
sizeof(*paddrinfo->LocalAddr.lpSockaddr)))
+ return FALSE;
+
+ paddrinfo->RemoteAddr.lpSockaddr =
(LPSOCKADDR)mswBufferEndPtr(mswBuf);
+
+ if (!mswBufferIncUsed(mswBuf,
sizeof(*paddrinfo->RemoteAddr.lpSockaddr)))
> + return FALSE;
> +
> + paddrinfo->iSocketType = SOCK_DGRAM;
> + paddrinfo->iProtocol = IPPROTO_UDP;
> +
> + psa = (LPSOCKADDR_IN)paddrinfo->LocalAddr.lpSockaddr;
> + paddrinfo->LocalAddr.iSockaddrLength = sizeof(*psa);
> + psa->sin_family = AF_INET;
> + psa->sin_port = 0;
> + psa->sin_addr.s_addr = 0;
> + RtlZeroMemory(psa->sin_zero, sizeof(psa->sin_zero));
> +
> + psa = (LPSOCKADDR_IN)paddrinfo->RemoteAddr.lpSockaddr;
> + paddrinfo->RemoteAddr.iSockaddrLength = sizeof(*psa);
> + psa->sin_family = AF_INET;
> + psa->sin_port = 0;
> + psa->sin_addr.s_addr = ip4addr;
> + RtlZeroMemory(psa->sin_zero, sizeof(psa->sin_zero));
> +
> + return TRUE;
> +}
> +
> +/* ansicode <-> unicode */
> +WCHAR*
> +StrA2WHeapAlloc(_In_opt_ HANDLE hHeap,
> + _In_ char* aStr)
> +{
> + int aStrByteLen;
> + int wStrByteLen;
> + int charLen;
> + int ret;
> + WCHAR* wStr;
> +
> + if (aStr == NULL)
> + return NULL;
> +
> + charLen = strlen(aStr) + 1;
> +
> + aStrByteLen = (charLen * sizeof(char));
> + wStrByteLen = (charLen * sizeof(WCHAR));
> +
> + if (hHeap == 0)
> + hHeap = GetProcessHeap();
> +
> + wStr = HeapAlloc(hHeap, 0, wStrByteLen);
> + if (wStr == NULL)
> + {
> + HeapFree(hHeap, 0, wStr);
> + return NULL;
> + }
> +
> + ret = MultiByteToWideChar(1252,
> + 0,
> + aStr,
> + aStrByteLen,
> + wStr,
> + charLen);
> +
> + if (ret != charLen)
> + {
> + HeapFree(hHeap, 0, wStr);
> + return NULL;
> + }
> + return wStr;
> +}
> +
> +char*
> +StrW2AHeapAlloc(_In_opt_ HANDLE hHeap,
> + _In_ WCHAR* wStr)
> +{
> + int charLen;
> + int aStrByteLen;
> + int ret;
> + char* aStr;
> +
> + if (wStr == NULL)
> + return NULL;
> +
> + charLen = wcslen(wStr) + 1;
> +
> + aStrByteLen = (charLen * sizeof(char));
> +
> + if (hHeap == 0)
> + hHeap = GetProcessHeap();
> +
> + aStr = HeapAlloc(hHeap, 0, aStrByteLen);
> + if (aStr == NULL)
> + {
> + HeapFree(hHeap, 0, aStr);
> + return NULL;
> + }
> +
> + ret = WideCharToMultiByte(1252,
> + 0,
> + wStr,
> + charLen,
> + aStr,
> + aStrByteLen,
> + NULL,
> + NULL);
> + if (ret != aStrByteLen)
> + {
> + HeapFree(hHeap, 0, aStr);
> + return NULL;
> + }
> + return aStr;
> +}
> +
> +WCHAR*
> +StrCpyHeapAllocW(_In_opt_ HANDLE hHeap,
> + _In_ WCHAR* wStr)
> +{
> + int chLen;
> + int bLen;
> + WCHAR* resW;
> +
> + if (wStr == NULL)
> + return NULL;
> +
> + if (hHeap == 0)
> + hHeap = GetProcessHeap();
> +
> + chLen = wcslen(wStr);
> +
> + bLen = (chLen + 1) * sizeof(WCHAR);
> +
> + resW = HeapAlloc(hHeap, 0, bLen);
> + RtlCopyMemory(resW, wStr, bLen);
> + return resW;
> +}
> +
> +char*
> +StrCpyHeapAllocA(_In_opt_ HANDLE hHeap,
> + _In_ char* aStr)
> +{
> + int chLen;
> + int bLen;
> + char* resA;
> +
> + if (aStr == NULL)
> + return NULL;
> +
> + if (hHeap == 0)
> + hHeap = GetProcessHeap();
> +
> + chLen = strlen(aStr);
> +
> + bLen = (chLen + 1) * sizeof(char);
> +
> + resA = HeapAlloc(hHeap, 0, bLen);
> + RtlCopyMemory(resA, aStr, bLen);
> + return resA;
> +}
> +
> +char**
> +StrAryCpyHeapAllocA(_In_opt_ HANDLE hHeap,
> + _In_ char** aStrAry)
> +{
> + char** aSrcPtr;
> + char** aDstPtr;
> + char* aDstNextStr;
> + DWORD aStrByteLen[MAX_ARRAY_SIZE];
> + int bLen;
> + int bItmLen;
> + int aCount;
> + int i1;
> + char** resA;
> +
> + if (hHeap == 0)
> + hHeap = GetProcessHeap();
> +
> + /* Calculating size of array ... */
> + aSrcPtr = aStrAry;
> + bLen = 0;
> + aCount = 0;
> +
> + while (*aSrcPtr != NULL)
> + {
> + if (aCount >= MAX_ARRAY_SIZE)
> + return NULL;
> +
> + bItmLen = (strlen(*aSrcPtr) + 1) * sizeof(char);
> + aStrByteLen[aCount] = bItmLen;
> +
> + bLen += sizeof(*aSrcPtr) + bItmLen;
> +
> + aSrcPtr++;
> + aCount++;
> + }
> +
> + /* size for NULL-terminator */
> + bLen += sizeof(*aSrcPtr);
> +
> + /* get memory */
> + resA = HeapAlloc(hHeap, 0, bLen);
> +
> + /* copy data */
> + aSrcPtr = aStrAry;
> + aDstPtr = resA;
> +
> + /* pos for the first string */
> + aDstNextStr = (char*)(resA + aCount + 1);
> + for (i1 = 0; i1 < aCount; i1++)
> + {
> + bItmLen = aStrByteLen[i1];
> +
> + *aDstPtr = aDstNextStr;
> + RtlCopyMemory(*aDstPtr, *aSrcPtr, bItmLen);
> +
> + aDstNextStr = (char*)((DWORD)aDstNextStr + (DWORD)bItmLen);
> + aDstPtr++;
> + aSrcPtr++;
> + }
> +
> + /* terminate with NULL */
> + *aDstPtr = NULL;
> +
> + return resA;
> +}
> Propchange:
trunk/reactos/dll/win32/mswsock/mswhelper.c
------------------------------------------------------------------------------
> svn:eol-style = native
> Added:
trunk/reactos/dll/win32/mswsock/mswhelper.h
> URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/mswhelpe…
<http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/mswhelper.h?rev=72735>
==============================================================================
--- trunk/reactos/dll/win32/mswsock/mswhelper.h
(added)
+++ trunk/reactos/dll/win32/mswsock/mswhelper.h [iso-8859-1] Sun
Sep 18
21:21:28 2016
> @@ -0,0 +1,121 @@
> +#ifndef _MSWHELPER_H
> +#define _MSWHELPER_H
> +
> +#include <ws2spi.h>
> +
> +typedef struct {
> + DWORD bytesUsed;
> + DWORD bytesMax;
> + BYTE* buffer;
> + BYTE* bufendptr; // Pointer to the first "unused" byte
> + BOOL bufok; // FALSE if on mswBuffer-Function fails
> +} MSW_BUFFER, *PMSW_BUFFER;
> +
> +void
> +mswBufferInit(
> + _Out_ PMSW_BUFFER mswBuf,
> + _In_ BYTE* buffer,
> + _In_ DWORD bufferSize);
> +
> +inline
> +BOOL
> +mswBufferCheck(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _In_ DWORD count);
> +
> +BOOL
> +mswBufferIncUsed(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _In_ DWORD count);
> +
> +inline
> +BYTE*
> +mswBufferEndPtr(
> + _Inout_ PMSW_BUFFER mswBuf);
> +
> +BOOL
> +mswBufferAppend(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _In_ void *dataToAppend,
> + _In_ DWORD dataSize);
> +
> +BOOL
> +mswBufferAppendStrA(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _In_ char* str);
> +
> +BOOL
> +mswBufferAppendStrW(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _In_ WCHAR* str);
> +
> +BOOL
> +mswBufferAppendPtr(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _In_ void* ptr);
> +
> +BOOL
> +mswBufferAppendLst(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _In_ void **lst,
> + _In_ DWORD itemByteLength,
> + _In_opt_ int deltaofs);
> +
> +BOOL
> +mswBufferAppendStrLstA(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _In_ void **lst,
> + _In_opt_ int ptrofs);
> +
> +BOOL
> +mswBufferAppendBlob_Hostent(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _Inout_ LPWSAQUERYSETW lpRes,
> + _In_ char* hostnameA,
> + _In_ DWORD ip4addr);
> +
> +BOOL
> +mswBufferAppendBlob_Servent(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _Inout_ LPWSAQUERYSETW lpRes,
> + _In_ char* serviceNameA,
> + _In_ char** serviceAliasesA,
> + _In_ char* protocolNameA,
> + _In_ WORD port);
> +
> +BOOL
> +mswBufferAppendAddr_AddrInfoW(
> + _Inout_ PMSW_BUFFER mswBuf,
> + _Inout_ LPWSAQUERYSETW lpRes,
> + _In_ DWORD ip4addr);
> +
> +WCHAR*
> +StrA2WHeapAlloc(
> + _In_opt_ HANDLE hHeap,
> + _In_ char* aStr);
> +
> +char*
> +StrW2AHeapAlloc(
> + _In_opt_ HANDLE hHeap,
> + _In_ WCHAR* wStr);
> +
> +WCHAR*
> +StrCpyHeapAllocW(
> + _In_opt_ HANDLE hHeap,
> + _In_ WCHAR* wStr);
> +
> +char*
> +StrCpyHeapAllocA(
> + _In_opt_ HANDLE hHeap,
> + _In_ char* aStr);
> +
> +/* strary:
> + ptr1 ... ptrn \0
> + data1 ... datan
> +*/
> +char**
> +StrAryCpyHeapAllocA(
> + _In_opt_ HANDLE hHeap,
> + _In_ char** aStrAry);
> +
> +#endif // _MSWHELPER_H
> Propchange:
trunk/reactos/dll/win32/mswsock/mswhelper.h
------------------------------------------------------------------------------
> svn:eol-style = native
> Added:
trunk/reactos/dll/win32/mswsock/nsplookup.c
> URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/nsplooku…
<http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/nsplookup.c?rev=72735>
==============================================================================
--- trunk/reactos/dll/win32/mswsock/nsplookup.c
(added)
+++ trunk/reactos/dll/win32/mswsock/nsplookup.c [iso-8859-1] Sun
Sep 18
21:21:28 2016
@@ -0,0 +1,1233 @@
+#include "precomp.h"
+
+#include <stdlib.h>
+#include <ws2spi.h>
+#include <nspapi.h>
+#include <windef.h>
+#include <winuser.h>
+#include <windns.h>
+#include <guiddef.h>
+#include <svcguid.h>
+#include <iptypes.h>
+#include <strsafe.h>
+
+#include "mswhelper.h"
+
+#define NSP_CALLID_DNS 0x0001
+#define NSP_CALLID_HOSTNAME 0x0002
+#define NSP_CALLID_HOSTBYNAME 0x0003
+#define NSP_CALLID_SERVICEBYNAME 0x0004
+
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif // BUFSIZ
+#ifndef WS2_INTERNAL_MAX_ALIAS
+#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;
+} 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 */
+#ifdef NSP_REDIRECT
+ HANDLE rdrLookup;
+ NSP_ROUTINE rdrproc;
+#endif
+} WSHANDLEINTERN, *PWSHANDLEINTERN;
+
+static const GUID guid_NULL = {0};
+static const GUID guid_HOSTNAME = SVCID_HOSTNAME;
+static const GUID guid_INET_HOSTADDRBYINETSTRING =
SVCID_INET_HOSTADDRBYINETSTRING;
+static const GUID guid_INET_HOSTADDRBYNAME =
SVCID_INET_HOSTADDRBYNAME;
+static const GUID guid_INET_SERVICEBYNAME =
SVCID_INET_SERVICEBYNAME;
+
+/* GUIDs - maybe they should be loaded from registry? */
+/* Namespace: 32 */
+static const GUID guid_mswsock_TcpIp = {/*Data1:*/ 0x22059D40,
+ /*Data2:*/ 0x7E9E,
+ /*Data3:*/ 0x11CF,
+ /*Data4:*/ {0xAE, 0x5A,
0x00, 0xAA,
0x00, 0xA7, 0x11, 0x2B}};
+
+/* {6642243A-3BA8-4AA6-BAA5-2E0BD71FDD83} */
+/* Namespace: 15 */
+static const GUID guid_mswsock_NLA = {/*Data1:*/ 0x6642243A,
+ /*Data2:*/ 0x3BA8,
+ /*Data3:*/ 0x4AA6,
+ /*Data4:*/ {0xBA, 0xA5,
0x2E, 0x0B,
0xD7, 0x1F, 0xDD, 0x83}};
+
+#ifdef NSP_REDIRECT
+
+typedef INT
+(CALLBACK *lpRdrNSPStartup)(
+ LPGUID lpProviderId,
+ LPNSP_ROUTINE lpRout);
+
+const rdrLib = "mswsock.dll-original";
+lpRdrNSPStartup rdrNSPStartup;
+HANDLE hLib;
+NSP_ROUTINE rdrproc_tcpip;
+NSP_ROUTINE rdrproc_nla;
+
+#endif /* NSP_REDIRECT */
+
+/* Forwards */
+INT
+WINAPI
+mswNSPStartup(
+ LPGUID lpProviderId,
+ LPNSP_ROUTINE lpRout);
+
+INT
+NSP_LookupServiceBeginW(
+ PWSHANDLEINTERN data,
+ CHAR* hostnameA,
+ WCHAR* hostnameW,
+ DWORD CallID);
+
+INT
+NSP_LookupServiceNextW(
+ _In_ PWSHANDLEINTERN data,
+ _In_ DWORD CallID,
+ _Inout_ LPWSAQUERYSETW lpRes,
+ _Inout_ LPDWORD lpResLen);
+
+INT
+NSP_GetHostNameHeapAllocW(
+ _Out_ WCHAR** hostname);
+
+INT
+NSP_GetHostByNameHeapAllocW(
+ _In_ WCHAR* name,
+ _In_ GUID* lpProviderId,
+ _Out_ PWSHOSTINFOINTERN hostinfo);
+
+INT
+NSP_GetServiceByNameHeapAllocW(
+ _In_ WCHAR* nameW,
+ _In_ GUID* lpProviderId,
+ _Out_ PWSHOSTINFOINTERN hostinfo);
+
+/* Implementations - Internal */
+
+INT
+WSAAPI
+mwsNSPCleanUp(_In_ LPGUID lpProviderId)
+{
+ //WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ //return ERROR_CALL_NOT_IMPLEMENTED;
+ 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;
+
+ if (IsEqualGUID(lpProviderId, &guid_mswsock_TcpIp))
+ {
+ //OK
+ }
+ else if (IsEqualGUID(lpProviderId, &guid_mswsock_NLA))
+ {
+ WSASetLastError(WSASERVICE_NOT_FOUND);
+ return SOCKET_ERROR;
+ }
+ else
+ {
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+
+ /* allocate internal structure */
+ pLook = HeapAlloc(GetProcessHeap(), 0, sizeof(WSHANDLEINTERN));
+ if (!pLook)
+ {
+ 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))
+ {
+ wsaErr = ERROR_CALL_NOT_IMPLEMENTED;
+ }
+ else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId,
&guid_HOSTNAME))
+ {
+ wsaErr = NSP_LookupServiceBeginW(pLook,
+ NULL,
+ NULL,
+ NSP_CALLID_HOSTNAME);
+ }
+ else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId,
+ &guid_INET_HOSTADDRBYNAME))
+ {
+ wsaErr = NSP_LookupServiceBeginW(pLook,
+ NULL,
+ lpqsRestrictions->lpszServiceInstanceName,
+ NSP_CALLID_HOSTBYNAME);
+ }
+ else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId,
+ &guid_INET_SERVICEBYNAME))
+ {
+ wsaErr = NSP_LookupServiceBeginW(pLook,
+ NULL,
+ lpqsRestrictions->lpszServiceInstanceName,
+ NSP_CALLID_SERVICEBYNAME);
+ }
+ else if (IsEqualGUID(lpqsRestrictions->lpServiceClassId,
+ &guid_INET_HOSTADDRBYINETSTRING))
+ {
+ wsaErr = ERROR_CALL_NOT_IMPLEMENTED;
+ }
+
+#endif /* NSP_REDIRECT */
+
+ if (wsaErr != NO_ERROR)
+ {
+ 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;
+
+#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,
+ pLook->CallID,
+ lpqsResults,
+ lpdwBufferLength);
+
+
+#endif /* NSP_REDIRECT */
+
+End:
+ if (wsaErr != 0)
+ {
+ 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)
+{
+ WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+INT
+WSAAPI
+mwsNSPLookupServiceEnd(_In_ HANDLE hLookup)
+{
+ PWSHANDLEINTERN pLook;
+ HANDLE hHeap;
+ INT res;
+
+ res = NO_ERROR;
+ pLook = (PWSHANDLEINTERN)hLookup;
+ hHeap = GetProcessHeap();
+
+#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)
+{
+ WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+INT
+WSAAPI
+mwsNSPInstallServiceClass(_In_ LPGUID lpProviderId,
+ _In_ LPWSASERVICECLASSINFOW
lpServiceClassInfo)
+{
+ WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+INT
+WSAAPI
+mwsNSPRemoveServiceClass(_In_ LPGUID lpProviderId,
+ _In_ LPGUID lpServiceClassId)
+{
+ WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+INT
+WSAAPI
+mwsNSPGetServiceClassInfo(_In_ LPGUID lpProviderId,
+ _In_ LPDWORD lpdwBufSize,
+ _In_ LPWSASERVICECLASSINFOW
lpServiceClassInfo)
+{
+ WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ 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)
+{
+ HANDLE hHeap;
+
+ if (data->CallID != 0)
+ return WSAEFAULT;
+
+ data->CallID = CallID;
+
+ if ((CallID == NSP_CALLID_HOSTBYNAME) ||
+ (CallID == NSP_CALLID_SERVICEBYNAME))
+ {
+ hHeap = GetProcessHeap();
+
+ if (data->hostnameW != NULL)
+ HeapFree(hHeap, 0, data->hostnameW);
+
+ if (hostnameA != NULL)
+ {
+ data->hostnameW = StrA2WHeapAlloc(hHeap, hostnameA);
+ }
+ else
+ {
+ data->hostnameW = StrCpyHeapAllocW(hHeap, hostnameW);
+ }
+ }
+
+ WSASetLastError(0);
+
+ return ERROR_SUCCESS;
+}
+
+INT
+NSP_GetHostNameHeapAllocW(_Out_ WCHAR** hostname)
+{
+ WCHAR* name;
+ HANDLE hHeap = GetProcessHeap();
+ DWORD bufCharLen = MAX_COMPUTERNAME_LENGTH + 1;
+ DWORD bufByteLen = bufCharLen * sizeof(WCHAR);
+
+ name = HeapAlloc(hHeap, 0, bufByteLen);
+
+ if (!GetComputerNameExW(ComputerNameDnsHostname,
+ name,
+ &bufCharLen))
+ {
+ HeapFree(hHeap, 0, name);
+ WSASetLastError(WSAEFAULT);
+ return SOCKET_ERROR;
+ }
+
+ *hostname = name;
+ return ERROR_SUCCESS;
+}
+
+/* This function is far from perfect but it works enough */
+IP4_ADDRESS
+FindEntryInHosts(IN CONST WCHAR FAR* wname)
+{
+ BOOL Found = FALSE;
+ HANDLE HostsFile;
+ CHAR HostsDBData[BUFSIZ] = {0};
+ PCHAR SystemDirectory = HostsDBData;
+ PCHAR HostsLocation = "\\drivers\\etc\\hosts";
+ PCHAR AddressStr, DnsName = NULL, AddrTerm, NameSt,
NextLine, ThisLine,
Comment;
+ UINT SystemDirSize = sizeof(HostsDBData) -
1, ValidData = 0;
+ DWORD ReadSize;
+ DWORD Address;
+ CHAR name[MAX_HOSTNAME_LEN + 1];
+
+ wcstombs(name, wname, MAX_HOSTNAME_LEN);
+
+ /* We assume that the parameters are valid */
+ if (!GetSystemDirectoryA(SystemDirectory, SystemDirSize))
+ {
+ WSASetLastError(WSANO_RECOVERY);
+ //WS_DbgPrint(MIN_TRACE, ("Could not get windows system
directory.\n"));
+ return 0; /* Can't get system
directory */
+ }
+
+ strncat(SystemDirectory, HostsLocation, SystemDirSize);
+
+ HostsFile = CreateFileA(SystemDirectory,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN,
+ NULL);
+ if (HostsFile == INVALID_HANDLE_VALUE)
+ {
+ WSASetLastError(WSANO_RECOVERY);
+ return 0;
+ }
+
+ while (!Found && ReadFile(HostsFile,
+ HostsDBData + ValidData,
+ sizeof(HostsDBData) - ValidData,
+ &ReadSize,
+ NULL))
+ {
+ ValidData += ReadSize;
+ ReadSize = 0;
+ NextLine = ThisLine = HostsDBData;
+
+ /* Find the beginning of the next line */
+ while ((NextLine < HostsDBData + ValidData) &&
+ (*NextLine != '\r') &&
+ (*NextLine != '\n'))
+ {
+ NextLine++;
+ }
+
+ /* Zero and skip, so we can treat what we have as a
string */
+ if (NextLine > HostsDBData +
ValidData)
+ break;
+
+ *NextLine = 0;
+ NextLine++;
+
+ Comment = strchr(ThisLine, '#');
+ if (Comment)
+ *Comment = 0; /* Terminate at comment start */
+
+ AddressStr = ThisLine;
+ /* Find the first space separating the IP address from
the DNS name
*/
+ AddrTerm = strchr(ThisLine, '
');
+ if (AddrTerm)
+ {
+ /* Terminate the address string */
+ *AddrTerm = 0;
+
+ /* Find the last space before the DNS name */
+ NameSt = strrchr(ThisLine, ' ');
+
+ /* If there is only one space (the one we removed
above), then
just use the address terminator */
+ if (!NameSt)
+ NameSt = AddrTerm;
+
+ /* Move from the space to the first character of
the DNS name */
+ NameSt++;
+
+ DnsName = NameSt;
+
+ if (!strcmp(name, DnsName))
+ {
+ Found = TRUE;
+ break;
+ }
+ }
+
+ /* Get rid of everything we read so far */
+ while (NextLine <= HostsDBData + ValidData &&
+ isspace (*NextLine))
+ {
+ NextLine++;
+ }
+
+ if (HostsDBData + ValidData - NextLine <= 0)
+ break;
+
+ //WS_DbgPrint(MAX_TRACE,("About to move %d chars\n",
+ // HostsDBData + ValidData - NextLine));
+
+ memmove(HostsDBData, NextLine, HostsDBData + ValidData
- NextLine);
+ ValidData -= NextLine - HostsDBData;
+ //WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData));
+ }
+
+ CloseHandle(HostsFile);
+
+ if (!Found)
+ {
+ //WS_DbgPrint(MAX_TRACE,("Not found\n"));
+ WSASetLastError(WSANO_DATA);
+ return 0;
+ }
+
+ if (strstr(AddressStr, ":"))
+ {
+ //DbgPrint("AF_INET6 NOT SUPPORTED!\n");
+ WSASetLastError(WSAEINVAL);
+ return 0;
+ }
+
+ Address = inet_addr(AddressStr);
+ if (Address == INADDR_NONE)
+ {
+ WSASetLastError(WSAEINVAL);
+ return 0;
+ }
+
+ return Address;
+}
+
+INT
+NSP_GetHostByNameHeapAllocW(_In_ WCHAR* name,
+ _In_ GUID* lpProviderId,
+ _Out_ PWSHOSTINFOINTERN hostinfo)
+{
+ HANDLE hHeap = GetProcessHeap();
+ enum addr_type
+ {
+ GH_INVALID,
+ GH_IPV6,
+ GH_IPV4,
+ GH_RFC1123_DNS
+ };
+ typedef enum addr_type addr_type;
+ addr_type addr;
+ INT ret = 0;
+ WCHAR* found = 0;
+ DNS_STATUS dns_status = {0};
+ /* include/WinDNS.h -- look up DNS_RECORD on MSDN */
+ PDNS_RECORD dp;
+ PDNS_RECORD curr;
+ WCHAR* tmpHostnameW;
+ CHAR* tmpHostnameA;
+ IP4_ADDRESS address;
+ INT result = ERROR_SUCCESS;
+
+ /* needed to be cleaned up if != NULL */
+ tmpHostnameW = NULL;
+ dp = NULL;
+
+ addr = GH_INVALID;
+
+ if (name == NULL)
+ {
+ result = ERROR_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ /* Hostname "" / "localhost"
+ - convert to "computername" */
+ if ((wcscmp(L"", name) == 0) /*||
+ (wcsicmp(L"localhost", name) == 0)*/)
+ {
+ ret = NSP_GetHostNameHeapAllocW(&tmpHostnameW);
+ if (ret != ERROR_SUCCESS)
+ {
+ result = ret;
+ goto cleanup;
+ }
+ name = tmpHostnameW;
+ }
+
+ /* Is it an IPv6 address? */
+ found = wcschr(name, L':');
+ if (found != NULL)
+ {
+ addr = GH_IPV6;
+ goto act;
+ }
+
+ /* Is it an IPv4 address? */
+ if (!iswalpha(name[0]))
+ {
+ addr = GH_IPV4;
+ goto act;
+ }
+
+ addr = GH_RFC1123_DNS;
+
+/* Broken out in case we want to get fancy later */
+act:
+ switch (addr)
+ {
+ case GH_IPV6:
+ WSASetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ result = ERROR_CALL_NOT_IMPLEMENTED;
+ goto cleanup;
+ break;
+
+ case GH_INVALID:
+ WSASetLastError(WSAEFAULT);
+ result = ERROR_INVALID_PARAMETER;
+ goto cleanup;
+ break;
+
+ /* Note: If passed an IP address, MSDN says that
gethostbyname()
+ treats it as an unknown host.
+ This is different from the unix implementation. Use
inet_addr()
+ */
+ case GH_IPV4:
+ case GH_RFC1123_DNS:
+ /* DNS_TYPE_A: include/WinDNS.h */
+ /* DnsQuery -- lib/dnsapi/dnsapi/query.c */
+
+ /* Look for the DNS name in the hosts file */
+ if ((address = FindEntryInHosts(name)) != 0)
+ {
+ hostinfo->hostnameW = StrCpyHeapAllocW(hHeap, name);
+ hostinfo->addr4 = address;
+ result = ERROR_SUCCESS;
+ goto cleanup;
+ }
+
+ tmpHostnameA = StrW2AHeapAlloc(hHeap, name);
+ dns_status = DnsQuery(tmpHostnameA,
+ DNS_TYPE_A,
+ DNS_QUERY_STANDARD,
+ /* extra dns servers */ 0,
+ &dp,
+ 0);
+ HeapFree(hHeap, 0, tmpHostnameA);
+
+ if ((dns_status != 0) || (dp == NULL))
+ {
+ result = WSAHOST_NOT_FOUND;
+ goto cleanup;
+ }
+
+ //ASSERT(dp->wType == DNS_TYPE_A);
+ //ASSERT(dp->wDataLength == sizeof(DNS_A_DATA));
+ curr = dp;
+ while ((curr->pNext != NULL) || (curr->wType !=
DNS_TYPE_A))
+ {
+ curr = curr->pNext;
+ }
+
+ if (curr->wType != DNS_TYPE_A)
+ {
+ result = WSASERVICE_NOT_FOUND;
+ goto cleanup;
+ }
+
+ //WS_DbgPrint(MID_TRACE,("populating hostent\n"));
+ //WS_DbgPrint(MID_TRACE,("pName is (%s)\n", curr->pName));
+ //populate_hostent(p->Hostent,
+ // (PCHAR)curr->pName,
+ // curr->Data.A.IpAddress);
+ hostinfo->hostnameW = StrA2WHeapAlloc(hHeap, curr->pName);
+ hostinfo->addr4 = curr->Data.A.IpAddress;
+ result = ERROR_SUCCESS;
+ goto cleanup;
+
+ //WS_DbgPrint(MID_TRACE,("Called DnsQuery, but host not
found.
Err: %i\n",
+ // dns_status));
+ //WSASetLastError(WSAHOST_NOT_FOUND);
+ //return NULL;
+
+ break;
+
+ default:
+ result = WSANO_RECOVERY;
+ goto cleanup;
+ break;
+ }
+
+ result = WSANO_RECOVERY;
+
+cleanup:
+ if (dp != NULL)
+ DnsRecordListFree(dp, DnsFreeRecordList);
+
+ if (tmpHostnameW != NULL)
+ HeapFree(hHeap, 0, tmpHostnameW);
+
+ return result;
+}
+
+#define SKIPWS(ptr, act) \
+{while(*ptr && isspace(*ptr)) ptr++; if(!*ptr) act;}
+
+#define SKIPANDMARKSTR(ptr, act) \
+{while(*ptr && !isspace(*ptr)) ptr++; \
+ if(!*ptr) {act;} else { *ptr = 0; ptr++; }}
+
+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));
+
+ SKIPWS(ServiceString, return FALSE);
+ *ServiceName = ServiceString;
+ SKIPANDMARKSTR(ServiceString, return FALSE);
+ SKIPWS(ServiceString, return FALSE);
+ *PortNumberStr = ServiceString;
+ SKIPANDMARKSTR(ServiceString, ;);
+
+ while (*ServiceString && NAliases < MaxAlias - 1)
+ {
+ SKIPWS(ServiceString, break);
+ if (*ServiceString)
+ {
+ SKIPWS(ServiceString, ;);
+ if (strlen(ServiceString))
+ {
+ //WS_DbgPrint(MAX_TRACE, ("Alias: %s\n",
ServiceString));
+ *Aliases++ = ServiceString;
+ NAliases++;
+ }
+ SKIPANDMARKSTR(ServiceString, ;);
+ }
+ }
+ *Aliases = NULL;
+
+ *ProtocolStr = strchr(*PortNumberStr, '/');
+
+ if (!*ProtocolStr)
+ return FALSE;
+
+ **ProtocolStr = 0;
+ (*ProtocolStr)++;
+
+ //WS_DbgPrint(MAX_TRACE, ("Parsing done: %s %s %s %d\n",
+ // *ServiceName, *ProtocolStr, *PortNumberStr,
+ // NAliases));
+
+ return TRUE;
+}
+
+INT
+NSP_GetServiceByNameHeapAllocW(_In_ WCHAR* nameW,
+ _In_ GUID* lpProviderId,
+ _Out_ PWSHOSTINFOINTERN hostinfo)
+{
+ BOOL Found = FALSE;
+ HANDLE ServicesFile;
+ CHAR ServiceDBData[BUFSIZ * sizeof(WCHAR)] = {0};
+ PWCHAR SystemDirectory = (PWCHAR)ServiceDBData; /* Reuse
this stack space
*/
+ PWCHAR ServicesFileLocation =
L"\\drivers\\etc\\services";
+ 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,
+ SystemDirSize = (sizeof(ServiceDBData) / sizeof(WCHAR)) - 1;
+ DWORD ReadSize = 0;
+ HANDLE hHeap;
+ PCHAR nameA = NULL;
+ PCHAR nameServiceA = NULL;
+ PCHAR nameProtoA = NULL;
+ INT res = WSANO_RECOVERY;
+
+ if (!nameW)
+ {
+ res = WSANO_RECOVERY;
+ goto End;
+ }
+
+ hHeap = GetProcessHeap();
+ nameA = StrW2AHeapAlloc(hHeap, nameW);
+
+ /* nameA has the form <service-name>/<protocol>
+ we split these now */
+ nameProtoA = strchr(nameA, '/');
+ if (nameProtoA == NULL)
+ {
+ res = WSANO_RECOVERY;
+ goto End;
+ }
+
+ nameProtoA++;
+ i = (DWORD)(nameProtoA - nameA - 1);
+ nameServiceA = (PCHAR)HeapAlloc(hHeap, 0, i + 1);
+ StringCbCopyA(nameServiceA, i + 1, nameA);
+ nameServiceA[i] = '\0';
+
+ if (!GetSystemDirectoryW(SystemDirectory, SystemDirSize))
+ {
+ /* Can't get system directory */
+ res = WSANO_RECOVERY;
+ goto End;
+ }
+
+ wcsncat(SystemDirectory, ServicesFileLocation, SystemDirSize);
+
+ ServicesFile = CreateFileW(SystemDirectory,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN,
+ NULL);
+
+ if (ServicesFile == INVALID_HANDLE_VALUE)
+ {
+ return WSANO_RECOVERY;
+ }
+
+ /* 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 */
+ ReadFile(ServicesFile,
+ ServiceDBData,
+ sizeof( ServiceDBData ) - 1,
+ &ReadSize,
+ NULL);
+
+ 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)
+ {
+ //WS_DbgPrint(MIN_TRACE,("Line too long"));
+ return WSANO_RECOVERY;
+ }
+
+ memmove(ServiceDBData, ThisLine, LineLen);
+
+ ReadFile(ServicesFile,
+ ServiceDBData + LineLen,
+ sizeof( ServiceDBData )-1 - LineLen,
+ &ReadSize,
+ NULL);
+
+ 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)
+ {
+ 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 != NULL)
+ HeapFree(hHeap, 0, nameA);
+
+ if (nameServiceA != NULL)
+ HeapFree(hHeap, 0, nameServiceA);
+
+ return res;
+}
+
+INT
+NSP_LookupServiceNextW(_In_ PWSHANDLEINTERN data,
+ _In_ DWORD CallID,
+ _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;
+
+ 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 ((CallID == NSP_CALLID_HOSTNAME) ||
+ (CallID == NSP_CALLID_HOSTBYNAME) ||
+ (CallID == NSP_CALLID_SERVICEBYNAME))
+ {
+ if (data->CallIDCounter >= 1)
+ {
+ result = WSAENOMORE;
+ goto End;
+ }
+ }
+ else
+ {
+ result = WSANO_RECOVERY;
+ goto End;
+ }
+ data->CallIDCounter++;
+
+ if (CallID == NSP_CALLID_HOSTNAME)
+ {
+ result = NSP_GetHostNameHeapAllocW(&hostinfo.hostnameW);
+
+ if (result != ERROR_SUCCESS)
+ goto End;
+
+ hostinfo.addr4 = 0;
+ }
+ else if (CallID == NSP_CALLID_HOSTBYNAME)
+ {
+ result = NSP_GetHostByNameHeapAllocW(data->hostnameW,
+ &data->providerId,
+ &hostinfo);
+ if (result != ERROR_SUCCESS)
+ goto End;
+ }
+ else if (CallID == NSP_CALLID_SERVICEBYNAME)
+ {
+ result = NSP_GetServiceByNameHeapAllocW(data->hostnameW,
+ &data->providerId,
+ &hostinfo);
+ if (result != ERROR_SUCCESS)
+ goto End;
+ }
+ else
+ {
+ result = WSANO_RECOVERY; // Internal error!
+ goto End;
+ }
+
+ if (((LUP_RETURN_BLOB & data->dwControlFlags) != 0) ||
+ ((LUP_RETURN_NAME & data->dwControlFlags) != 0))
+ {
+ if (CallID == NSP_CALLID_HOSTNAME || CallID ==
NSP_CALLID_HOSTBYNAME)
+ {
+ ServiceInstanceNameW = hostinfo.hostnameW;
+ ServiceInstanceNameA = StrW2AHeapAlloc(hHeap,
ServiceInstanceNameW);
+ if (ServiceInstanceNameA == NULL)
+ {
+ result = WSAEFAULT;
+ goto End;
+
+ }
+ }
+ if (CallID == NSP_CALLID_SERVICEBYNAME)
+ {
+ ServiceInstanceNameW = hostinfo.servnameW;
+ ServiceInstanceNameA = StrW2AHeapAlloc(hHeap,
ServiceInstanceNameW);
+ if (ServiceInstanceNameA == NULL)
+ {
+ result = WSAEFAULT;
+ goto End;
+
+ }
+ ServiceProtocolNameA = StrW2AHeapAlloc(hHeap,
hostinfo.servprotoW);
+ if (ServiceProtocolNameA == NULL)
+ {
+ result = WSAEFAULT;
+ goto End;
+
+ }
+ }
+ }
+
+ if ((LUP_RETURN_ADDR & data->dwControlFlags) != 0)
+ {
+ if (!mswBufferAppendAddr_AddrInfoW(&buf, lpRes,
hostinfo.addr4))
+ {
+ *lpResLen = buf.bytesUsed;
+ result = WSAEFAULT;
+ goto End;
+ }
+ }
+
+ if ((LUP_RETURN_BLOB & data->dwControlFlags) != 0)
+ {
+ if (CallID == NSP_CALLID_HOSTBYNAME)
+ {
+ /* Write data for PBLOB (hostent) */
+ if (!mswBufferAppendBlob_Hostent(&buf,
+ lpRes,
+ ServiceInstanceNameA,
+ hostinfo.addr4))
+ {
+ *lpResLen = buf.bytesUsed;
+ result = WSAEFAULT;
+ goto End;
+ }
+ }
+ else if (CallID == NSP_CALLID_SERVICEBYNAME)
+ {
+ /* Write data for PBLOB (servent) */
+ if (!mswBufferAppendBlob_Servent(&buf,
+ lpRes,
+ ServiceInstanceNameA,/* ServiceName */
+ hostinfo.servaliasesA,
+ ServiceProtocolNameA,
+ hostinfo.servport))
+ {
+ *lpResLen = buf.bytesUsed;
+ result = WSAEFAULT;
+ goto End;
+ }
+ }
+ else
+ {
+ result = WSANO_RECOVERY;
+ goto End;
+ }
+ }
+
+ if ((LUP_RETURN_NAME & data->dwControlFlags) != 0)
+ {
+ /* HostByName sets the ServiceInstanceName to a
+ (UNICODE)copy of hostent.h_name */
+ lpRes->lpszServiceInstanceName =
(LPWSTR)mswBufferEndPtr(&buf);
> + if (!mswBufferAppendStrW(&buf, ServiceInstanceNameW))
> + {
> + lpRes->lpszServiceInstanceName = NULL;
> + *lpResLen = buf.bytesUsed;
> + result = WSAEFAULT;
> + goto End;
> + }
> + }
> +
> + *lpResLen = buf.bytesUsed;
> +
> + result = ERROR_SUCCESS;
> +End:
> + /* cleanup */
> + if (ServiceInstanceNameA != NULL)
> + HeapFree(hHeap, 0, ServiceInstanceNameA);
> +
> + if (ServiceProtocolNameA != NULL)
> + HeapFree(hHeap, 0, ServiceProtocolNameA);
> +
> + if (hostinfo.hostnameW != NULL)
> + HeapFree(hHeap, 0, hostinfo.hostnameW);
> +
> + if (hostinfo.servnameW != NULL)
> + HeapFree(hHeap, 0, hostinfo.servnameW);
> +
> + if (hostinfo.servprotoW != NULL)
> + HeapFree(hHeap, 0, hostinfo.servprotoW);
> +
> + return result;
> +}
> +
> +/* Implementations - Exports */
> +/*
> + * @implemented
> + */
> +int
> +WINAPI
> +NSPStartup(_In_ LPGUID lpProviderId,
> + _Out_ LPNSP_ROUTINE lpRout)
> +{
> + INT ret;
> +
> + if ((lpRout == NULL) ||
> + (lpRout->cbSize != sizeof(NSP_ROUTINE)))
> + {
> + WSASetLastError(ERROR_INVALID_PARAMETER);
> + return ERROR_INVALID_PARAMETER;
> + }
> +
> + mwsNSPInit();
> +
> + /* set own Provider GUID - maybe we need
> + here to set the original mswsock-GUID?! */
> +
> + /* Win2k3 returns
> + - Version 1.1
> + - no NSPIoctl
> + - sets cbSize to 44! */
> + lpRout->dwMajorVersion = 1;
> + lpRout->dwMinorVersion = 1;
> + lpRout->cbSize = sizeof(*lpRout) - sizeof(lpRout->NSPIoctl);
> + lpRout->NSPCleanup = &mwsNSPCleanUp;
> + lpRout->NSPLookupServiceBegin = &mwsNSPLookupServiceBegin;
> + lpRout->NSPLookupServiceNext = &mwsNSPLookupServiceNext;
> + lpRout->NSPLookupServiceEnd = &mwsNSPLookupServiceEnd;
> + lpRout->NSPSetService = &mwsNSPSetService;
> + lpRout->NSPInstallServiceClass = &mwsNSPInstallServiceClass;
> + lpRout->NSPRemoveServiceClass = &mwsNSPRemoveServiceClass;
> + lpRout->NSPGetServiceClassInfo = &mwsNSPGetServiceClassInfo;
> + lpRout->NSPIoctl = NULL;// &mwsNSPIoCtl;
> +
> + ret = NO_ERROR;
> +
> + return ret;
> +}
> Propchange:
trunk/reactos/dll/win32/mswsock/nsplookup.c
------------------------------------------------------------------------------
> svn:eol-style = native
> Modified:
trunk/reactos/dll/win32/mswsock/stubs.c
> URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/stubs.c?…
<http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mswsock/stubs.c?rev=72735&r1=72734&r2=72735&view=diff>
==============================================================================
--- trunk/reactos/dll/win32/mswsock/stubs.c
[iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mswsock/stubs.c [iso-8859-1] Sun
Sep 18 21:21:28
2016
> @@ -9,6 +9,7 @@
> #include "precomp.h"
> +#include <windef.h>
> #include <ws2spi.h>
> #include <nspapi.h>
> @@ -417,21 +418,6 @@
> return TRUE;
> }
> -
> -/*
> - * @unimplemented
> - */
> -INT
> -WINAPI
> -NSPStartup(
> - LPGUID lpProviderId,
> - LPNSP_ROUTINE lpnspRoutines
> - )
> -{
> - return TRUE;
> -}
> -
> -
> /*
> * @unimplemented
> */
_______________________________________________
Ros-dev mailing list
Ros-dev(a)reactos.org <mailto:Ros-dev@reactos.org>
http://www.reactos.org/mailman/listinfo/ros-dev
<http://www.reactos.org/mailman/listinfo/ros-dev>
_______________________________________________
Ros-dev mailing list
Ros-dev(a)reactos.org
http://www.reactos.org/mailman/listinfo/ros-dev