4 * Copyright (C) 2006 Matthew Kehrer
5 * Copyright (C) 2006 Hans Leidekker
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 /******************************************************************************
28 * DnsNameCompare_A [DNSAPI.@]
31 BOOL WINAPI
DnsNameCompare_A( LPCSTR name1
, LPCSTR name2
)
36 name1W
= dns_strdup_aw( name1
);
37 name2W
= dns_strdup_aw( name2
);
39 ret
= DnsNameCompare_W( name1W
, name2W
);
41 HeapFree(GetProcessHeap(), 0, name1W
);
42 HeapFree(GetProcessHeap(), 0, name2W
);
47 /******************************************************************************
48 * DnsNameCompare_W [DNSAPI.@]
51 BOOL WINAPI
DnsNameCompare_W( PCWSTR name1
, PCWSTR name2
)
55 if (!name1
&& !name2
) return TRUE
;
56 if (!name1
|| !name2
) return FALSE
;
58 p
= name1
+ lstrlenW( name1
) - 1;
59 q
= name2
+ lstrlenW( name2
) - 1;
61 while (*p
== '.' && p
>= name1
) p
--;
62 while (*q
== '.' && q
>= name2
) q
--;
64 if (p
- name1
!= q
- name2
) return FALSE
;
68 if (towupper( *name1
) != towupper( *name2
))
77 /******************************************************************************
78 * DnsValidateName_A [DNSAPI.@]
81 DNS_STATUS WINAPI
DnsValidateName_A( PCSTR name
, DNS_NAME_FORMAT format
)
86 nameW
= dns_strdup_aw( name
);
87 ret
= DnsValidateName_W( nameW
, format
);
89 HeapFree(GetProcessHeap(), 0, nameW
);
93 /******************************************************************************
94 * DnsValidateName_UTF8 [DNSAPI.@]
97 DNS_STATUS WINAPI
DnsValidateName_UTF8( PCSTR name
, DNS_NAME_FORMAT format
)
102 nameW
= dns_strdup_uw( name
);
103 ret
= DnsValidateName_W( nameW
, format
);
105 HeapFree(GetProcessHeap(), 0, nameW
);
109 #define HAS_EXTENDED 0x0001
110 #define HAS_NUMERIC 0x0002
111 #define HAS_NON_NUMERIC 0x0004
112 #define HAS_DOT 0x0008
113 #define HAS_DOT_DOT 0x0010
114 #define HAS_SPACE 0x0020
115 #define HAS_INVALID 0x0040
116 #define HAS_ASTERISK 0x0080
117 #define HAS_UNDERSCORE 0x0100
118 #define HAS_LONG_LABEL 0x0200
120 /******************************************************************************
121 * DnsValidateName_W [DNSAPI.@]
124 DNS_STATUS WINAPI
DnsValidateName_W( PCWSTR name
, DNS_NAME_FORMAT format
)
127 unsigned int i
, j
, state
= 0;
128 static const WCHAR invalid
[] = {
129 '{','|','}','~','[','\\',']','^','\'',':',';','<','=','>',
130 '?','@','!','\"','#','$','%','^','`','(',')','+','/',',',0 };
132 if (!name
) return ERROR_INVALID_NAME
;
134 for (p
= name
, i
= 0, j
= 0; *p
; p
++, i
++, j
++)
140 if (p
[1] == '.') state
|= HAS_DOT_DOT
;
142 else if (*p
< '0' || *p
> '9') state
|= HAS_NON_NUMERIC
;
143 else state
|= HAS_NUMERIC
;
145 if (j
> 62) state
|= HAS_LONG_LABEL
;
147 if (wcschr( invalid
, *p
)) state
|= HAS_INVALID
;
148 else if ((unsigned)*p
> 127) state
|= HAS_EXTENDED
;
149 else if (*p
== ' ') state
|= HAS_SPACE
;
150 else if (*p
== '_') state
|= HAS_UNDERSCORE
;
151 else if (*p
== '*') state
|= HAS_ASTERISK
;
154 if (i
== 0 || i
> 255 ||
155 (state
& HAS_LONG_LABEL
) ||
156 (state
& HAS_DOT_DOT
) ||
157 (name
[0] == '.' && name
[1])) return ERROR_INVALID_NAME
;
163 if (!(state
& HAS_NON_NUMERIC
) && (state
& HAS_NUMERIC
))
164 return DNS_ERROR_NUMERIC_NAME
;
165 if ((state
& HAS_EXTENDED
) || (state
& HAS_UNDERSCORE
))
166 return DNS_ERROR_NON_RFC_NAME
;
167 if ((state
& HAS_SPACE
) ||
168 (state
& HAS_INVALID
) ||
169 (state
& HAS_ASTERISK
)) return DNS_ERROR_INVALID_NAME_CHAR
;
172 case DnsNameDomainLabel
:
174 if (state
& HAS_DOT
) return ERROR_INVALID_NAME
;
175 if ((state
& HAS_EXTENDED
) || (state
& HAS_UNDERSCORE
))
176 return DNS_ERROR_NON_RFC_NAME
;
177 if ((state
& HAS_SPACE
) ||
178 (state
& HAS_INVALID
) ||
179 (state
& HAS_ASTERISK
)) return DNS_ERROR_INVALID_NAME_CHAR
;
182 case DnsNameHostnameFull
:
184 if (!(state
& HAS_NON_NUMERIC
) && (state
& HAS_NUMERIC
))
185 return DNS_ERROR_NUMERIC_NAME
;
186 if ((state
& HAS_EXTENDED
) || (state
& HAS_UNDERSCORE
))
187 return DNS_ERROR_NON_RFC_NAME
;
188 if ((state
& HAS_SPACE
) ||
189 (state
& HAS_INVALID
) ||
190 (state
& HAS_ASTERISK
)) return DNS_ERROR_INVALID_NAME_CHAR
;
193 case DnsNameHostnameLabel
:
195 if (state
& HAS_DOT
) return ERROR_INVALID_NAME
;
196 if (!(state
& HAS_NON_NUMERIC
) && (state
& HAS_NUMERIC
))
197 return DNS_ERROR_NUMERIC_NAME
;
198 if ((state
& HAS_EXTENDED
) || (state
& HAS_UNDERSCORE
))
199 return DNS_ERROR_NON_RFC_NAME
;
200 if ((state
& HAS_SPACE
) ||
201 (state
& HAS_INVALID
) ||
202 (state
& HAS_ASTERISK
)) return DNS_ERROR_INVALID_NAME_CHAR
;
205 case DnsNameWildcard
:
207 if (!(state
& HAS_NON_NUMERIC
) && (state
& HAS_NUMERIC
))
208 return ERROR_INVALID_NAME
;
209 if (name
[0] != '*') return ERROR_INVALID_NAME
;
210 if (name
[1] && name
[1] != '.')
211 return DNS_ERROR_INVALID_NAME_CHAR
;
212 if ((state
& HAS_EXTENDED
) ||
213 (state
& HAS_SPACE
) ||
214 (state
& HAS_INVALID
)) return ERROR_INVALID_NAME
;
217 case DnsNameSrvRecord
:
219 if (!(state
& HAS_NON_NUMERIC
) && (state
& HAS_NUMERIC
))
220 return ERROR_INVALID_NAME
;
221 if (name
[0] != '_') return ERROR_INVALID_NAME
;
222 if ((state
& HAS_UNDERSCORE
) && !name
[1])
223 return DNS_ERROR_NON_RFC_NAME
;
224 if ((state
& HAS_EXTENDED
) ||
225 (state
& HAS_SPACE
) ||
226 (state
& HAS_INVALID
)) return ERROR_INVALID_NAME
;
230 DPRINT1( "unknown format: %d\n", format
);
233 return ERROR_SUCCESS
;