[ros-dev] [ros-diffs] [akhaldi] 72735: [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-1...

Timo Kreuzer timo.kreuzer at web.de
Wed Sep 21 00:17:52 UTC 2016


:D

Am 20.09.2016 um 19:28 schrieb Javier Agustìn Fernàndez Arroyo:
> L
> O
> L
>
> On Tue, Sep 20, 2016 at 6:32 PM, Alex Ionescu <ionucu at videotron.ca 
> <mailto:ionucu at 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 at svn.reactos.org
>     <mailto:akhaldi at 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/CMakeLists.txt?rev=72735&r1=72734&r2=72735&view=diff
>     <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/mswhelper.c?rev=72735
>     <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/mswhelper.h?rev=72735
>     <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/nsplookup.c?rev=72735
>     <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?rev=72735&r1=72734&r2=72735&view=diff
>     <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 at reactos.org <mailto:Ros-dev at reactos.org>
>     http://www.reactos.org/mailman/listinfo/ros-dev
>     <http://www.reactos.org/mailman/listinfo/ros-dev>
>
>
>
>
> _______________________________________________
> Ros-dev mailing list
> Ros-dev at reactos.org
> http://www.reactos.org/mailman/listinfo/ros-dev


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.reactos.org/pipermail/ros-dev/attachments/20160921/09f30d19/attachment-0001.html>


More information about the Ros-dev mailing list