6 static BOOL
DnsIntNameContainsDots( LPCWSTR Name
) {
7 return wcschr( Name
, '.' ) ? TRUE
: FALSE
;
10 static BOOL
DnsIntTwoConsecutiveDots( LPCWSTR Name
) {
11 return wcsstr( Name
, L
".." ) ? TRUE
: FALSE
;
14 static BOOL
DnsIntContainsUnderscore( LPCWSTR Name
) {
15 return wcschr( Name
, '_' ) ? TRUE
: FALSE
;
18 /* DnsValidateName *********************
19 * Use some different algorithms to validate the given name as suitable for
22 * Name -- The name to evaluate.
23 * Format -- Format to use:
27 * DnsNameHostnameLabel
31 * ERROR_SUCCESS -- All good
32 * ERROR_INVALID_NAME --
33 * Name greater than 255 chars.
34 * Label greater than 63 chars.
35 * Two consecutive dots, or starts with dot.
36 * Contains a dot, but a Label check was specified.
37 * DNS_ERROR_INVALID_NAME_CHAR
38 * Contains any invalid char: " {|}~[\]^':;<=>?@!"#$%^`()+/,"
39 * Contains an *, except when it is the first label and Wildcard was
41 * DNS_ERROR_NUMERIC_NAME
42 * Set if the name contains only numerics, unless Domain is specified.
43 * DNS_ERROR_NON_RFC_NAME
44 * If the name contains underscore.
45 * If there is an underscore in any position but the first in the SrvRecord
47 * If the name contains a non-ascii character.
50 DNS_STATUS WINAPI DnsValidateName_W
52 DNS_NAME_FORMAT Format
) {
53 BOOL AllowDot
= FALSE
;
54 BOOL AllowLeadingAst
= FALSE
;
55 BOOL AllowLeadingUnderscore
= FALSE
;
56 BOOL AllowAllDigits
= FALSE
;
57 const WCHAR
*NextLabel
, *CurrentLabel
, *CurrentChar
;
61 AllowAllDigits
= TRUE
;
64 case DnsNameDomainLabel
:
65 AllowAllDigits
= TRUE
;
67 case DnsNameHostnameFull
:
70 case DnsNameHostnameLabel
:
73 AllowLeadingAst
= TRUE
;
76 case DnsNameSrvRecord
:
77 AllowLeadingUnderscore
= TRUE
;
83 /* Preliminary checks */
84 if( Name
[0] == 0 ) return ERROR_INVALID_NAME
; /* XXX arty: Check this */
87 if( wcslen( Name
) > 255 ) {
88 return ERROR_INVALID_NAME
;
91 /* Violations about dots */
92 if( (!AllowDot
&& DnsIntNameContainsDots( Name
)) ||
93 Name
[0] == '.' || DnsIntTwoConsecutiveDots( Name
) )
94 return ERROR_INVALID_NAME
;
96 /* Check component sizes */
99 NextLabel
= CurrentLabel
;
100 while( *NextLabel
&& *NextLabel
!= '.' ) NextLabel
++;
102 if( NextLabel
- CurrentLabel
> 63 )
103 return ERROR_INVALID_NAME
;
105 CurrentLabel
= NextLabel
;
106 } while( *CurrentLabel
);
110 while( *CurrentChar
) {
111 if( wcschr(L
" {|}~[\\]^':;<=>?@!\"#$%^`()+/,",*CurrentChar
) )
112 return DNS_ERROR_INVALID_NAME_CHAR
;
116 if( (!AllowLeadingAst
&& Name
[0] == '*') ||
117 (AllowLeadingAst
&& Name
[0] == '*' && Name
[1] && Name
[1] != '.') )
118 return DNS_ERROR_INVALID_NAME_CHAR
;
120 if( wcschr( Name
+ 1, '*' ) )
121 return DNS_ERROR_INVALID_NAME_CHAR
;
124 while( !AllowAllDigits
&& *CurrentChar
) {
125 if( *CurrentChar
== '.' || (*CurrentChar
>= '0' && *CurrentChar
<= '9') )
126 return DNS_ERROR_NUMERIC_NAME
;
129 if( ((AllowLeadingUnderscore
&& Name
[0] == '_') || Name
[0] != '_') &&
130 !DnsIntContainsUnderscore( Name
+ 1 ) )
131 return DNS_ERROR_NON_RFC_NAME
;
133 return ERROR_SUCCESS
;
136 DNS_STATUS WINAPI DnsValidateName_UTF8
138 DNS_NAME_FORMAT Format
) {
143 StrLenWc
= mbstowcs( NULL
, Name
, 0 );
144 Buffer
= RtlAllocateHeap( GetProcessHeap(), 0,
145 sizeof( WCHAR
) * (StrLenWc
+ 1) );
146 mbstowcs( Buffer
, Name
, StrLenWc
+ 1 );
147 Status
= DnsValidateName_W( Buffer
, Format
);
148 RtlFreeHeap( GetProcessHeap(), 0, Buffer
);
153 DNS_STATUS WINAPI DnsValidateName_A
155 DNS_NAME_FORMAT Format
) {
156 return DnsValidateName_UTF8( Name
, Format
);
159 /* DnsNameCompare **********************
160 * Return TRUE if the names are identical.
162 * Name1 & Name2 -- Names.
165 BOOL WINAPI DnsNameCompare_W
170 while( Name1
[offset
] && Name2
[offset
] &&
171 towupper( Name1
[offset
] ) == towupper( Name2
[offset
] ) ) offset
++;
173 (!Name1
[offset
] && !Name2
[offset
]) ||
174 (!Name1
[offset
] && !wcscmp( Name2
+ offset
, L
"." )) ||
175 (!Name2
[offset
] && !wcscmp( Name1
+ offset
, L
"." ));
178 BOOL WINAPI DnsNameCompare_UTF8
183 while( Name1
[offset
] && Name2
[offset
] &&
184 toupper( Name1
[offset
] ) == toupper( Name2
[offset
] ) ) offset
++;
186 (!Name1
[offset
] && !Name2
[offset
]) ||
187 (!Name1
[offset
] && !strcmp( Name2
+ offset
, ".")) ||
188 (!Name2
[offset
] && !strcmp( Name1
+ offset
, "."));
191 BOOL WINAPI DnsNameCompare_A
194 return DnsNameCompare_UTF8( Name1
, Name2
);