2 * iphlpapi dll implementation -- Setting and storing route information
4 * These are stubs for functions that set routing information on the target
5 * operating system. They are grouped here because their implementation will
6 * vary widely by operating system.
8 * Copyright (C) 2004 Art Yerkes
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "iphlpapi_private.h"
29 #include <sys/types.h>
30 #ifdef HAVE_NETINET_IN_H
31 # include <netinet/in.h>
33 #ifdef HAVE_ARPA_INET_H
34 # include <arpa/inet.h>
36 #ifdef HAVE_ARPA_NAMESER_H
37 # include <arpa/nameser.h>
48 #include "wine/debug.h"
50 typedef struct _NAME_SERVER_LIST_PRIVATE
{
52 IP_ADDR_STRING
* pCurrent
;
53 } NAME_SERVER_LIST_PRIVATE
, *PNAME_SERVER_LIST_PRIVATE
;
76 RtlUnicodeToMultiByteN (
85 typedef VOID (*EnumInterfacesFunc
)( HKEY ChildKeyHandle
,
92 * Call the enumeration function for each name server.
95 static void EnumInterfaces( PVOID Data
, EnumInterfacesFunc cb
) {
97 HKEY ChildKeyHandle
= 0;
98 PWCHAR RegKeyToEnumerate
=
99 L
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
100 PWCHAR ChildKeyName
= 0;
101 DWORD CurrentInterface
;
103 if (OpenChildKeyRead(HKEY_LOCAL_MACHINE
,RegKeyToEnumerate
,&RegHandle
)) {
107 for (CurrentInterface
= 0; TRUE
; CurrentInterface
++) {
108 ChildKeyName
= GetNthChildKeyName( RegHandle
, CurrentInterface
);
109 if (!ChildKeyName
) break;
110 if (OpenChildKeyRead(RegHandle
,ChildKeyName
,
111 &ChildKeyHandle
) == 0) {
112 cb( ChildKeyHandle
, ChildKeyName
, Data
);
113 RegCloseKey( ChildKeyHandle
);
115 ConsumeChildKeyName( ChildKeyName
);
123 void EnumNameServers( HANDLE RegHandle
, PWCHAR Interface
,
124 PVOID Data
, EnumNameServersFunc cb
) {
125 PWCHAR NameServerString
=
126 QueryRegistryValueString(RegHandle
, L
"DhcpNameServer");
128 if (!NameServerString
)
129 NameServerString
= QueryRegistryValueString(RegHandle
, L
"NameServer");
131 if (NameServerString
) {
132 /* Now, count the non-empty comma separated */
134 DWORD LastNameStart
= 0;
135 for (ch
= 0; NameServerString
[ch
]; ch
++) {
136 if (NameServerString
[ch
] == ',') {
137 if (ch
- LastNameStart
> 0) { /* Skip empty entries */
139 malloc(((ch
- LastNameStart
) + 1) * sizeof(WCHAR
));
141 memcpy(NameServer
,NameServerString
+ LastNameStart
,
142 (ch
- LastNameStart
) * sizeof(WCHAR
));
143 NameServer
[ch
- LastNameStart
] = 0;
144 cb( Interface
, NameServer
, Data
);
146 LastNameStart
= ch
+1;
149 LastNameStart
= ch
+ 1; /* The first one after the comma */
152 if (ch
- LastNameStart
> 0) { /* A last name? */
153 PWCHAR NameServer
= malloc(((ch
- LastNameStart
) + 1) * sizeof(WCHAR
));
155 memcpy(NameServer
,NameServerString
+ LastNameStart
,
156 (ch
- LastNameStart
) * sizeof(WCHAR
));
157 NameServer
[ch
- LastNameStart
] = 0;
158 cb( Interface
, NameServer
, Data
);
162 ConsumeRegValueString(NameServerString
);
166 static void CreateNameServerListEnumNamesFuncCount( PWCHAR Interface
,
169 PNAME_SERVER_LIST_PRIVATE Data
= (PNAME_SERVER_LIST_PRIVATE
)_Data
;
173 static void CreateNameServerListEnumIfFuncCount( HKEY RegHandle
,
174 PWCHAR InterfaceName
,
176 PNAME_SERVER_LIST_PRIVATE Data
= (PNAME_SERVER_LIST_PRIVATE
)_Data
;
177 EnumNameServers(RegHandle
,InterfaceName
,Data
,
178 CreateNameServerListEnumNamesFuncCount
);
181 VOID
CreateNameServerListEnumNamesFunc(
186 PNAME_SERVER_LIST_PRIVATE Data
= (PNAME_SERVER_LIST_PRIVATE
)_Data
;
188 if (WideCharToMultiByte(CP_ACP
, 0, Server
, -1, Data
->pCurrent
->IpAddress
.String
, 16, NULL
, NULL
))
190 Data
->pCurrent
->Next
= (struct _IP_ADDR_STRING
*)(char*)Data
->pCurrent
+ sizeof(IP_ADDR_STRING
);
191 Data
->pCurrent
= Data
->pCurrent
->Next
;
196 Data
->pCurrent
->IpAddress
.String
[0] = '\0';
200 static void CreateNameServerListEnumIfFunc( HKEY RegHandle
,
201 PWCHAR InterfaceName
,
203 PNAME_SERVER_LIST_PRIVATE Data
= (PNAME_SERVER_LIST_PRIVATE
)_Data
;
204 EnumNameServers(RegHandle
,InterfaceName
,Data
,
205 CreateNameServerListEnumNamesFunc
);
208 static int CountNameServers( PNAME_SERVER_LIST_PRIVATE PrivateData
) {
209 EnumInterfaces(PrivateData
,CreateNameServerListEnumIfFuncCount
);
210 return PrivateData
->NumServers
;
213 static void MakeNameServerList( PNAME_SERVER_LIST_PRIVATE PrivateData
) {
214 EnumInterfaces(PrivateData
,CreateNameServerListEnumIfFunc
);
217 PIPHLP_RES_INFO
getResInfo() {
219 NAME_SERVER_LIST_PRIVATE PrivateNSEnum
;
220 PIPHLP_RES_INFO ResInfo
;
221 IP_ADDR_STRING
* DnsList
;
223 PrivateNSEnum
.NumServers
= 0;
224 ServerCount
= CountNameServers( &PrivateNSEnum
);
226 PrivateNSEnum
.NumServers
= ServerCount
;
227 DnsList
= HeapAlloc(GetProcessHeap(), 0, ServerCount
* sizeof(IP_ADDR_STRING
));
228 if (!DnsList
) return NULL
;
230 ZeroMemory(DnsList
, ServerCount
* sizeof(IP_ADDR_STRING
));
232 ResInfo
= (PIPHLP_RES_INFO
)RtlAllocateHeap ( GetProcessHeap(), 0, sizeof(IPHLP_RES_INFO
));
235 HeapFree( GetProcessHeap(), 0, DnsList
);
239 PrivateNSEnum
.NumServers
= 0;
240 PrivateNSEnum
.pCurrent
= DnsList
;
242 MakeNameServerList( &PrivateNSEnum
);
243 ResInfo
->DnsList
= DnsList
;
244 ResInfo
->riCount
= PrivateNSEnum
.NumServers
;
249 VOID
disposeResInfo( PIPHLP_RES_INFO InfoPtr
)
251 HeapFree(GetProcessHeap(), 0, InfoPtr
->DnsList
);
252 RtlFreeHeap( GetProcessHeap(), 0, InfoPtr
);