4 * Copyright 2002, 2003 Alexandre Julliard
5 * Copyright 2003 Eric Pouech
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "wine/unicode.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(file);
30 #define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
32 /***********************************************************************
33 * RtlDetermineDosPathNameType_U (NTDLL.@)
35 DOS_PATHNAME_TYPE WINAPI RtlDetermineDosPathNameType_U( PCWSTR path )
37 if (IS_SEPARATOR(path[0]))
39 if (!IS_SEPARATOR(path[1])) return ABSOLUTE_PATH; /* "/foo" */
40 if (path[2] != '.') return UNC_PATH; /* "//foo" */
41 if (IS_SEPARATOR(path[3])) return DEVICE_PATH; /* "//./foo" */
42 if (path[3]) return UNC_PATH; /* "//.foo" */
43 return UNC_DOT_PATH; /* "//." */
47 if (!path[0] || path[1] != ':') return RELATIVE_PATH; /* "foo" */
48 if (IS_SEPARATOR(path[2])) return ABSOLUTE_DRIVE_PATH; /* "c:/foo" */
49 return RELATIVE_DRIVE_PATH; /* "c:foo" */
54 /***********************************************************************
55 * RtlIsDosDeviceName_U (NTDLL.@)
57 * Check if the given DOS path contains a DOS device name.
59 * Returns the length of the device name in the low word and its
60 * position in the high word (both in bytes, not WCHARs), or 0 if no
61 * device name is found.
63 ULONG WINAPI RtlIsDosDeviceName_U( PCWSTR dos_name )
65 static const WCHAR consoleW[] = {'\\','\\','.','\\','C','O','N',0};
66 static const WCHAR auxW[3] = {'A','U','X'};
67 static const WCHAR comW[3] = {'C','O','M'};
68 static const WCHAR conW[3] = {'C','O','N'};
69 static const WCHAR lptW[3] = {'L','P','T'};
70 static const WCHAR nulW[3] = {'N','U','L'};
71 static const WCHAR prnW[3] = {'P','R','N'};
73 const WCHAR *start, *end, *p;
75 switch(RtlDetermineDosPathNameType_U( dos_name ))
81 if (!strcmpiW( dos_name, consoleW ))
82 return MAKELONG( sizeof(conW), 4 * sizeof(WCHAR) ); /* 4 is length of \\.\ prefix */
88 end = dos_name + strlenW(dos_name) - 1;
89 if (end >= dos_name && *end == ':') end--; /* remove trailing ':' */
91 /* find start of file name */
92 for (start = end; start >= dos_name; start--)
94 if (IS_SEPARATOR(start[0])) break;
95 /* check for ':' but ignore if before extension (for things like NUL:.txt) */
96 if (start[0] == ':' && start[1] != '.') break;
100 /* remove extension */
101 if ((p = strchrW( start, '.' )))
104 if (end >= dos_name && *end == ':') end--; /* remove trailing ':' before extension */
108 /* no extension, remove trailing spaces */
109 while (end >= dos_name && *end == ' ') end--;
112 /* now we have a potential device name between start and end, check it */
113 switch(end - start + 1)
116 if (strncmpiW( start, auxW, 3 ) &&
117 strncmpiW( start, conW, 3 ) &&
118 strncmpiW( start, nulW, 3 ) &&
119 strncmpiW( start, prnW, 3 )) break;
120 return MAKELONG( 3 * sizeof(WCHAR), (start - dos_name) * sizeof(WCHAR) );
122 if (strncmpiW( start, comW, 3 ) && strncmpiW( start, lptW, 3 )) break;
123 if (*end <= '0' || *end > '9') break;
124 return MAKELONG( 4 * sizeof(WCHAR), (start - dos_name) * sizeof(WCHAR) );
125 default: /* can't match anything */
132 /******************************************************************
133 * RtlIsNameLegalDOS8Dot3 (NTDLL.@)
135 * Returns TRUE iff unicode is a valid DOS (8+3) name.
136 * If the name is valid, oem gets filled with the corresponding OEM string
137 * spaces is set to TRUE if unicode contains spaces
139 BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3( const UNICODE_STRING *unicode,
140 OEM_STRING *oem, BOOLEAN *spaces )
146 BOOLEAN got_space = FALSE;
150 oem_str.Length = sizeof(buffer);
151 oem_str.MaximumLength = sizeof(buffer);
152 oem_str.Buffer = buffer;
155 if (RtlUpcaseUnicodeStringToCountedOemString( oem, unicode, FALSE ) != STATUS_SUCCESS)
158 if (oem->Length > 12) return FALSE;
160 /* a starting . is invalid, except for . and .. */
161 if (oem->Buffer[0] == '.')
163 if (oem->Length != 1 && (oem->Length != 2 || oem->Buffer[1] != '.')) return FALSE;
164 if (spaces) *spaces = FALSE;
168 for (i = 0; i < oem->Length; i++)
170 switch (oem->Buffer[i])
173 /* leading/trailing spaces not allowed */
174 if (!i || i == oem->Length-1 || oem->Buffer[i+1] == '.') return FALSE;
178 if (dot != -1) return FALSE;
182 /* FIXME: check for invalid chars */
186 /* check file part is shorter than 8, extension shorter than 3
187 * dot cannot be last in string
191 if (oem->Length > 8) return FALSE;
195 if (dot > 8 || (oem->Length - dot > 4) || dot == oem->Length - 1) return FALSE;
197 if (spaces) *spaces = got_space;