Release 1.5.29.
[wine] / dlls / vnbt.vxd / vnbt.c
1 /*
2  * VNBT VxD implementation
3  *
4  * Copyright 2003 Juan Lang
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "iphlpapi.h"
27 #include "winsock2.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(vxd);
31
32 #ifndef INADDR_NONE
33 #define INADDR_NONE ~0UL
34 #endif
35
36 typedef struct _nbtInfo
37 {
38     DWORD ip;
39     DWORD winsPrimary;
40     DWORD winsSecondary;
41     DWORD dnsPrimary;
42     DWORD dnsSecondary;
43     DWORD unk0;
44 } nbtInfo;
45
46 #define MAX_NBT_ENTRIES 7
47
48 typedef struct _nbtTable
49 {
50     DWORD   numEntries;
51     nbtInfo table[MAX_NBT_ENTRIES];
52     UCHAR   pad[6];
53     WORD    nodeType;
54     WORD    scopeLen;
55     char    scope[254];
56 } nbtTable;
57
58
59 /***********************************************************************
60  *           DeviceIoControl   (VNB.VXD.@)
61  */
62 BOOL WINAPI VNBT_DeviceIoControl(DWORD dwIoControlCode,
63                                  LPVOID lpvInBuffer, DWORD cbInBuffer,
64                                  LPVOID lpvOutBuffer, DWORD cbOutBuffer,
65                                  LPDWORD lpcbBytesReturned,
66                                  LPOVERLAPPED lpOverlapped)
67 {
68     DWORD error;
69
70     switch (dwIoControlCode)
71     {
72     case 116:
73         if (lpcbBytesReturned)
74             *lpcbBytesReturned = sizeof(nbtTable);
75         if (!lpvOutBuffer || cbOutBuffer < sizeof(nbtTable))
76             error = ERROR_BUFFER_OVERFLOW;
77         else
78         {
79             nbtTable *info = (nbtTable *)lpvOutBuffer;
80             DWORD size = 0;
81
82             memset(info, 0, sizeof(nbtTable));
83
84             error = GetNetworkParams(NULL, &size);
85             if (ERROR_BUFFER_OVERFLOW == error)
86             {
87                 PFIXED_INFO fixedInfo = HeapAlloc( GetProcessHeap(), 0, size);
88
89                 error = GetNetworkParams(fixedInfo, &size);
90                 if (NO_ERROR == error)
91                 {
92                     info->nodeType = (WORD)fixedInfo->NodeType;
93                     info->scopeLen = min(strlen(fixedInfo->ScopeId) + 1,
94                                          sizeof(info->scope) - 2);
95                     memcpy(info->scope + 1, fixedInfo->ScopeId,
96                            info->scopeLen);
97                     info->scope[info->scopeLen + 1] = '\0';
98                     {
99                         /* convert into L2-encoded version */
100                         char *ptr, *lenPtr;
101
102                         for (ptr = info->scope + 1; *ptr &&
103                                  ptr - info->scope < sizeof(info->scope); )
104                         {
105                             for (lenPtr = ptr - 1, *lenPtr = 0;
106                                  *ptr && *ptr != '.' &&
107                                      ptr - info->scope < sizeof(info->scope);
108                                  ptr++)
109                                 *lenPtr += 1;
110                             ptr++;
111                         }
112                     }
113                     /* could set DNS servers here too, but since
114                      * ipconfig.exe and winipcfg.exe read these from the
115                      * registry, there's no point */
116                 }
117                 HeapFree(GetProcessHeap(), 0, fixedInfo);
118             }
119             size = 0;
120             error = GetAdaptersInfo(NULL, &size);
121             if (ERROR_BUFFER_OVERFLOW == error)
122             {
123                 PIP_ADAPTER_INFO adapterInfo = HeapAlloc(GetProcessHeap(), 0, size);
124
125                 error = GetAdaptersInfo(adapterInfo, &size);
126                 if (NO_ERROR == error)
127                 {
128                     PIP_ADAPTER_INFO ptr;
129
130                     for (ptr = adapterInfo; ptr && info->numEntries <
131                              MAX_NBT_ENTRIES; ptr = ptr->Next)
132                     {
133                         unsigned long addr;
134
135                         addr = inet_addr(ptr->IpAddressList.IpAddress.String);
136                         if (addr != 0 && addr != INADDR_NONE)
137                             info->table[info->numEntries].ip = ntohl(addr);
138                         addr = inet_addr(ptr->PrimaryWinsServer.IpAddress.String);
139                         if (addr != 0 && addr != INADDR_NONE)
140                             info->table[info->numEntries].winsPrimary = ntohl(addr);
141                         addr = inet_addr(ptr->SecondaryWinsServer.IpAddress.String);
142                         if (addr != 0 && addr != INADDR_NONE)
143                             info->table[info->numEntries].winsSecondary = ntohl(addr);
144                         info->numEntries++;
145                     }
146                 }
147                 HeapFree(GetProcessHeap(), 0, adapterInfo);
148             }
149         }
150         break;
151
152     case 119:
153         /* nbtstat.exe uses this, but the return seems to be a bunch of
154          * pointers, so it's not so easy to reverse engineer.  Fall through
155          * to unimplemented...
156          */
157     default:
158         FIXME( "Unimplemented control %d for VxD device VNB\n",
159                dwIoControlCode );
160         error = ERROR_NOT_SUPPORTED;
161         break;
162     }
163     if (error)
164         SetLastError(error);
165     return error == NO_ERROR;
166 }