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.
19 /* $Id: dos8dot3.c,v 1.6 2002/09/08 10:23:41 chorns Exp $
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 *****************************************************************/
39 const PWCHAR RtlpShortIllegals
= L
" ;+=[]',\"*\\<>/?:|";
42 /* FUNCTIONS *****************************************************************/
45 RtlpIsShortIllegal(WCHAR Char
)
49 for (i
= 0; RtlpShortIllegals
[i
]; i
++)
51 if (Char
== RtlpShortIllegals
[i
])
60 RtlGenerate8dot3Name(IN PUNICODE_STRING Name
,
61 IN BOOLEAN AllowExtendedCharacters
,
62 IN OUT PGENERATE_NAME_CONTEXT Context
,
63 OUT PUNICODE_STRING Name8dot3
)
75 memset(NameBuffer
, 0, sizeof(NameBuffer
));
76 memset(ExtBuffer
, 0, sizeof(ExtBuffer
));
78 StrLength
= Name
->Length
/ sizeof(WCHAR
);
79 DPRINT("StrLength: %hu\n", StrLength
);
81 /* Find last dot in Name */
83 for (i
= 0; i
< StrLength
; i
++)
85 if (Name
->Buffer
[i
] == L
'.')
95 DPRINT("DotPos: %hu\n", DotPos
);
97 /* Copy name (6 valid characters max) */
98 for (i
= 0, NameLength
= 0; NameLength
< 6 && i
< DotPos
; i
++)
100 if ((!RtlpIsShortIllegal(Name
->Buffer
[i
])) &&
101 (Name
->Buffer
[i
] != L
'.'))
103 NameBuffer
[NameLength
++] = RtlUpcaseUnicodeChar(Name
->Buffer
[i
]);
106 DPRINT("NameBuffer: '%.08S'\n", NameBuffer
);
107 DPRINT("NameLength: %hu\n", NameLength
);
109 /* Copy extension (4 valid characters max) */
110 if (DotPos
< StrLength
)
112 for (i
= DotPos
, ExtLength
= 0; ExtLength
< 4 && i
< StrLength
; i
++)
114 if (!RtlpIsShortIllegal(Name
->Buffer
[i
]))
116 ExtBuffer
[ExtLength
++] = RtlUpcaseUnicodeChar(Name
->Buffer
[i
]);
124 DPRINT("ExtBuffer: '%.04S'\n", ExtBuffer
);
125 DPRINT("ExtLength: %hu\n", ExtLength
);
127 /* Determine next index */
128 CurrentIndex
= Context
->LastIndexValue
;
129 CopyLength
= min(NameLength
, (CurrentIndex
< 10) ? 6 : 5);
130 DPRINT("CopyLength: %hu\n", CopyLength
);
132 if ((Context
->NameLength
== CopyLength
) &&
133 (wcsncmp(Context
->NameBuffer
, NameBuffer
, CopyLength
) == 0) &&
134 (Context
->ExtensionLength
== ExtLength
) &&
135 (wcsncmp(Context
->ExtensionBuffer
, ExtBuffer
, ExtLength
) == 0))
139 DPRINT("CurrentIndex: %hu\n", CurrentIndex
);
141 /* Build the short name */
142 for (i
= 0; i
< CopyLength
; i
++)
144 Name8dot3
->Buffer
[i
] = NameBuffer
[i
];
147 Name8dot3
->Buffer
[i
++] = L
'~';
148 if (CurrentIndex
>= 10)
149 Name8dot3
->Buffer
[i
++] = (CurrentIndex
/ 10) + L
'0';
150 Name8dot3
->Buffer
[i
++] = (CurrentIndex
% 10) + L
'0';
152 for (j
= 0; j
< ExtLength
; i
++, j
++)
154 Name8dot3
->Buffer
[i
] = ExtBuffer
[j
];
157 Name8dot3
->Length
= i
* sizeof(WCHAR
);
159 DPRINT("Name8dot3: '%wZ'\n", Name8dot3
);
162 Context
->NameLength
= CopyLength
;
163 for (i
= 0; i
< CopyLength
; i
++)
165 Context
->NameBuffer
[i
] = NameBuffer
[i
];
168 Context
->ExtensionLength
= ExtLength
;
169 for (i
= 0; i
< ExtLength
; i
++)
171 Context
->ExtensionBuffer
[i
] = ExtBuffer
[i
];
174 Context
->LastIndexValue
= CurrentIndex
;
179 RtlIsNameLegalDOS8Dot3(IN PUNICODE_STRING UnicodeName
,
180 IN PANSI_STRING AnsiName
,
181 OUT PBOOLEAN SpacesFound
)
183 PANSI_STRING name
= AnsiName
;
184 ANSI_STRING DummyString
;
190 BOOLEAN HasSpace
= FALSE
;
191 BOOLEAN HasDot
= FALSE
;
193 if (UnicodeName
->Length
> 24)
195 return(FALSE
); /* name too long */
202 name
->MaximumLength
= 12;
203 name
->Buffer
= Buffer
;
206 Status
= RtlUpcaseUnicodeStringToCountedOemString(name
,
209 if (!NT_SUCCESS(Status
))
214 Length
= name
->Length
;
217 if (!(Length
== 1 && *str
== '.') &&
218 !(Length
== 2 && *str
== '.' && *(str
+ 1) == '.'))
220 for (i
= 0; i
< Length
; i
++, str
++)
229 if ((HasDot
) || /* two or more dots */
230 (i
== 0) || /* dot is first char */
231 (i
+ 1 == Length
) || /* dot is last char */
232 (Length
- i
> 4) || /* more than 3 chars of extension */
233 (HasDot
== FALSE
&& i
> 8)) /* name is longer than 8 chars */
241 /* Name is longer than 8 chars and does not have an extension */
242 if (Length
> 8 && HasDot
== FALSE
)
248 *SpacesFound
= HasSpace
;