ReactOS 0.4.15-dev-8219-ge8b88cf
hostsfile.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: base/services/dnsrslvr/hostsfile.c
5 * PURPOSE: HOSTS file routines
6 * PROGRAMERS: Art Yerkes
7 * Eric Kohl
8 */
9
10#include "precomp.h"
11#include <inaddr.h>
12#include <in6addr.h>
13
14
15#define NDEBUG
16#include <debug.h>
17
18static WCHAR szHexChar[] = L"0123456789abcdef";
19
20static
23 PSTR NarrowString)
24{
25 PWSTR WideString;
26 int WideLen;
27
29 0,
30 NarrowString,
31 -1,
32 NULL,
33 0);
34 if (WideLen == 0)
35 return NULL;
36
37 WideString = HeapAlloc(GetProcessHeap(),
38 0,
39 WideLen * sizeof(WCHAR));
40 if (WideString == NULL)
41 return NULL;
42
44 0,
45 NarrowString,
46 -1,
47 WideString,
48 WideLen);
49
50 return WideString;
51}
52
53
54static
55BOOL
57 _In_ PCSTR AddressString,
58 _Out_ PIN_ADDR pAddress)
59{
60 PCSTR pTerminator = NULL;
62
63 Status = RtlIpv4StringToAddressA(AddressString,
64 TRUE,
65 &pTerminator,
66 pAddress);
67 if (NT_SUCCESS(Status) && pTerminator != NULL && *pTerminator == '\0')
68 return TRUE;
69
70 return FALSE;
71}
72
73
74static
75BOOL
77 _In_ LPCSTR AddressString,
78 _Out_ PIN6_ADDR pAddress)
79{
80 PCSTR pTerminator = NULL;
82
83 Status = RtlIpv6StringToAddressA(AddressString,
84 &pTerminator,
85 pAddress);
86 if (NT_SUCCESS(Status) && pTerminator != NULL && *pTerminator == '\0')
87 return TRUE;
88
89 return FALSE;
90}
91
92
93static
94VOID
96 PWSTR pszHostName,
97 PIN_ADDR pAddress)
98{
99 DNS_RECORDW ARecord, PtrRecord;
100 WCHAR szReverseName[32];
101
102 /* Prepare the A record */
103 ZeroMemory(&ARecord, sizeof(DNS_RECORDW));
104
105 ARecord.pName = pszHostName;
106 ARecord.wType = DNS_TYPE_A;
107 ARecord.wDataLength = sizeof(DNS_A_DATA);
110 ARecord.dwTtl = 86400;
111
112 ARecord.Data.A.IpAddress = pAddress->S_un.S_addr;
113
114 /* Prepare the PTR record */
115 swprintf(szReverseName,
116 L"%u.%u.%u.%u.in-addr.arpa.",
117 pAddress->S_un.S_un_b.s_b4,
118 pAddress->S_un.S_un_b.s_b3,
119 pAddress->S_un.S_un_b.s_b2,
120 pAddress->S_un.S_un_b.s_b1);
121
122 ZeroMemory(&PtrRecord, sizeof(DNS_RECORDW));
123
124 PtrRecord.pName = szReverseName;
125 PtrRecord.wType = DNS_TYPE_PTR;
126 PtrRecord.wDataLength = sizeof(DNS_PTR_DATA);
127 PtrRecord.Flags.S.Section = DnsSectionAnswer;
128 PtrRecord.Flags.S.CharSet = DnsCharSetUnicode;
129 PtrRecord.dwTtl = 86400;
130
131 PtrRecord.Data.PTR.pNameHost = pszHostName;
132
133 DnsIntCacheAddEntry(&ARecord, TRUE);
134 DnsIntCacheAddEntry(&PtrRecord, TRUE);
135}
136
137
138static
139VOID
141 PWSTR pszHostName,
142 PIN6_ADDR pAddress)
143{
144 DNS_RECORDW AAAARecord, PtrRecord;
145 WCHAR szReverseName[80];
146 DWORD i, j, k;
147
148 /* Prepare the AAAA record */
149 ZeroMemory(&AAAARecord, sizeof(DNS_RECORDW));
150
151 AAAARecord.pName = pszHostName;
152 AAAARecord.wType = DNS_TYPE_AAAA;
153 AAAARecord.wDataLength = sizeof(DNS_AAAA_DATA);
154 AAAARecord.Flags.S.Section = DnsSectionAnswer;
155 AAAARecord.Flags.S.CharSet = DnsCharSetUnicode;
156 AAAARecord.dwTtl = 86400;
157
158 CopyMemory(&AAAARecord.Data.AAAA.Ip6Address,
159 &pAddress->u.Byte,
160 sizeof(IN6_ADDR));
161
162 /* Prepare the PTR record */
163 ZeroMemory(szReverseName, sizeof(szReverseName));
164
165 for (i = 0; i < sizeof(IN6_ADDR); i++)
166 {
167 j = 4 * i;
168 k = sizeof(IN6_ADDR) - 1 - i;
169 szReverseName[j] = szHexChar[pAddress->u.Byte[k] & 0xF];
170 szReverseName[j + 1] = L'.';
171 szReverseName[j + 2] = szHexChar[(pAddress->u.Byte[k] >> 4) & 0xF];
172 szReverseName[j + 3] = L'.';
173 }
174 wcscat(szReverseName, L"ip6.arpa.");
175
176 ZeroMemory(&PtrRecord, sizeof(DNS_RECORDW));
177
178 PtrRecord.pName = szReverseName;
179 PtrRecord.wType = DNS_TYPE_PTR;
180 PtrRecord.wDataLength = sizeof(DNS_PTR_DATA);
181 PtrRecord.Flags.S.Section = DnsSectionAnswer;
182 PtrRecord.Flags.S.CharSet = DnsCharSetUnicode;
183 PtrRecord.dwTtl = 86400;
184
185 PtrRecord.Data.PTR.pNameHost = pszHostName;
186
187 DnsIntCacheAddEntry(&AAAARecord, TRUE);
188 DnsIntCacheAddEntry(&PtrRecord, TRUE);
189}
190
191
192static
193FILE *
195{
196 PWSTR ExpandedPath;
198 HKEY DatabaseKey;
199 DWORD RegSize = 0;
200 size_t StringLength;
201 FILE *pHostsFile;
202 DWORD dwError;
203
204 ExpandedPath = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
205 if (ExpandedPath == NULL)
206 return NULL;
207
208 /* Open the database path key */
210 L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
211 0,
212 KEY_READ,
213 &DatabaseKey);
214 if (dwError == ERROR_SUCCESS)
215 {
216 /* Read the actual path */
217 RegQueryValueExW(DatabaseKey,
218 L"DatabasePath",
219 NULL,
220 NULL,
221 NULL,
222 &RegSize);
223
224 DatabasePath = HeapAlloc(GetProcessHeap(), 0, RegSize);
225 if (DatabasePath == NULL)
226 {
227 HeapFree(GetProcessHeap(), 0, ExpandedPath);
228 RegCloseKey(DatabaseKey);
229 return NULL;
230 }
231
232 /* Read the actual path */
233 dwError = RegQueryValueExW(DatabaseKey,
234 L"DatabasePath",
235 NULL,
236 NULL,
238 &RegSize);
239
240 /* Close the key */
241 RegCloseKey(DatabaseKey);
242
243 if (dwError != ERROR_SUCCESS)
244 {
246 HeapFree(GetProcessHeap(), 0, ExpandedPath);
247 return NULL;
248 }
249
250 /* Expand the name */
252
254 }
255 else
256 {
257 /* Use defalt path */
258 GetSystemDirectoryW(ExpandedPath, MAX_PATH);
259
260 StringCchLengthW(ExpandedPath, MAX_PATH, &StringLength);
261 if (ExpandedPath[StringLength - 1] != L'\\')
262 {
263 /* It isn't, so add it ourselves */
264 StringCchCatW(ExpandedPath, MAX_PATH, L"\\");
265 }
266
267 StringCchCatW(ExpandedPath, MAX_PATH, L"drivers\\etc\\");
268 }
269
270 /* Make sure that the path is backslash-terminated */
271 StringCchLengthW(ExpandedPath, MAX_PATH, &StringLength);
272 if (ExpandedPath[StringLength - 1] != L'\\')
273 {
274 /* It isn't, so add it ourselves */
275 StringCchCatW(ExpandedPath, MAX_PATH, L"\\");
276 }
277
278 /* Add the database name */
279 StringCchCatW(ExpandedPath, MAX_PATH, L"hosts");
280
281 /* Open the hosts file */
282 pHostsFile = _wfopen(ExpandedPath, L"r");
283
284 HeapFree(GetProcessHeap(), 0, ExpandedPath);
285
286 return pHostsFile;
287}
288
289
290BOOL
292{
293 CHAR szLineBuffer[512];
294 FILE *pHostFile = NULL;
295 CHAR *Ptr, *NameStart, *NameEnd, *AddressStart, *AddressEnd;
296 struct in_addr Ipv4Address;
297 struct in6_addr Ipv6Address;
298 PWSTR pszHostName;
299
300 pHostFile = OpenHostsFile();
301 if (pHostFile == NULL)
302 return FALSE;
303
304 for (;;)
305 {
306 /* Read a line */
307 if (fgets(szLineBuffer, sizeof(szLineBuffer), pHostFile) == NULL)
308 break;
309
310 NameStart = NameEnd = NULL;
311 AddressStart = AddressEnd = NULL;
312
313 /* Search for the start of the ip address */
314 Ptr = szLineBuffer;
315 for (;;)
316 {
317 if (*Ptr == 0 || *Ptr == '#')
318 break;
319
320 if (!isspace(*Ptr))
321 {
322 AddressStart = Ptr;
323 Ptr = Ptr + 1;
324 break;
325 }
326
327 Ptr = Ptr + 1;
328 }
329
330 /* Search for the end of the ip address */
331 for (;;)
332 {
333 if (*Ptr == 0 || *Ptr == '#')
334 break;
335
336 if (isspace(*Ptr))
337 {
338 AddressEnd = Ptr;
339 Ptr = Ptr + 1;
340 break;
341 }
342
343 Ptr = Ptr + 1;
344 }
345
346 /* Search for the start of the name */
347 for (;;)
348 {
349 if (*Ptr == 0 || *Ptr == '#')
350 break;
351
352 if (!isspace(*Ptr))
353 {
354 NameStart = Ptr;
355 Ptr = Ptr + 1;
356 break;
357 }
358
359 Ptr = Ptr + 1;
360 }
361
362 /* Search for the end of the name */
363 for (;;)
364 {
365 if (*Ptr == 0 || *Ptr == '#')
366 break;
367
368 if (isspace(*Ptr))
369 {
370 NameEnd = Ptr;
371 break;
372 }
373
374 Ptr = Ptr + 1;
375 }
376
377 if (AddressStart == NULL || AddressEnd == NULL ||
378 NameStart == NULL || NameEnd == NULL)
379 continue;
380
381 *AddressEnd = 0;
382 *NameEnd = 0;
383
384 DPRINT("%s ==> %s\n", NameStart, AddressStart);
385
386 if (ParseIpv4Address(AddressStart, &Ipv4Address))
387 {
388 DPRINT("IPv4: %s\n", AddressStart);
389
390 pszHostName = AnsiToUnicode(NameStart);
391 if (pszHostName != NULL)
392 {
393 AddIpv4HostEntries(pszHostName, &Ipv4Address);
394 HeapFree(GetProcessHeap(), 0, pszHostName);
395 }
396 }
397 else if (ParseIpv6Address(AddressStart, &Ipv6Address))
398 {
399 DPRINT("IPv6: %s\n", AddressStart);
400
401 pszHostName = AnsiToUnicode(NameStart);
402 if (pszHostName != NULL)
403 {
404 AddIpv6HostEntries(pszHostName, &Ipv6Address);
405 HeapFree(GetProcessHeap(), 0, pszHostName);
406 }
407 }
408 }
409
410 fclose(pHostFile);
411
412 return TRUE;
413}
414
415/* EOF */
#define isspace(c)
Definition: acclib.h:69
LONG NTSTATUS
Definition: precomp.h:26
VOID DnsIntCacheAddEntry(_In_ PDNS_RECORDW Record, _In_ BOOL bHostsFileEntry)
Definition: cache.c:233
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define MultiByteToWideChar
Definition: compat.h:110
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
#define swprintf
Definition: precomp.h:40
PWSTR DatabasePath
Definition: database.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static BOOL ParseIpv6Address(_In_ LPCSTR AddressString, _Out_ PIN6_ADDR pAddress)
Definition: hostsfile.c:76
static WCHAR szHexChar[]
Definition: hostsfile.c:18
static FILE * OpenHostsFile(VOID)
Definition: hostsfile.c:194
BOOL ReadHostsFile(VOID)
Definition: hostsfile.c:291
static VOID AddIpv4HostEntries(PWSTR pszHostName, PIN_ADDR pAddress)
Definition: hostsfile.c:95
static BOOL ParseIpv4Address(_In_ PCSTR AddressString, _Out_ PIN_ADDR pAddress)
Definition: hostsfile.c:56
static PWSTR AnsiToUnicode(PSTR NarrowString)
Definition: hostsfile.c:22
static VOID AddIpv6HostEntries(PWSTR pszHostName, PIN6_ADDR pAddress)
Definition: hostsfile.c:140
struct in6_addr IN6_ADDR
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
int k
Definition: mpi.c:3369
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
NTSYSAPI NTSTATUS NTAPI RtlIpv4StringToAddressA(_In_ PCSTR String, _In_ BOOLEAN Strict, _Out_ PCSTR *Terminator, _Out_ struct in_addr *Addr)
Definition: network.c:338
NTSYSAPI NTSTATUS NTAPI RtlIpv6StringToAddressA(_In_ PCSTR String, _Out_ PCSTR *Terminator, _Out_ struct in6_addr *Addr)
Definition: network.c:745
#define KEY_READ
Definition: nt_native.h:1023
#define L(x)
Definition: ntvdm.h:50
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define DPRINT
Definition: sndvol32.h:73
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchLengthW(STRSAFE_LPCWSTR psz, size_t cchMax, size_t *pcchLength)
Definition: strsafe.h:842
DNS_IP6_ADDRESS Ip6Address
Definition: windns.h:250
IP4_ADDRESS IpAddress
Definition: windns.h:246
LPWSTR pNameHost
Definition: windns.h:319
DWORD CharSet
Definition: windns.h:240
DWORD Section
Definition: windns.h:238
WORD wType
Definition: windns.h:600
LPWSTR pName
Definition: windns.h:599
DNS_A_DATA A
Definition: windns.h:609
DNS_AAAA_DATA AAAA
Definition: windns.h:617
DNS_RECORD_FLAGS S
Definition: windns.h:604
union _DnsRecordW::@3321 Data
union _DnsRecordW::@3320 Flags
DWORD dwTtl
Definition: windns.h:606
WORD wDataLength
Definition: windns.h:601
DNS_PTR_DATAW PTR
Definition: windns.h:611
union in6_addr::@3013 u
UCHAR Byte[16]
Definition: in6addr.h:5
Definition: tcpip.h:126
u_long S_addr
Definition: tcpip.h:131
union in_addr::@1027 S_un
struct in_addr::@1027::@1028 S_un_b
uint16_t * PWSTR
Definition: typedefs.h:56
char * PSTR
Definition: typedefs.h:51
unsigned char * LPBYTE
Definition: typedefs.h:53
const char * PCSTR
Definition: typedefs.h:52
#define ZeroMemory
Definition: winbase.h:1712
#define CopyMemory
Definition: winbase.h:1710
@ DnsSectionAnswer
Definition: windns.h:154
#define DNS_TYPE_PTR
Definition: windns.h:52
#define DNS_PTR_DATA
Definition: windns.h:923
@ DnsCharSetUnicode
Definition: windns.h:111
#define DNS_TYPE_AAAA
Definition: windns.h:68
#define DNS_TYPE_A
Definition: windns.h:41
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175