/*
 * VNBT VxD implementation
 *
 * Copyright 2003 Juan Lang
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winsock2.h"
#include "iphlpapi.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(vxd);

#ifndef INADDR_NONE
#define INADDR_NONE ~0UL
#endif

typedef struct _nbtInfo
{
    DWORD ip;
    DWORD winsPrimary;
    DWORD winsSecondary;
    DWORD dnsPrimary;
    DWORD dnsSecondary;
    DWORD unk0;
} nbtInfo;

#define MAX_NBT_ENTRIES 7

typedef struct _nbtTable
{
    DWORD   numEntries;
    nbtInfo table[MAX_NBT_ENTRIES];
    UCHAR   pad[6];
    WORD    nodeType;
    WORD    scopeLen;
    char    scope[254];
} nbtTable;


/***********************************************************************
 *           DeviceIoControl   (VNB.VXD.@)
 */
BOOL WINAPI VNBT_DeviceIoControl(DWORD dwIoControlCode,
                                 LPVOID lpvInBuffer, DWORD cbInBuffer,
                                 LPVOID lpvOutBuffer, DWORD cbOutBuffer,
                                 LPDWORD lpcbBytesReturned,
                                 LPOVERLAPPED lpOverlapped)
{
    DWORD error;

    switch (dwIoControlCode)
    {
    case 116:
        if (lpcbBytesReturned)
            *lpcbBytesReturned = sizeof(nbtTable);
        if (!lpvOutBuffer || cbOutBuffer < sizeof(nbtTable))
            error = ERROR_BUFFER_OVERFLOW;
        else
        {
            nbtTable *info = (nbtTable *)lpvOutBuffer;
            DWORD size = 0;

            memset(info, 0, sizeof(nbtTable));

            error = GetNetworkParams(NULL, &size);
            if (ERROR_BUFFER_OVERFLOW == error)
            {
                PFIXED_INFO fixedInfo = HeapAlloc( GetProcessHeap(), 0, size);

                error = GetNetworkParams(fixedInfo, &size);
                if (NO_ERROR == error)
                {
                    info->nodeType = (WORD)fixedInfo->NodeType;
                    info->scopeLen = min(strlen(fixedInfo->ScopeId) + 1,
                                         sizeof(info->scope) - 2);
                    memcpy(info->scope + 1, fixedInfo->ScopeId,
                           info->scopeLen);
                    info->scope[info->scopeLen + 1] = '\0';
                    {
                        /* convert into L2-encoded version */
                        char *ptr, *lenPtr;

                        for (ptr = info->scope + 1; *ptr &&
                                 ptr - info->scope < sizeof(info->scope); )
                        {
                            for (lenPtr = ptr - 1, *lenPtr = 0;
                                 *ptr && *ptr != '.' &&
                                     ptr - info->scope < sizeof(info->scope);
                                 ptr++)
                                *lenPtr += 1;
                            ptr++;
                        }
                    }
                    /* could set DNS servers here too, but since
                     * ipconfig.exe and winipcfg.exe read these from the
                     * registry, there's no point */
                }
                HeapFree(GetProcessHeap(), 0, fixedInfo);
            }
            size = 0;
            error = GetAdaptersInfo(NULL, &size);
            if (ERROR_BUFFER_OVERFLOW == error)
            {
                PIP_ADAPTER_INFO adapterInfo = HeapAlloc(GetProcessHeap(), 0, size);

                error = GetAdaptersInfo(adapterInfo, &size);
                if (NO_ERROR == error)
                {
                    PIP_ADAPTER_INFO ptr;

                    for (ptr = adapterInfo; ptr && info->numEntries <
                             MAX_NBT_ENTRIES; ptr = ptr->Next)
                    {
                        unsigned long addr;

                        addr = inet_addr(ptr->IpAddressList.IpAddress.String);
                        if (addr != 0 && addr != INADDR_NONE)
                            info->table[info->numEntries].ip = ntohl(addr);
                        addr = inet_addr(ptr->PrimaryWinsServer.IpAddress.String);
                        if (addr != 0 && addr != INADDR_NONE)
                            info->table[info->numEntries].winsPrimary = ntohl(addr);
                        addr = inet_addr(ptr->SecondaryWinsServer.IpAddress.String);
                        if (addr != 0 && addr != INADDR_NONE)
                            info->table[info->numEntries].winsSecondary = ntohl(addr);
                        info->numEntries++;
                    }
                }
                HeapFree(GetProcessHeap(), 0, adapterInfo);
            }
        }
        break;

    case 119:
        /* nbtstat.exe uses this, but the return seems to be a bunch of
         * pointers, so it's not so easy to reverse engineer.  Fall through
         * to unimplemented...
         */
    default:
        FIXME( "Unimplemented control %d for VxD device VNB\n",
               dwIoControlCode );
        error = ERROR_NOT_SUPPORTED;
        break;
    }
    if (error)
        SetLastError(error);
    return error == NO_ERROR;
}
