3 * Copyright (C) 2002 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: ntoskrnl/rtl/dos8dot3.c
24 * PURPOSE: Short name (8.3 name) functions
25 * PROGRAMMER: Eric Kohl
28 /* INCLUDES ******************************************************************/
30 #include <ddk/ntddk.h>
31 #include <ntos/minmax.h>
34 #include <internal/debug.h>
37 /* CONSTANTS *****************************************************************/
40 static const WCHAR *RtlpShortIllegals;
41 #endif /* LIBCAPTIVE */
44 /* FUNCTIONS *****************************************************************/
49 RtlpIsShortIllegal(WCHAR Char)
53 if (!RtlpShortIllegals)
54 RtlpShortIllegals = REACTOS_UCS2(L" ;+=[]',\"*\\<>/?:|");
56 for (i = 0; RtlpShortIllegals[i]; i++)
58 if (Char == RtlpShortIllegals[i])
67 RtlGenerate8dot3Name(IN PUNICODE_STRING Name,
68 IN BOOLEAN AllowExtendedCharacters,
69 IN OUT PGENERATE_NAME_CONTEXT Context,
70 OUT PUNICODE_STRING Name8dot3)
82 memset(NameBuffer, 0, sizeof(NameBuffer));
83 memset(ExtBuffer, 0, sizeof(ExtBuffer));
85 StrLength = Name->Length / sizeof(WCHAR);
86 DPRINT("StrLength: %hu\n", StrLength);
88 /* Find last dot in Name */
90 for (i = 0; i < StrLength; i++)
92 if (Name->Buffer[i] == L'.')
102 DPRINT("DotPos: %hu\n", DotPos);
104 /* Copy name (6 valid characters max) */
105 for (i = 0, NameLength = 0; NameLength < 6 && i < DotPos; i++)
107 if ((!RtlpIsShortIllegal(Name->Buffer[i])) &&
108 (Name->Buffer[i] != L'.'))
110 NameBuffer[NameLength++] = RtlUpcaseUnicodeChar(Name->Buffer[i]);
113 DPRINT("NameBuffer: '%.08S'\n", NameBuffer);
114 DPRINT("NameLength: %hu\n", NameLength);
116 /* Copy extension (4 valid characters max) */
117 if (DotPos < StrLength)
119 for (i = DotPos, ExtLength = 0; ExtLength < 4 && i < StrLength; i++)
121 if (!RtlpIsShortIllegal(Name->Buffer[i]))
123 ExtBuffer[ExtLength++] = RtlUpcaseUnicodeChar(Name->Buffer[i]);
131 DPRINT("ExtBuffer: '%.04S'\n", ExtBuffer);
132 DPRINT("ExtLength: %hu\n", ExtLength);
134 /* Determine next index */
135 CurrentIndex = Context->LastIndexValue;
136 CopyLength = min(NameLength, (CurrentIndex < 10) ? 6 : 5);
137 DPRINT("CopyLength: %hu\n", CopyLength);
139 if ((Context->NameLength == CopyLength) &&
140 (wcsncmp(Context->NameBuffer, NameBuffer, CopyLength) == 0) &&
141 (Context->ExtensionLength == ExtLength) &&
142 (wcsncmp(Context->ExtensionBuffer, ExtBuffer, ExtLength) == 0))
146 DPRINT("CurrentIndex: %hu\n", CurrentIndex);
148 /* Build the short name */
149 for (i = 0; i < CopyLength; i++)
151 Name8dot3->Buffer[i] = NameBuffer[i];
154 Name8dot3->Buffer[i++] = L'~';
155 if (CurrentIndex >= 10)
156 Name8dot3->Buffer[i++] = (CurrentIndex / 10) + L'0';
157 Name8dot3->Buffer[i++] = (CurrentIndex % 10) + L'0';
159 for (j = 0; j < ExtLength; i++, j++)
161 Name8dot3->Buffer[i] = ExtBuffer[j];
164 Name8dot3->Length = i * sizeof(WCHAR);
166 DPRINT("Name8dot3: '%wZ'\n", Name8dot3);
169 Context->NameLength = CopyLength;
170 for (i = 0; i < CopyLength; i++)
172 Context->NameBuffer[i] = NameBuffer[i];
175 Context->ExtensionLength = ExtLength;
176 for (i = 0; i < ExtLength; i++)
178 Context->ExtensionBuffer[i] = ExtBuffer[i];
181 Context->LastIndexValue = CurrentIndex;
186 RtlIsNameLegalDOS8Dot3(IN PUNICODE_STRING UnicodeName,
187 IN PANSI_STRING AnsiName,
188 OUT PBOOLEAN SpacesFound)
190 PANSI_STRING name = AnsiName;
191 ANSI_STRING DummyString;
197 BOOLEAN HasSpace = FALSE;
198 BOOLEAN HasDot = FALSE;
200 if (UnicodeName->Length > 24)
202 return(FALSE); /* name too long */
209 name->MaximumLength = 12;
210 name->Buffer = Buffer;
213 Status = RtlUpcaseUnicodeStringToCountedOemString(name,
216 if (!NT_SUCCESS(Status))
221 Length = name->Length;
224 if (!(Length == 1 && *str == '.') &&
225 !(Length == 2 && *str == '.' && *(str + 1) == '.'))
227 for (i = 0; i < Length; i++, str++)
236 if ((HasDot) || /* two or more dots */
237 (i == 0) || /* dot is first char */
238 (i + 1 == Length) || /* dot is last char */
239 (Length - i > 4) || /* more than 3 chars of extension */
240 (HasDot == FALSE && i > 8)) /* name is longer than 8 chars */
248 /* Name is longer than 8 chars and does not have an extension */
249 if (Length > 8 && HasDot == FALSE)
255 *SpacesFound = HasSpace;
260 #endif /* LIBCAPTIVE */