183 lines
6.0 KiB
C
183 lines
6.0 KiB
C
/*
|
|
* VNB 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <sys/types.h>
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
# include <sys/socket.h>
|
|
#endif
|
|
#ifdef HAVE_NETINET_IN_H
|
|
# include <netinet/in.h>
|
|
#endif
|
|
#ifdef HAVE_ARPA_INET_H
|
|
# include <arpa/inet.h>
|
|
#endif
|
|
#ifdef HAVE_UNISTD_H
|
|
# include <unistd.h>
|
|
#endif
|
|
|
|
#include "windef.h"
|
|
#include "winbase.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 VNB_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 = (PFIXED_INFO)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 */
|
|
}
|
|
if (fixedInfo)
|
|
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 = adapterInfo;
|
|
|
|
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++;
|
|
}
|
|
}
|
|
if (adapterInfo)
|
|
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 %ld for VxD device VNB\n",
|
|
dwIoControlCode );
|
|
error = ERROR_NOT_SUPPORTED;
|
|
break;
|
|
}
|
|
if (error)
|
|
SetLastError(error);
|
|
return error == NO_ERROR;
|
|
}
|