wine/dlls/vnbt.vxd/vnbt.c
2011-07-06 11:20:40 +02:00

167 lines
5.7 KiB
C

/*
* 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 "iphlpapi.h"
#include "winsock2.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;
}