1*23b7c7b8SHermès Bélusca-Maïto /*++
2*23b7c7b8SHermès Bélusca-Maïto
3*23b7c7b8SHermès Bélusca-Maïto Copyright (c) 1989-2000 Microsoft Corporation
4*23b7c7b8SHermès Bélusca-Maïto
5*23b7c7b8SHermès Bélusca-Maïto Module Name:
6*23b7c7b8SHermès Bélusca-Maïto
7*23b7c7b8SHermès Bélusca-Maïto NameSup.c
8*23b7c7b8SHermès Bélusca-Maïto
9*23b7c7b8SHermès Bélusca-Maïto Abstract:
10*23b7c7b8SHermès Bélusca-Maïto
11*23b7c7b8SHermès Bélusca-Maïto This module implements the Fat Name support routines
12*23b7c7b8SHermès Bélusca-Maïto
13*23b7c7b8SHermès Bélusca-Maïto
14*23b7c7b8SHermès Bélusca-Maïto --*/
15*23b7c7b8SHermès Bélusca-Maïto
16*23b7c7b8SHermès Bélusca-Maïto #include "fatprocs.h"
17*23b7c7b8SHermès Bélusca-Maïto
18*23b7c7b8SHermès Bélusca-Maïto #define Dbg (DEBUG_TRACE_NAMESUP)
19*23b7c7b8SHermès Bélusca-Maïto
20*23b7c7b8SHermès Bélusca-Maïto #ifdef ALLOC_PRAGMA
21*23b7c7b8SHermès Bélusca-Maïto #pragma alloc_text(PAGE, Fat8dot3ToString)
22*23b7c7b8SHermès Bélusca-Maïto #pragma alloc_text(PAGE, FatIsNameInExpression)
23*23b7c7b8SHermès Bélusca-Maïto #pragma alloc_text(PAGE, FatStringTo8dot3)
24*23b7c7b8SHermès Bélusca-Maïto #pragma alloc_text(PAGE, FatSetFullFileNameInFcb)
25*23b7c7b8SHermès Bélusca-Maïto #pragma alloc_text(PAGE, FatGetUnicodeNameFromFcb)
26*23b7c7b8SHermès Bélusca-Maïto #pragma alloc_text(PAGE, FatUnicodeToUpcaseOem)
27*23b7c7b8SHermès Bélusca-Maïto #pragma alloc_text(PAGE, FatSelectNames)
28*23b7c7b8SHermès Bélusca-Maïto #pragma alloc_text(PAGE, FatEvaluateNameCase)
29*23b7c7b8SHermès Bélusca-Maïto #pragma alloc_text(PAGE, FatSpaceInName)
30*23b7c7b8SHermès Bélusca-Maïto #pragma alloc_text(PAGE, FatUnicodeRestoreShortNameCase)
31*23b7c7b8SHermès Bélusca-Maïto #endif
32*23b7c7b8SHermès Bélusca-Maïto
33*23b7c7b8SHermès Bélusca-Maïto
34*23b7c7b8SHermès Bélusca-Maïto BOOLEAN
FatIsNameInExpression(IN PIRP_CONTEXT IrpContext,IN OEM_STRING Expression,IN OEM_STRING Name)35*23b7c7b8SHermès Bélusca-Maïto FatIsNameInExpression (
36*23b7c7b8SHermès Bélusca-Maïto IN PIRP_CONTEXT IrpContext,
37*23b7c7b8SHermès Bélusca-Maïto IN OEM_STRING Expression,
38*23b7c7b8SHermès Bélusca-Maïto IN OEM_STRING Name
39*23b7c7b8SHermès Bélusca-Maïto )
40*23b7c7b8SHermès Bélusca-Maïto
41*23b7c7b8SHermès Bélusca-Maïto /*++
42*23b7c7b8SHermès Bélusca-Maïto
43*23b7c7b8SHermès Bélusca-Maïto Routine Description:
44*23b7c7b8SHermès Bélusca-Maïto
45*23b7c7b8SHermès Bélusca-Maïto This routine compare a name and an expression and tells the caller if
46*23b7c7b8SHermès Bélusca-Maïto the name is equal to or not equal to the expression. The input name
47*23b7c7b8SHermès Bélusca-Maïto cannot contain wildcards, while the expression may contain wildcards.
48*23b7c7b8SHermès Bélusca-Maïto
49*23b7c7b8SHermès Bélusca-Maïto Arguments:
50*23b7c7b8SHermès Bélusca-Maïto
51*23b7c7b8SHermès Bélusca-Maïto Expression - Supplies the input expression to check against
52*23b7c7b8SHermès Bélusca-Maïto The caller must have already upcased the Expression.
53*23b7c7b8SHermès Bélusca-Maïto
54*23b7c7b8SHermès Bélusca-Maïto Name - Supplies the input name to check for. The caller must have
55*23b7c7b8SHermès Bélusca-Maïto already upcased the name.
56*23b7c7b8SHermès Bélusca-Maïto
57*23b7c7b8SHermès Bélusca-Maïto Return Value:
58*23b7c7b8SHermès Bélusca-Maïto
59*23b7c7b8SHermès Bélusca-Maïto BOOLEAN - TRUE if Name is an element in the set of strings denoted
60*23b7c7b8SHermès Bélusca-Maïto by the input Expression and FALSE otherwise.
61*23b7c7b8SHermès Bélusca-Maïto
62*23b7c7b8SHermès Bélusca-Maïto --*/
63*23b7c7b8SHermès Bélusca-Maïto
64*23b7c7b8SHermès Bélusca-Maïto {
65*23b7c7b8SHermès Bélusca-Maïto PAGED_CODE();
66*23b7c7b8SHermès Bélusca-Maïto
67*23b7c7b8SHermès Bélusca-Maïto //
68*23b7c7b8SHermès Bélusca-Maïto // Call the appropriate FsRtl routine do to the real work
69*23b7c7b8SHermès Bélusca-Maïto //
70*23b7c7b8SHermès Bélusca-Maïto
71*23b7c7b8SHermès Bélusca-Maïto return FsRtlIsDbcsInExpression( &Expression,
72*23b7c7b8SHermès Bélusca-Maïto &Name );
73*23b7c7b8SHermès Bélusca-Maïto
74*23b7c7b8SHermès Bélusca-Maïto UNREFERENCED_PARAMETER( IrpContext );
75*23b7c7b8SHermès Bélusca-Maïto }
76*23b7c7b8SHermès Bélusca-Maïto
77*23b7c7b8SHermès Bélusca-Maïto
78*23b7c7b8SHermès Bélusca-Maïto VOID
79*23b7c7b8SHermès Bélusca-Maïto FatStringTo8dot3 (
80*23b7c7b8SHermès Bélusca-Maïto _In_ PIRP_CONTEXT IrpContext,
81*23b7c7b8SHermès Bélusca-Maïto _In_ OEM_STRING InputString,
82*23b7c7b8SHermès Bélusca-Maïto _Out_writes_bytes_(11) PFAT8DOT3 Output8dot3
83*23b7c7b8SHermès Bélusca-Maïto )
84*23b7c7b8SHermès Bélusca-Maïto
85*23b7c7b8SHermès Bélusca-Maïto /*++
86*23b7c7b8SHermès Bélusca-Maïto
87*23b7c7b8SHermès Bélusca-Maïto Routine Description:
88*23b7c7b8SHermès Bélusca-Maïto
89*23b7c7b8SHermès Bélusca-Maïto Convert a string into fat 8.3 format. The string must not contain
90*23b7c7b8SHermès Bélusca-Maïto any wildcards.
91*23b7c7b8SHermès Bélusca-Maïto
92*23b7c7b8SHermès Bélusca-Maïto Arguments:
93*23b7c7b8SHermès Bélusca-Maïto
94*23b7c7b8SHermès Bélusca-Maïto InputString - Supplies the input string to convert
95*23b7c7b8SHermès Bélusca-Maïto
96*23b7c7b8SHermès Bélusca-Maïto Output8dot3 - Receives the converted string, the memory must be supplied
97*23b7c7b8SHermès Bélusca-Maïto by the caller.
98*23b7c7b8SHermès Bélusca-Maïto
99*23b7c7b8SHermès Bélusca-Maïto Return Value:
100*23b7c7b8SHermès Bélusca-Maïto
101*23b7c7b8SHermès Bélusca-Maïto None.
102*23b7c7b8SHermès Bélusca-Maïto
103*23b7c7b8SHermès Bélusca-Maïto --*/
104*23b7c7b8SHermès Bélusca-Maïto
105*23b7c7b8SHermès Bélusca-Maïto {
106*23b7c7b8SHermès Bélusca-Maïto ULONG i;
107*23b7c7b8SHermès Bélusca-Maïto ULONG j;
108*23b7c7b8SHermès Bélusca-Maïto
109*23b7c7b8SHermès Bélusca-Maïto PAGED_CODE();
110*23b7c7b8SHermès Bélusca-Maïto
111*23b7c7b8SHermès Bélusca-Maïto DebugTrace(+1, Dbg, "FatStringTo8dot3\n", 0);
112*23b7c7b8SHermès Bélusca-Maïto DebugTrace( 0, Dbg, "InputString = %Z\n", &InputString);
113*23b7c7b8SHermès Bélusca-Maïto
114*23b7c7b8SHermès Bélusca-Maïto NT_ASSERT( InputString.Length <= 12 );
115*23b7c7b8SHermès Bélusca-Maïto
116*23b7c7b8SHermès Bélusca-Maïto //
117*23b7c7b8SHermès Bélusca-Maïto // Make the output name all blanks
118*23b7c7b8SHermès Bélusca-Maïto //
119*23b7c7b8SHermès Bélusca-Maïto
120*23b7c7b8SHermès Bélusca-Maïto RtlFillMemory( Output8dot3, 11, UCHAR_SP );
121*23b7c7b8SHermès Bélusca-Maïto
122*23b7c7b8SHermès Bélusca-Maïto //
123*23b7c7b8SHermès Bélusca-Maïto // Copy over the first part of the file name. Stop when we get to
124*23b7c7b8SHermès Bélusca-Maïto // the end of the input string or a dot.
125*23b7c7b8SHermès Bélusca-Maïto //
126*23b7c7b8SHermès Bélusca-Maïto
127*23b7c7b8SHermès Bélusca-Maïto for (i = 0;
128*23b7c7b8SHermès Bélusca-Maïto (i < (ULONG)InputString.Length) && (InputString.Buffer[i] != '.') && (i < 11);
129*23b7c7b8SHermès Bélusca-Maïto i += 1) {
130*23b7c7b8SHermès Bélusca-Maïto
131*23b7c7b8SHermès Bélusca-Maïto (*Output8dot3)[i] = InputString.Buffer[i];
132*23b7c7b8SHermès Bélusca-Maïto }
133*23b7c7b8SHermès Bélusca-Maïto
134*23b7c7b8SHermès Bélusca-Maïto //
135*23b7c7b8SHermès Bélusca-Maïto // Check if we need to process an extension
136*23b7c7b8SHermès Bélusca-Maïto //
137*23b7c7b8SHermès Bélusca-Maïto
138*23b7c7b8SHermès Bélusca-Maïto if (i < (ULONG)InputString.Length) {
139*23b7c7b8SHermès Bélusca-Maïto
140*23b7c7b8SHermès Bélusca-Maïto //
141*23b7c7b8SHermès Bélusca-Maïto // Make sure we have a dot and then skip over it.
142*23b7c7b8SHermès Bélusca-Maïto //
143*23b7c7b8SHermès Bélusca-Maïto
144*23b7c7b8SHermès Bélusca-Maïto NT_ASSERT( (InputString.Length - i) <= 4 );
145*23b7c7b8SHermès Bélusca-Maïto NT_ASSERT( InputString.Buffer[i] == '.' );
146*23b7c7b8SHermès Bélusca-Maïto
147*23b7c7b8SHermès Bélusca-Maïto i += 1;
148*23b7c7b8SHermès Bélusca-Maïto
149*23b7c7b8SHermès Bélusca-Maïto //
150*23b7c7b8SHermès Bélusca-Maïto // Copy over the extension. Stop when we get to the
151*23b7c7b8SHermès Bélusca-Maïto // end of the input string.
152*23b7c7b8SHermès Bélusca-Maïto //
153*23b7c7b8SHermès Bélusca-Maïto
154*23b7c7b8SHermès Bélusca-Maïto for (j = 8; (i < (ULONG)InputString.Length); j += 1, i += 1) {
155*23b7c7b8SHermès Bélusca-Maïto
156*23b7c7b8SHermès Bélusca-Maïto (*Output8dot3)[j] = InputString.Buffer[i];
157*23b7c7b8SHermès Bélusca-Maïto }
158*23b7c7b8SHermès Bélusca-Maïto }
159*23b7c7b8SHermès Bélusca-Maïto
160*23b7c7b8SHermès Bélusca-Maïto //
161*23b7c7b8SHermès Bélusca-Maïto // Before we return check if we should translate the first character
162*23b7c7b8SHermès Bélusca-Maïto // from 0xe5 to 0x5.
163*23b7c7b8SHermès Bélusca-Maïto //
164*23b7c7b8SHermès Bélusca-Maïto
165*23b7c7b8SHermès Bélusca-Maïto if ((*Output8dot3)[0] == 0xe5) {
166*23b7c7b8SHermès Bélusca-Maïto
167*23b7c7b8SHermès Bélusca-Maïto (*Output8dot3)[0] = FAT_DIRENT_REALLY_0E5;
168*23b7c7b8SHermès Bélusca-Maïto }
169*23b7c7b8SHermès Bélusca-Maïto
170*23b7c7b8SHermès Bélusca-Maïto DebugTrace(-1, Dbg, "FatStringTo8dot3 -> (VOID)\n", 0);
171*23b7c7b8SHermès Bélusca-Maïto
172*23b7c7b8SHermès Bélusca-Maïto UNREFERENCED_PARAMETER( IrpContext );
173*23b7c7b8SHermès Bélusca-Maïto
174*23b7c7b8SHermès Bélusca-Maïto return;
175*23b7c7b8SHermès Bélusca-Maïto }
176*23b7c7b8SHermès Bélusca-Maïto
177*23b7c7b8SHermès Bélusca-Maïto
178*23b7c7b8SHermès Bélusca-Maïto VOID
Fat8dot3ToString(_In_ PIRP_CONTEXT IrpContext,_In_ PDIRENT Dirent,_In_ BOOLEAN RestoreCase,_Out_ POEM_STRING OutputString)179*23b7c7b8SHermès Bélusca-Maïto Fat8dot3ToString (
180*23b7c7b8SHermès Bélusca-Maïto _In_ PIRP_CONTEXT IrpContext,
181*23b7c7b8SHermès Bélusca-Maïto _In_ PDIRENT Dirent,
182*23b7c7b8SHermès Bélusca-Maïto _In_ BOOLEAN RestoreCase,
183*23b7c7b8SHermès Bélusca-Maïto _Out_ POEM_STRING OutputString
184*23b7c7b8SHermès Bélusca-Maïto )
185*23b7c7b8SHermès Bélusca-Maïto
186*23b7c7b8SHermès Bélusca-Maïto /*++
187*23b7c7b8SHermès Bélusca-Maïto
188*23b7c7b8SHermès Bélusca-Maïto Routine Description:
189*23b7c7b8SHermès Bélusca-Maïto
190*23b7c7b8SHermès Bélusca-Maïto Convert fat 8.3 format into a string. The 8.3 name must be well formed.
191*23b7c7b8SHermès Bélusca-Maïto
192*23b7c7b8SHermès Bélusca-Maïto Arguments:
193*23b7c7b8SHermès Bélusca-Maïto
194*23b7c7b8SHermès Bélusca-Maïto Dirent - Supplies the input 8.3 name to convert
195*23b7c7b8SHermès Bélusca-Maïto
196*23b7c7b8SHermès Bélusca-Maïto RestoreCase - If TRUE, then the magic reserved bits are used to restore
197*23b7c7b8SHermès Bélusca-Maïto the original case.
198*23b7c7b8SHermès Bélusca-Maïto
199*23b7c7b8SHermès Bélusca-Maïto OutputString - Receives the converted name, the memory must be supplied
200*23b7c7b8SHermès Bélusca-Maïto by the caller.
201*23b7c7b8SHermès Bélusca-Maïto
202*23b7c7b8SHermès Bélusca-Maïto Return Value:
203*23b7c7b8SHermès Bélusca-Maïto
204*23b7c7b8SHermès Bélusca-Maïto None
205*23b7c7b8SHermès Bélusca-Maïto
206*23b7c7b8SHermès Bélusca-Maïto --*/
207*23b7c7b8SHermès Bélusca-Maïto
208*23b7c7b8SHermès Bélusca-Maïto {
209*23b7c7b8SHermès Bélusca-Maïto ULONG StringIndex;
210*23b7c7b8SHermès Bélusca-Maïto ULONG BaseLength, ExtensionLength;
211*23b7c7b8SHermès Bélusca-Maïto
212*23b7c7b8SHermès Bélusca-Maïto PAGED_CODE();
213*23b7c7b8SHermès Bélusca-Maïto
214*23b7c7b8SHermès Bélusca-Maïto DebugTrace(+1, Dbg, "Fat8dot3ToString\n", 0);
215*23b7c7b8SHermès Bélusca-Maïto
216*23b7c7b8SHermès Bélusca-Maïto //
217*23b7c7b8SHermès Bélusca-Maïto // First, find the length of the base component.
218*23b7c7b8SHermès Bélusca-Maïto //
219*23b7c7b8SHermès Bélusca-Maïto
220*23b7c7b8SHermès Bélusca-Maïto for (BaseLength = 8; BaseLength > 0; BaseLength -= 1) {
221*23b7c7b8SHermès Bélusca-Maïto
222*23b7c7b8SHermès Bélusca-Maïto if (Dirent->FileName[BaseLength - 1] != UCHAR_SP) {
223*23b7c7b8SHermès Bélusca-Maïto
224*23b7c7b8SHermès Bélusca-Maïto break;
225*23b7c7b8SHermès Bélusca-Maïto }
226*23b7c7b8SHermès Bélusca-Maïto }
227*23b7c7b8SHermès Bélusca-Maïto
228*23b7c7b8SHermès Bélusca-Maïto //
229*23b7c7b8SHermès Bélusca-Maïto // Now find the length of the extension.
230*23b7c7b8SHermès Bélusca-Maïto //
231*23b7c7b8SHermès Bélusca-Maïto
232*23b7c7b8SHermès Bélusca-Maïto for (ExtensionLength = 3; ExtensionLength > 0; ExtensionLength -= 1) {
233*23b7c7b8SHermès Bélusca-Maïto
234*23b7c7b8SHermès Bélusca-Maïto if (Dirent->FileName[8 + ExtensionLength - 1] != UCHAR_SP) {
235*23b7c7b8SHermès Bélusca-Maïto
236*23b7c7b8SHermès Bélusca-Maïto break;
237*23b7c7b8SHermès Bélusca-Maïto }
238*23b7c7b8SHermès Bélusca-Maïto }
239*23b7c7b8SHermès Bélusca-Maïto
240*23b7c7b8SHermès Bélusca-Maïto //
241*23b7c7b8SHermès Bélusca-Maïto // If there was a base part, copy it and check the case. Don't forget
242*23b7c7b8SHermès Bélusca-Maïto // if the first character needs to be changed from 0x05 to 0xe5.
243*23b7c7b8SHermès Bélusca-Maïto //
244*23b7c7b8SHermès Bélusca-Maïto
245*23b7c7b8SHermès Bélusca-Maïto if (BaseLength != 0) {
246*23b7c7b8SHermès Bélusca-Maïto
247*23b7c7b8SHermès Bélusca-Maïto RtlCopyMemory( OutputString->Buffer, Dirent->FileName, BaseLength );
248*23b7c7b8SHermès Bélusca-Maïto
249*23b7c7b8SHermès Bélusca-Maïto if (OutputString->Buffer[0] == FAT_DIRENT_REALLY_0E5) {
250*23b7c7b8SHermès Bélusca-Maïto
251*23b7c7b8SHermès Bélusca-Maïto OutputString->Buffer[0] = 0xe5;
252*23b7c7b8SHermès Bélusca-Maïto }
253*23b7c7b8SHermès Bélusca-Maïto
254*23b7c7b8SHermès Bélusca-Maïto //
255*23b7c7b8SHermès Bélusca-Maïto // Now if we are to restore case, look for A-Z
256*23b7c7b8SHermès Bélusca-Maïto //
257*23b7c7b8SHermès Bélusca-Maïto
258*23b7c7b8SHermès Bélusca-Maïto if (FatData.ChicagoMode &&
259*23b7c7b8SHermès Bélusca-Maïto RestoreCase &&
260*23b7c7b8SHermès Bélusca-Maïto FlagOn(Dirent->NtByte, FAT_DIRENT_NT_BYTE_8_LOWER_CASE)) {
261*23b7c7b8SHermès Bélusca-Maïto
262*23b7c7b8SHermès Bélusca-Maïto for (StringIndex = 0; StringIndex < BaseLength; StringIndex += 1) {
263*23b7c7b8SHermès Bélusca-Maïto
264*23b7c7b8SHermès Bélusca-Maïto //
265*23b7c7b8SHermès Bélusca-Maïto // Depending on whether the media was built in a system that was
266*23b7c7b8SHermès Bélusca-Maïto // running with "code page invariance" (see FatEvaluateNameCase),
267*23b7c7b8SHermès Bélusca-Maïto // there could be double-byte OEM characters lying in wait here.
268*23b7c7b8SHermès Bélusca-Maïto // Gotta skip them.
269*23b7c7b8SHermès Bélusca-Maïto //
270*23b7c7b8SHermès Bélusca-Maïto
271*23b7c7b8SHermès Bélusca-Maïto if (FsRtlIsLeadDbcsCharacter(OutputString->Buffer[StringIndex])) {
272*23b7c7b8SHermès Bélusca-Maïto
273*23b7c7b8SHermès Bélusca-Maïto StringIndex += 1;
274*23b7c7b8SHermès Bélusca-Maïto continue;
275*23b7c7b8SHermès Bélusca-Maïto }
276*23b7c7b8SHermès Bélusca-Maïto
277*23b7c7b8SHermès Bélusca-Maïto if ((OutputString->Buffer[StringIndex] >= 'A') &&
278*23b7c7b8SHermès Bélusca-Maïto (OutputString->Buffer[StringIndex] <= 'Z')) {
279*23b7c7b8SHermès Bélusca-Maïto
280*23b7c7b8SHermès Bélusca-Maïto OutputString->Buffer[StringIndex] += 'a' - 'A';
281*23b7c7b8SHermès Bélusca-Maïto }
282*23b7c7b8SHermès Bélusca-Maïto }
283*23b7c7b8SHermès Bélusca-Maïto }
284*23b7c7b8SHermès Bélusca-Maïto }
285*23b7c7b8SHermès Bélusca-Maïto
286*23b7c7b8SHermès Bélusca-Maïto //
287*23b7c7b8SHermès Bélusca-Maïto // If there was an extension, copy that over. Else we now know the
288*23b7c7b8SHermès Bélusca-Maïto // size of the string.
289*23b7c7b8SHermès Bélusca-Maïto //
290*23b7c7b8SHermès Bélusca-Maïto
291*23b7c7b8SHermès Bélusca-Maïto if (ExtensionLength != 0) {
292*23b7c7b8SHermès Bélusca-Maïto
293*23b7c7b8SHermès Bélusca-Maïto PUCHAR o, d;
294*23b7c7b8SHermès Bélusca-Maïto
295*23b7c7b8SHermès Bélusca-Maïto //
296*23b7c7b8SHermès Bélusca-Maïto // Now add the dot
297*23b7c7b8SHermès Bélusca-Maïto //
298*23b7c7b8SHermès Bélusca-Maïto
299*23b7c7b8SHermès Bélusca-Maïto OutputString->Buffer[BaseLength++] = '.';
300*23b7c7b8SHermès Bélusca-Maïto
301*23b7c7b8SHermès Bélusca-Maïto //
302*23b7c7b8SHermès Bélusca-Maïto // Copy over the extension into the output buffer.
303*23b7c7b8SHermès Bélusca-Maïto //
304*23b7c7b8SHermès Bélusca-Maïto
305*23b7c7b8SHermès Bélusca-Maïto o = (PUCHAR)&OutputString->Buffer[BaseLength];
306*23b7c7b8SHermès Bélusca-Maïto d = &Dirent->FileName[8];
307*23b7c7b8SHermès Bélusca-Maïto
308*23b7c7b8SHermès Bélusca-Maïto switch (ExtensionLength) {
309*23b7c7b8SHermès Bélusca-Maïto case 3:
310*23b7c7b8SHermès Bélusca-Maïto *o++ = *d++;
311*23b7c7b8SHermès Bélusca-Maïto case 2:
312*23b7c7b8SHermès Bélusca-Maïto *o++ = *d++;
313*23b7c7b8SHermès Bélusca-Maïto case 1:
314*23b7c7b8SHermès Bélusca-Maïto *o++ = *d++;
315*23b7c7b8SHermès Bélusca-Maïto }
316*23b7c7b8SHermès Bélusca-Maïto
317*23b7c7b8SHermès Bélusca-Maïto //
318*23b7c7b8SHermès Bélusca-Maïto // Set the output string length
319*23b7c7b8SHermès Bélusca-Maïto //
320*23b7c7b8SHermès Bélusca-Maïto
321*23b7c7b8SHermès Bélusca-Maïto OutputString->Length = (USHORT)(BaseLength + ExtensionLength);
322*23b7c7b8SHermès Bélusca-Maïto
323*23b7c7b8SHermès Bélusca-Maïto //
324*23b7c7b8SHermès Bélusca-Maïto // Now if we are to restore case, look for A-Z
325*23b7c7b8SHermès Bélusca-Maïto //
326*23b7c7b8SHermès Bélusca-Maïto
327*23b7c7b8SHermès Bélusca-Maïto if (FatData.ChicagoMode &&
328*23b7c7b8SHermès Bélusca-Maïto RestoreCase &&
329*23b7c7b8SHermès Bélusca-Maïto FlagOn(Dirent->NtByte, FAT_DIRENT_NT_BYTE_3_LOWER_CASE)) {
330*23b7c7b8SHermès Bélusca-Maïto
331*23b7c7b8SHermès Bélusca-Maïto for (StringIndex = BaseLength;
332*23b7c7b8SHermès Bélusca-Maïto StringIndex < OutputString->Length;
333*23b7c7b8SHermès Bélusca-Maïto StringIndex++ ) {
334*23b7c7b8SHermès Bélusca-Maïto
335*23b7c7b8SHermès Bélusca-Maïto //
336*23b7c7b8SHermès Bélusca-Maïto // Depending on whether the media was built in a system that was
337*23b7c7b8SHermès Bélusca-Maïto // running with "code page invariance" (see FatEvaluateNameCase),
338*23b7c7b8SHermès Bélusca-Maïto // there could be double-byte OEM characters lying in wait here.
339*23b7c7b8SHermès Bélusca-Maïto // Gotta skip them.
340*23b7c7b8SHermès Bélusca-Maïto //
341*23b7c7b8SHermès Bélusca-Maïto
342*23b7c7b8SHermès Bélusca-Maïto if (FsRtlIsLeadDbcsCharacter(OutputString->Buffer[StringIndex])) {
343*23b7c7b8SHermès Bélusca-Maïto
344*23b7c7b8SHermès Bélusca-Maïto StringIndex += 1;
345*23b7c7b8SHermès Bélusca-Maïto continue;
346*23b7c7b8SHermès Bélusca-Maïto }
347*23b7c7b8SHermès Bélusca-Maïto
348*23b7c7b8SHermès Bélusca-Maïto if ((OutputString->Buffer[StringIndex] >= 'A') &&
349*23b7c7b8SHermès Bélusca-Maïto (OutputString->Buffer[StringIndex] <= 'Z')) {
350*23b7c7b8SHermès Bélusca-Maïto
351*23b7c7b8SHermès Bélusca-Maïto OutputString->Buffer[StringIndex] += 'a' - 'A';
352*23b7c7b8SHermès Bélusca-Maïto }
353*23b7c7b8SHermès Bélusca-Maïto }
354*23b7c7b8SHermès Bélusca-Maïto }
355*23b7c7b8SHermès Bélusca-Maïto
356*23b7c7b8SHermès Bélusca-Maïto } else {
357*23b7c7b8SHermès Bélusca-Maïto
358*23b7c7b8SHermès Bélusca-Maïto //
359*23b7c7b8SHermès Bélusca-Maïto // Set the output string length
360*23b7c7b8SHermès Bélusca-Maïto //
361*23b7c7b8SHermès Bélusca-Maïto
362*23b7c7b8SHermès Bélusca-Maïto OutputString->Length = (USHORT)BaseLength;
363*23b7c7b8SHermès Bélusca-Maïto }
364*23b7c7b8SHermès Bélusca-Maïto
365*23b7c7b8SHermès Bélusca-Maïto //
366*23b7c7b8SHermès Bélusca-Maïto // And return to our caller
367*23b7c7b8SHermès Bélusca-Maïto //
368*23b7c7b8SHermès Bélusca-Maïto
369*23b7c7b8SHermès Bélusca-Maïto DebugTrace(-1, Dbg, "Fat8dot3ToString, OutputString = \"%Z\" -> VOID\n", OutputString);
370*23b7c7b8SHermès Bélusca-Maïto
371*23b7c7b8SHermès Bélusca-Maïto UNREFERENCED_PARAMETER( IrpContext );
372*23b7c7b8SHermès Bélusca-Maïto
373*23b7c7b8SHermès Bélusca-Maïto return;
374*23b7c7b8SHermès Bélusca-Maïto }
375*23b7c7b8SHermès Bélusca-Maïto
_Requires_lock_held_(_Global_critical_region_)376*23b7c7b8SHermès Bélusca-Maïto _Requires_lock_held_(_Global_critical_region_)
377*23b7c7b8SHermès Bélusca-Maïto VOID
378*23b7c7b8SHermès Bélusca-Maïto FatGetUnicodeNameFromFcb (
379*23b7c7b8SHermès Bélusca-Maïto IN PIRP_CONTEXT IrpContext,
380*23b7c7b8SHermès Bélusca-Maïto IN PFCB Fcb,
381*23b7c7b8SHermès Bélusca-Maïto IN OUT PUNICODE_STRING Lfn
382*23b7c7b8SHermès Bélusca-Maïto )
383*23b7c7b8SHermès Bélusca-Maïto
384*23b7c7b8SHermès Bélusca-Maïto /*++
385*23b7c7b8SHermès Bélusca-Maïto
386*23b7c7b8SHermès Bélusca-Maïto Routine Description:
387*23b7c7b8SHermès Bélusca-Maïto
388*23b7c7b8SHermès Bélusca-Maïto This routine will return the unicode name for a given Fcb. If the
389*23b7c7b8SHermès Bélusca-Maïto file has an LFN, it will return this. Otherwise it will return
390*23b7c7b8SHermès Bélusca-Maïto the UNICODE conversion of the Oem name, properly cased.
391*23b7c7b8SHermès Bélusca-Maïto
392*23b7c7b8SHermès Bélusca-Maïto Arguments:
393*23b7c7b8SHermès Bélusca-Maïto
394*23b7c7b8SHermès Bélusca-Maïto Fcb - Supplies the Fcb to query.
395*23b7c7b8SHermès Bélusca-Maïto
396*23b7c7b8SHermès Bélusca-Maïto Lfn - Supplies a string that already has enough storage for the
397*23b7c7b8SHermès Bélusca-Maïto full unicode name.
398*23b7c7b8SHermès Bélusca-Maïto
399*23b7c7b8SHermès Bélusca-Maïto Return Value:
400*23b7c7b8SHermès Bélusca-Maïto
401*23b7c7b8SHermès Bélusca-Maïto None
402*23b7c7b8SHermès Bélusca-Maïto
403*23b7c7b8SHermès Bélusca-Maïto --*/
404*23b7c7b8SHermès Bélusca-Maïto
405*23b7c7b8SHermès Bélusca-Maïto {
406*23b7c7b8SHermès Bélusca-Maïto PDIRENT Dirent;
407*23b7c7b8SHermès Bélusca-Maïto PBCB DirentBcb = NULL;
408*23b7c7b8SHermès Bélusca-Maïto ULONG DirentByteOffset;
409*23b7c7b8SHermès Bélusca-Maïto
410*23b7c7b8SHermès Bélusca-Maïto CCB LocalCcb;
411*23b7c7b8SHermès Bélusca-Maïto
412*23b7c7b8SHermès Bélusca-Maïto PAGED_CODE();
413*23b7c7b8SHermès Bélusca-Maïto
414*23b7c7b8SHermès Bélusca-Maïto NT_ASSERT((MAX_LFN_CHARACTERS * sizeof( WCHAR)) == Lfn->MaximumLength);
415*23b7c7b8SHermès Bélusca-Maïto
416*23b7c7b8SHermès Bélusca-Maïto //
417*23b7c7b8SHermès Bélusca-Maïto // We'll start by locating the dirent for the name.
418*23b7c7b8SHermès Bélusca-Maïto //
419*23b7c7b8SHermès Bélusca-Maïto
420*23b7c7b8SHermès Bélusca-Maïto FatStringTo8dot3( IrpContext,
421*23b7c7b8SHermès Bélusca-Maïto Fcb->ShortName.Name.Oem,
422*23b7c7b8SHermès Bélusca-Maïto &LocalCcb.OemQueryTemplate.Constant );
423*23b7c7b8SHermès Bélusca-Maïto
424*23b7c7b8SHermès Bélusca-Maïto LocalCcb.Flags = 0;
425*23b7c7b8SHermès Bélusca-Maïto LocalCcb.UnicodeQueryTemplate.Length = 0;
426*23b7c7b8SHermès Bélusca-Maïto LocalCcb.ContainsWildCards = FALSE;
427*23b7c7b8SHermès Bélusca-Maïto
428*23b7c7b8SHermès Bélusca-Maïto FatLocateDirent( IrpContext,
429*23b7c7b8SHermès Bélusca-Maïto Fcb->ParentDcb,
430*23b7c7b8SHermès Bélusca-Maïto &LocalCcb,
431*23b7c7b8SHermès Bélusca-Maïto Fcb->LfnOffsetWithinDirectory,
432*23b7c7b8SHermès Bélusca-Maïto NULL,
433*23b7c7b8SHermès Bélusca-Maïto &Dirent,
434*23b7c7b8SHermès Bélusca-Maïto &DirentBcb,
435*23b7c7b8SHermès Bélusca-Maïto (PVBO)&DirentByteOffset,
436*23b7c7b8SHermès Bélusca-Maïto NULL,
437*23b7c7b8SHermès Bélusca-Maïto Lfn,
438*23b7c7b8SHermès Bélusca-Maïto NULL );
439*23b7c7b8SHermès Bélusca-Maïto _SEH2_TRY {
440*23b7c7b8SHermès Bélusca-Maïto
441*23b7c7b8SHermès Bélusca-Maïto //
442*23b7c7b8SHermès Bélusca-Maïto // If we didn't find the Dirent, something is terribly wrong.
443*23b7c7b8SHermès Bélusca-Maïto //
444*23b7c7b8SHermès Bélusca-Maïto
445*23b7c7b8SHermès Bélusca-Maïto if ((DirentBcb == NULL) ||
446*23b7c7b8SHermès Bélusca-Maïto (DirentByteOffset != Fcb->DirentOffsetWithinDirectory)) {
447*23b7c7b8SHermès Bélusca-Maïto
448*23b7c7b8SHermès Bélusca-Maïto FatRaiseStatus( IrpContext, STATUS_FILE_INVALID );
449*23b7c7b8SHermès Bélusca-Maïto }
450*23b7c7b8SHermès Bélusca-Maïto
451*23b7c7b8SHermès Bélusca-Maïto //
452*23b7c7b8SHermès Bélusca-Maïto // Check for the easy case.
453*23b7c7b8SHermès Bélusca-Maïto //
454*23b7c7b8SHermès Bélusca-Maïto
455*23b7c7b8SHermès Bélusca-Maïto if (Lfn->Length == 0) {
456*23b7c7b8SHermès Bélusca-Maïto
457*23b7c7b8SHermès Bélusca-Maïto NTSTATUS Status;
458*23b7c7b8SHermès Bélusca-Maïto OEM_STRING ShortName;
459*23b7c7b8SHermès Bélusca-Maïto UCHAR ShortNameBuffer[12];
460*23b7c7b8SHermès Bélusca-Maïto
461*23b7c7b8SHermès Bélusca-Maïto //
462*23b7c7b8SHermès Bélusca-Maïto // If we thought that there was an LFN here and didn't find one,
463*23b7c7b8SHermès Bélusca-Maïto // we're as dead. This shouldn't happen in normal operation, but
464*23b7c7b8SHermès Bélusca-Maïto // if someone scrambles a directory by hand ...
465*23b7c7b8SHermès Bélusca-Maïto //
466*23b7c7b8SHermès Bélusca-Maïto
467*23b7c7b8SHermès Bélusca-Maïto NT_ASSERT( Fcb->LfnOffsetWithinDirectory == Fcb->DirentOffsetWithinDirectory );
468*23b7c7b8SHermès Bélusca-Maïto
469*23b7c7b8SHermès Bélusca-Maïto if (Fcb->LfnOffsetWithinDirectory != Fcb->DirentOffsetWithinDirectory) {
470*23b7c7b8SHermès Bélusca-Maïto
471*23b7c7b8SHermès Bélusca-Maïto FatRaiseStatus( IrpContext, STATUS_FILE_INVALID );
472*23b7c7b8SHermès Bélusca-Maïto }
473*23b7c7b8SHermès Bélusca-Maïto
474*23b7c7b8SHermès Bélusca-Maïto //
475*23b7c7b8SHermès Bélusca-Maïto // There is no LFN, so manufacture a UNICODE name.
476*23b7c7b8SHermès Bélusca-Maïto //
477*23b7c7b8SHermès Bélusca-Maïto
478*23b7c7b8SHermès Bélusca-Maïto ShortName.Length = 0;
479*23b7c7b8SHermès Bélusca-Maïto ShortName.MaximumLength = 12;
480*23b7c7b8SHermès Bélusca-Maïto ShortName.Buffer = (PCHAR)ShortNameBuffer;
481*23b7c7b8SHermès Bélusca-Maïto
482*23b7c7b8SHermès Bélusca-Maïto Fat8dot3ToString( IrpContext, Dirent, TRUE, &ShortName );
483*23b7c7b8SHermès Bélusca-Maïto
484*23b7c7b8SHermès Bélusca-Maïto //
485*23b7c7b8SHermès Bélusca-Maïto // OK, now convert this string to UNICODE
486*23b7c7b8SHermès Bélusca-Maïto //
487*23b7c7b8SHermès Bélusca-Maïto
488*23b7c7b8SHermès Bélusca-Maïto #ifdef _MSC_VER
489*23b7c7b8SHermès Bélusca-Maïto #pragma prefast( suppress:28931, "needed for debug build" )
490*23b7c7b8SHermès Bélusca-Maïto #endif
491*23b7c7b8SHermès Bélusca-Maïto Status = RtlOemStringToCountedUnicodeString( Lfn,
492*23b7c7b8SHermès Bélusca-Maïto &ShortName,
493*23b7c7b8SHermès Bélusca-Maïto FALSE );
494*23b7c7b8SHermès Bélusca-Maïto
495*23b7c7b8SHermès Bélusca-Maïto NT_ASSERT( Status == STATUS_SUCCESS );
496*23b7c7b8SHermès Bélusca-Maïto }
497*23b7c7b8SHermès Bélusca-Maïto
498*23b7c7b8SHermès Bélusca-Maïto } _SEH2_FINALLY {
499*23b7c7b8SHermès Bélusca-Maïto
500*23b7c7b8SHermès Bélusca-Maïto FatUnpinBcb( IrpContext, DirentBcb );
501*23b7c7b8SHermès Bélusca-Maïto } _SEH2_END;
502*23b7c7b8SHermès Bélusca-Maïto }
503*23b7c7b8SHermès Bélusca-Maïto
_Requires_lock_held_(_Global_critical_region_)504*23b7c7b8SHermès Bélusca-Maïto _Requires_lock_held_(_Global_critical_region_)
505*23b7c7b8SHermès Bélusca-Maïto VOID
506*23b7c7b8SHermès Bélusca-Maïto FatSetFullFileNameInFcb (
507*23b7c7b8SHermès Bélusca-Maïto IN PIRP_CONTEXT IrpContext,
508*23b7c7b8SHermès Bélusca-Maïto IN PFCB Fcb
509*23b7c7b8SHermès Bélusca-Maïto )
510*23b7c7b8SHermès Bélusca-Maïto
511*23b7c7b8SHermès Bélusca-Maïto /*++
512*23b7c7b8SHermès Bélusca-Maïto
513*23b7c7b8SHermès Bélusca-Maïto Routine Description:
514*23b7c7b8SHermès Bélusca-Maïto
515*23b7c7b8SHermès Bélusca-Maïto If the FullFileName field in the Fcb has not yet been filled in, we
516*23b7c7b8SHermès Bélusca-Maïto proceed to do so.
517*23b7c7b8SHermès Bélusca-Maïto
518*23b7c7b8SHermès Bélusca-Maïto Arguments:
519*23b7c7b8SHermès Bélusca-Maïto
520*23b7c7b8SHermès Bélusca-Maïto Fcb - Supplies the file.
521*23b7c7b8SHermès Bélusca-Maïto
522*23b7c7b8SHermès Bélusca-Maïto Return Value:
523*23b7c7b8SHermès Bélusca-Maïto
524*23b7c7b8SHermès Bélusca-Maïto None
525*23b7c7b8SHermès Bélusca-Maïto
526*23b7c7b8SHermès Bélusca-Maïto --*/
527*23b7c7b8SHermès Bélusca-Maïto
528*23b7c7b8SHermès Bélusca-Maïto {
529*23b7c7b8SHermès Bélusca-Maïto PAGED_CODE();
530*23b7c7b8SHermès Bélusca-Maïto
531*23b7c7b8SHermès Bélusca-Maïto if (Fcb->FullFileName.Buffer == NULL) {
532*23b7c7b8SHermès Bélusca-Maïto
533*23b7c7b8SHermès Bélusca-Maïto UNICODE_STRING Lfn;
534*23b7c7b8SHermès Bélusca-Maïto PFCB TmpFcb = Fcb;
535*23b7c7b8SHermès Bélusca-Maïto PFCB StopFcb;
536*23b7c7b8SHermès Bélusca-Maïto PWCHAR TmpBuffer;
537*23b7c7b8SHermès Bélusca-Maïto ULONG PathLength = 0;
538*23b7c7b8SHermès Bélusca-Maïto
539*23b7c7b8SHermès Bélusca-Maïto //
540*23b7c7b8SHermès Bélusca-Maïto // We will assume we do this infrequently enough, that it's OK to
541*23b7c7b8SHermès Bélusca-Maïto // to a pool allocation here.
542*23b7c7b8SHermès Bélusca-Maïto //
543*23b7c7b8SHermès Bélusca-Maïto
544*23b7c7b8SHermès Bélusca-Maïto Lfn.Length = 0;
545*23b7c7b8SHermès Bélusca-Maïto Lfn.MaximumLength = MAX_LFN_CHARACTERS * sizeof(WCHAR);
546*23b7c7b8SHermès Bélusca-Maïto Lfn.Buffer = FsRtlAllocatePoolWithTag( PagedPool,
547*23b7c7b8SHermès Bélusca-Maïto MAX_LFN_CHARACTERS * sizeof(WCHAR),
548*23b7c7b8SHermès Bélusca-Maïto TAG_FILENAME_BUFFER );
549*23b7c7b8SHermès Bélusca-Maïto
550*23b7c7b8SHermès Bélusca-Maïto _SEH2_TRY {
551*23b7c7b8SHermès Bélusca-Maïto
552*23b7c7b8SHermès Bélusca-Maïto //
553*23b7c7b8SHermès Bélusca-Maïto // First determine how big the name will be. If we find an
554*23b7c7b8SHermès Bélusca-Maïto // ancestor with a FullFileName, our work is easier.
555*23b7c7b8SHermès Bélusca-Maïto //
556*23b7c7b8SHermès Bélusca-Maïto
557*23b7c7b8SHermès Bélusca-Maïto while (TmpFcb != Fcb->Vcb->RootDcb) {
558*23b7c7b8SHermès Bélusca-Maïto
559*23b7c7b8SHermès Bélusca-Maïto if ((TmpFcb != Fcb) && (TmpFcb->FullFileName.Buffer != NULL)) {
560*23b7c7b8SHermès Bélusca-Maïto
561*23b7c7b8SHermès Bélusca-Maïto PathLength += TmpFcb->FullFileName.Length;
562*23b7c7b8SHermès Bélusca-Maïto
563*23b7c7b8SHermès Bélusca-Maïto Fcb->FullFileName.Buffer = FsRtlAllocatePoolWithTag( PagedPool,
564*23b7c7b8SHermès Bélusca-Maïto PathLength,
565*23b7c7b8SHermès Bélusca-Maïto TAG_FILENAME_BUFFER );
566*23b7c7b8SHermès Bélusca-Maïto
567*23b7c7b8SHermès Bélusca-Maïto RtlCopyMemory( Fcb->FullFileName.Buffer,
568*23b7c7b8SHermès Bélusca-Maïto TmpFcb->FullFileName.Buffer,
569*23b7c7b8SHermès Bélusca-Maïto TmpFcb->FullFileName.Length );
570*23b7c7b8SHermès Bélusca-Maïto
571*23b7c7b8SHermès Bélusca-Maïto break;
572*23b7c7b8SHermès Bélusca-Maïto }
573*23b7c7b8SHermès Bélusca-Maïto
574*23b7c7b8SHermès Bélusca-Maïto PathLength += TmpFcb->FinalNameLength + sizeof(WCHAR);
575*23b7c7b8SHermès Bélusca-Maïto
576*23b7c7b8SHermès Bélusca-Maïto TmpFcb = TmpFcb->ParentDcb;
577*23b7c7b8SHermès Bélusca-Maïto }
578*23b7c7b8SHermès Bélusca-Maïto
579*23b7c7b8SHermès Bélusca-Maïto //
580*23b7c7b8SHermès Bélusca-Maïto // If FullFileName.Buffer is still NULL, allocate it.
581*23b7c7b8SHermès Bélusca-Maïto //
582*23b7c7b8SHermès Bélusca-Maïto
583*23b7c7b8SHermès Bélusca-Maïto if (Fcb->FullFileName.Buffer == NULL) {
584*23b7c7b8SHermès Bélusca-Maïto
585*23b7c7b8SHermès Bélusca-Maïto Fcb->FullFileName.Buffer = FsRtlAllocatePoolWithTag( PagedPool,
586*23b7c7b8SHermès Bélusca-Maïto PathLength,
587*23b7c7b8SHermès Bélusca-Maïto TAG_FILENAME_BUFFER );
588*23b7c7b8SHermès Bélusca-Maïto }
589*23b7c7b8SHermès Bélusca-Maïto
590*23b7c7b8SHermès Bélusca-Maïto StopFcb = TmpFcb;
591*23b7c7b8SHermès Bélusca-Maïto
592*23b7c7b8SHermès Bélusca-Maïto TmpFcb = Fcb;
593*23b7c7b8SHermès Bélusca-Maïto TmpBuffer = Fcb->FullFileName.Buffer + PathLength / sizeof(WCHAR);
594*23b7c7b8SHermès Bélusca-Maïto
595*23b7c7b8SHermès Bélusca-Maïto Fcb->FullFileName.Length =
596*23b7c7b8SHermès Bélusca-Maïto Fcb->FullFileName.MaximumLength = (USHORT)PathLength;
597*23b7c7b8SHermès Bélusca-Maïto
598*23b7c7b8SHermès Bélusca-Maïto while (TmpFcb != StopFcb) {
599*23b7c7b8SHermès Bélusca-Maïto
600*23b7c7b8SHermès Bélusca-Maïto FatGetUnicodeNameFromFcb( IrpContext,
601*23b7c7b8SHermès Bélusca-Maïto TmpFcb,
602*23b7c7b8SHermès Bélusca-Maïto &Lfn );
603*23b7c7b8SHermès Bélusca-Maïto
604*23b7c7b8SHermès Bélusca-Maïto TmpBuffer -= Lfn.Length / sizeof(WCHAR);
605*23b7c7b8SHermès Bélusca-Maïto
606*23b7c7b8SHermès Bélusca-Maïto RtlCopyMemory( TmpBuffer, Lfn.Buffer, Lfn.Length );
607*23b7c7b8SHermès Bélusca-Maïto
608*23b7c7b8SHermès Bélusca-Maïto TmpBuffer -= 1;
609*23b7c7b8SHermès Bélusca-Maïto
610*23b7c7b8SHermès Bélusca-Maïto *TmpBuffer = L'\\';
611*23b7c7b8SHermès Bélusca-Maïto
612*23b7c7b8SHermès Bélusca-Maïto TmpFcb = TmpFcb->ParentDcb;
613*23b7c7b8SHermès Bélusca-Maïto }
614*23b7c7b8SHermès Bélusca-Maïto
615*23b7c7b8SHermès Bélusca-Maïto } _SEH2_FINALLY {
616*23b7c7b8SHermès Bélusca-Maïto
617*23b7c7b8SHermès Bélusca-Maïto if (_SEH2_AbnormalTermination()) {
618*23b7c7b8SHermès Bélusca-Maïto
619*23b7c7b8SHermès Bélusca-Maïto if (Fcb->FullFileName.Buffer) {
620*23b7c7b8SHermès Bélusca-Maïto
621*23b7c7b8SHermès Bélusca-Maïto ExFreePool( Fcb->FullFileName.Buffer );
622*23b7c7b8SHermès Bélusca-Maïto Fcb->FullFileName.Buffer = NULL;
623*23b7c7b8SHermès Bélusca-Maïto }
624*23b7c7b8SHermès Bélusca-Maïto }
625*23b7c7b8SHermès Bélusca-Maïto
626*23b7c7b8SHermès Bélusca-Maïto ExFreePool( Lfn.Buffer );
627*23b7c7b8SHermès Bélusca-Maïto } _SEH2_END;
628*23b7c7b8SHermès Bélusca-Maïto }
629*23b7c7b8SHermès Bélusca-Maïto }
630*23b7c7b8SHermès Bélusca-Maïto
631*23b7c7b8SHermès Bélusca-Maïto VOID
FatUnicodeToUpcaseOem(IN PIRP_CONTEXT IrpContext,IN POEM_STRING OemString,IN PUNICODE_STRING UnicodeString)632*23b7c7b8SHermès Bélusca-Maïto FatUnicodeToUpcaseOem (
633*23b7c7b8SHermès Bélusca-Maïto IN PIRP_CONTEXT IrpContext,
634*23b7c7b8SHermès Bélusca-Maïto IN POEM_STRING OemString,
635*23b7c7b8SHermès Bélusca-Maïto IN PUNICODE_STRING UnicodeString
636*23b7c7b8SHermès Bélusca-Maïto )
637*23b7c7b8SHermès Bélusca-Maïto
638*23b7c7b8SHermès Bélusca-Maïto /*++
639*23b7c7b8SHermès Bélusca-Maïto
640*23b7c7b8SHermès Bélusca-Maïto Routine Description:
641*23b7c7b8SHermès Bélusca-Maïto
642*23b7c7b8SHermès Bélusca-Maïto This routine is our standard routine for trying to use stack space
643*23b7c7b8SHermès Bélusca-Maïto if possible when calling RtlUpcaseUnicodeStringToCountedOemString().
644*23b7c7b8SHermès Bélusca-Maïto
645*23b7c7b8SHermès Bélusca-Maïto If an unmappable character is encountered, we set the destination
646*23b7c7b8SHermès Bélusca-Maïto length to 0.
647*23b7c7b8SHermès Bélusca-Maïto
648*23b7c7b8SHermès Bélusca-Maïto Arguments:
649*23b7c7b8SHermès Bélusca-Maïto
650*23b7c7b8SHermès Bélusca-Maïto OemString - Specifies the destination string. Space is already assumed to
651*23b7c7b8SHermès Bélusca-Maïto be allocated. If there is not enough, then we allocate enough
652*23b7c7b8SHermès Bélusca-Maïto space.
653*23b7c7b8SHermès Bélusca-Maïto
654*23b7c7b8SHermès Bélusca-Maïto UnicodeString - Specifies the source string.
655*23b7c7b8SHermès Bélusca-Maïto
656*23b7c7b8SHermès Bélusca-Maïto Return Value:
657*23b7c7b8SHermès Bélusca-Maïto
658*23b7c7b8SHermès Bélusca-Maïto None.
659*23b7c7b8SHermès Bélusca-Maïto
660*23b7c7b8SHermès Bélusca-Maïto --*/
661*23b7c7b8SHermès Bélusca-Maïto
662*23b7c7b8SHermès Bélusca-Maïto {
663*23b7c7b8SHermès Bélusca-Maïto NTSTATUS Status;
664*23b7c7b8SHermès Bélusca-Maïto
665*23b7c7b8SHermès Bélusca-Maïto PAGED_CODE();
666*23b7c7b8SHermès Bélusca-Maïto
667*23b7c7b8SHermès Bélusca-Maïto Status = RtlUpcaseUnicodeStringToCountedOemString( OemString,
668*23b7c7b8SHermès Bélusca-Maïto UnicodeString,
669*23b7c7b8SHermès Bélusca-Maïto FALSE );
670*23b7c7b8SHermès Bélusca-Maïto
671*23b7c7b8SHermès Bélusca-Maïto if (Status == STATUS_BUFFER_OVERFLOW) {
672*23b7c7b8SHermès Bélusca-Maïto
673*23b7c7b8SHermès Bélusca-Maïto OemString->Buffer = NULL;
674*23b7c7b8SHermès Bélusca-Maïto OemString->Length = 0;
675*23b7c7b8SHermès Bélusca-Maïto OemString->MaximumLength = 0;
676*23b7c7b8SHermès Bélusca-Maïto
677*23b7c7b8SHermès Bélusca-Maïto Status = RtlUpcaseUnicodeStringToCountedOemString( OemString,
678*23b7c7b8SHermès Bélusca-Maïto UnicodeString,
679*23b7c7b8SHermès Bélusca-Maïto TRUE );
680*23b7c7b8SHermès Bélusca-Maïto }
681*23b7c7b8SHermès Bélusca-Maïto
682*23b7c7b8SHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) {
683*23b7c7b8SHermès Bélusca-Maïto
684*23b7c7b8SHermès Bélusca-Maïto if (Status == STATUS_UNMAPPABLE_CHARACTER) {
685*23b7c7b8SHermès Bélusca-Maïto
686*23b7c7b8SHermès Bélusca-Maïto OemString->Length = 0;
687*23b7c7b8SHermès Bélusca-Maïto
688*23b7c7b8SHermès Bélusca-Maïto } else {
689*23b7c7b8SHermès Bélusca-Maïto
690*23b7c7b8SHermès Bélusca-Maïto FatNormalizeAndRaiseStatus( IrpContext, Status );
691*23b7c7b8SHermès Bélusca-Maïto }
692*23b7c7b8SHermès Bélusca-Maïto }
693*23b7c7b8SHermès Bélusca-Maïto
694*23b7c7b8SHermès Bélusca-Maïto return;
695*23b7c7b8SHermès Bélusca-Maïto }
696*23b7c7b8SHermès Bélusca-Maïto
697*23b7c7b8SHermès Bélusca-Maïto
_Requires_lock_held_(_Global_critical_region_)698*23b7c7b8SHermès Bélusca-Maïto _Requires_lock_held_(_Global_critical_region_)
699*23b7c7b8SHermès Bélusca-Maïto VOID
700*23b7c7b8SHermès Bélusca-Maïto FatSelectNames (
701*23b7c7b8SHermès Bélusca-Maïto IN PIRP_CONTEXT IrpContext,
702*23b7c7b8SHermès Bélusca-Maïto IN PDCB Parent,
703*23b7c7b8SHermès Bélusca-Maïto IN POEM_STRING OemName,
704*23b7c7b8SHermès Bélusca-Maïto IN PUNICODE_STRING UnicodeName,
705*23b7c7b8SHermès Bélusca-Maïto IN OUT POEM_STRING ShortName,
706*23b7c7b8SHermès Bélusca-Maïto IN PUNICODE_STRING SuggestedShortName OPTIONAL,
707*23b7c7b8SHermès Bélusca-Maïto IN OUT BOOLEAN *AllLowerComponent,
708*23b7c7b8SHermès Bélusca-Maïto IN OUT BOOLEAN *AllLowerExtension,
709*23b7c7b8SHermès Bélusca-Maïto IN OUT BOOLEAN *CreateLfn
710*23b7c7b8SHermès Bélusca-Maïto )
711*23b7c7b8SHermès Bélusca-Maïto
712*23b7c7b8SHermès Bélusca-Maïto /*++
713*23b7c7b8SHermès Bélusca-Maïto
714*23b7c7b8SHermès Bélusca-Maïto Routine Description:
715*23b7c7b8SHermès Bélusca-Maïto
716*23b7c7b8SHermès Bélusca-Maïto This routine takes the original UNICODE string that the user specified,
717*23b7c7b8SHermès Bélusca-Maïto and the upcased Oem equivalent. This routine then decides if the OemName
718*23b7c7b8SHermès Bélusca-Maïto is acceptable for dirent, or whether a short name has to be manufactured.
719*23b7c7b8SHermès Bélusca-Maïto
720*23b7c7b8SHermès Bélusca-Maïto Two values are returned to the caller. One tells the caller if the name
721*23b7c7b8SHermès Bélusca-Maïto happens to be all lower case < 0x80. In this special case we don't
722*23b7c7b8SHermès Bélusca-Maïto have to create an Lfn. Also we tell the caller if it must create an LFN.
723*23b7c7b8SHermès Bélusca-Maïto
724*23b7c7b8SHermès Bélusca-Maïto Arguments:
725*23b7c7b8SHermès Bélusca-Maïto
726*23b7c7b8SHermès Bélusca-Maïto OemName - Supplies the proposed short Oem name.
727*23b7c7b8SHermès Bélusca-Maïto
728*23b7c7b8SHermès Bélusca-Maïto ShortName - If this OemName is OK for storeage in a dirent it is copied to
729*23b7c7b8SHermès Bélusca-Maïto this string, otherwise this string is filled with a name that is OK.
730*23b7c7b8SHermès Bélusca-Maïto If OemName and ShortName are the same string, no copy is done.
731*23b7c7b8SHermès Bélusca-Maïto
732*23b7c7b8SHermès Bélusca-Maïto UnicodeName - Provides the original final name.
733*23b7c7b8SHermès Bélusca-Maïto
734*23b7c7b8SHermès Bélusca-Maïto SuggestedShortName - a first-try short name to try before auto-generation
735*23b7c7b8SHermès Bélusca-Maïto is used
736*23b7c7b8SHermès Bélusca-Maïto
737*23b7c7b8SHermès Bélusca-Maïto AllLowerComponent - Returns whether this component was all lower case.
738*23b7c7b8SHermès Bélusca-Maïto
739*23b7c7b8SHermès Bélusca-Maïto AllLowerExtension - Returns wheather the extension was all lower case.
740*23b7c7b8SHermès Bélusca-Maïto
741*23b7c7b8SHermès Bélusca-Maïto CreateLfn - Tells the caller if we must create an LFN for the UnicodeName or
742*23b7c7b8SHermès Bélusca-Maïto SuggestedLongName
743*23b7c7b8SHermès Bélusca-Maïto
744*23b7c7b8SHermès Bélusca-Maïto Return Value:
745*23b7c7b8SHermès Bélusca-Maïto
746*23b7c7b8SHermès Bélusca-Maïto None.
747*23b7c7b8SHermès Bélusca-Maïto
748*23b7c7b8SHermès Bélusca-Maïto --*/
749*23b7c7b8SHermès Bélusca-Maïto
750*23b7c7b8SHermès Bélusca-Maïto {
751*23b7c7b8SHermès Bélusca-Maïto BOOLEAN GenerateShortName;
752*23b7c7b8SHermès Bélusca-Maïto
753*23b7c7b8SHermès Bélusca-Maïto PAGED_CODE();
754*23b7c7b8SHermès Bélusca-Maïto
755*23b7c7b8SHermès Bélusca-Maïto //
756*23b7c7b8SHermès Bélusca-Maïto // First see if we must generate a short name.
757*23b7c7b8SHermès Bélusca-Maïto //
758*23b7c7b8SHermès Bélusca-Maïto
759*23b7c7b8SHermès Bélusca-Maïto if ((OemName->Length == 0) ||
760*23b7c7b8SHermès Bélusca-Maïto !FatIsNameShortOemValid( IrpContext, *OemName, FALSE, FALSE, FALSE ) ||
761*23b7c7b8SHermès Bélusca-Maïto FatSpaceInName( IrpContext, UnicodeName )) {
762*23b7c7b8SHermès Bélusca-Maïto
763*23b7c7b8SHermès Bélusca-Maïto WCHAR ShortNameBuffer[12];
764*23b7c7b8SHermès Bélusca-Maïto UNICODE_STRING ShortUnicodeName;
765*23b7c7b8SHermès Bélusca-Maïto GENERATE_NAME_CONTEXT Context;
766*23b7c7b8SHermès Bélusca-Maïto BOOLEAN TrySuggestedShortName;
767*23b7c7b8SHermès Bélusca-Maïto
768*23b7c7b8SHermès Bélusca-Maïto PDIRENT Dirent;
769*23b7c7b8SHermès Bélusca-Maïto PBCB Bcb = NULL;
770*23b7c7b8SHermès Bélusca-Maïto ULONG ByteOffset;
771*23b7c7b8SHermès Bélusca-Maïto NTSTATUS Status;
772*23b7c7b8SHermès Bélusca-Maïto
773*23b7c7b8SHermès Bélusca-Maïto GenerateShortName = TRUE;
774*23b7c7b8SHermès Bélusca-Maïto
775*23b7c7b8SHermès Bélusca-Maïto TrySuggestedShortName = (SuggestedShortName != NULL);
776*23b7c7b8SHermès Bélusca-Maïto
777*23b7c7b8SHermès Bélusca-Maïto //
778*23b7c7b8SHermès Bélusca-Maïto // Now generate a short name.
779*23b7c7b8SHermès Bélusca-Maïto //
780*23b7c7b8SHermès Bélusca-Maïto
781*23b7c7b8SHermès Bélusca-Maïto ShortUnicodeName.Length = 0;
782*23b7c7b8SHermès Bélusca-Maïto ShortUnicodeName.MaximumLength = 12 * sizeof(WCHAR);
783*23b7c7b8SHermès Bélusca-Maïto ShortUnicodeName.Buffer = ShortNameBuffer;
784*23b7c7b8SHermès Bélusca-Maïto
785*23b7c7b8SHermès Bélusca-Maïto RtlZeroMemory( &Context, sizeof( GENERATE_NAME_CONTEXT ) );
786*23b7c7b8SHermès Bélusca-Maïto
787*23b7c7b8SHermès Bélusca-Maïto _SEH2_TRY {
788*23b7c7b8SHermès Bélusca-Maïto
789*23b7c7b8SHermès Bélusca-Maïto while ( TRUE ) {
790*23b7c7b8SHermès Bélusca-Maïto
791*23b7c7b8SHermès Bélusca-Maïto FatUnpinBcb( IrpContext, Bcb );
792*23b7c7b8SHermès Bélusca-Maïto
793*23b7c7b8SHermès Bélusca-Maïto if (TrySuggestedShortName) {
794*23b7c7b8SHermès Bélusca-Maïto
795*23b7c7b8SHermès Bélusca-Maïto //
796*23b7c7b8SHermès Bélusca-Maïto // Try our caller's candidate first. Note that this must have
797*23b7c7b8SHermès Bélusca-Maïto // been uppercased previously.
798*23b7c7b8SHermès Bélusca-Maïto //
799*23b7c7b8SHermès Bélusca-Maïto
800*23b7c7b8SHermès Bélusca-Maïto ShortUnicodeName.Length = SuggestedShortName->Length;
801*23b7c7b8SHermès Bélusca-Maïto ShortUnicodeName.MaximumLength = SuggestedShortName->MaximumLength;
802*23b7c7b8SHermès Bélusca-Maïto ShortUnicodeName.Buffer = SuggestedShortName->Buffer;
803*23b7c7b8SHermès Bélusca-Maïto
804*23b7c7b8SHermès Bélusca-Maïto TrySuggestedShortName = FALSE;
805*23b7c7b8SHermès Bélusca-Maïto
806*23b7c7b8SHermès Bélusca-Maïto } else {
807*23b7c7b8SHermès Bélusca-Maïto
808*23b7c7b8SHermès Bélusca-Maïto RtlGenerate8dot3Name( UnicodeName, TRUE, &Context, &ShortUnicodeName );
809*23b7c7b8SHermès Bélusca-Maïto }
810*23b7c7b8SHermès Bélusca-Maïto
811*23b7c7b8SHermès Bélusca-Maïto //
812*23b7c7b8SHermès Bélusca-Maïto // We have a candidate, make sure it doesn't exist.
813*23b7c7b8SHermès Bélusca-Maïto //
814*23b7c7b8SHermès Bélusca-Maïto
815*23b7c7b8SHermès Bélusca-Maïto #ifdef _MSC_VER
816*23b7c7b8SHermès Bélusca-Maïto #pragma prefast( suppress:28931, "needed for debug build" )
817*23b7c7b8SHermès Bélusca-Maïto #endif
818*23b7c7b8SHermès Bélusca-Maïto Status = RtlUnicodeStringToCountedOemString( ShortName,
819*23b7c7b8SHermès Bélusca-Maïto &ShortUnicodeName,
820*23b7c7b8SHermès Bélusca-Maïto FALSE );
821*23b7c7b8SHermès Bélusca-Maïto
822*23b7c7b8SHermès Bélusca-Maïto NT_ASSERT( Status == STATUS_SUCCESS );
823*23b7c7b8SHermès Bélusca-Maïto
824*23b7c7b8SHermès Bélusca-Maïto FatLocateSimpleOemDirent( IrpContext,
825*23b7c7b8SHermès Bélusca-Maïto Parent,
826*23b7c7b8SHermès Bélusca-Maïto ShortName,
827*23b7c7b8SHermès Bélusca-Maïto &Dirent,
828*23b7c7b8SHermès Bélusca-Maïto &Bcb,
829*23b7c7b8SHermès Bélusca-Maïto (PVBO)&ByteOffset );
830*23b7c7b8SHermès Bélusca-Maïto
831*23b7c7b8SHermès Bélusca-Maïto if (Bcb == NULL) {
832*23b7c7b8SHermès Bélusca-Maïto
833*23b7c7b8SHermès Bélusca-Maïto _SEH2_LEAVE;
834*23b7c7b8SHermès Bélusca-Maïto
835*23b7c7b8SHermès Bélusca-Maïto }
836*23b7c7b8SHermès Bélusca-Maïto }
837*23b7c7b8SHermès Bélusca-Maïto
838*23b7c7b8SHermès Bélusca-Maïto } _SEH2_FINALLY {
839*23b7c7b8SHermès Bélusca-Maïto
840*23b7c7b8SHermès Bélusca-Maïto FatUnpinBcb( IrpContext, Bcb );
841*23b7c7b8SHermès Bélusca-Maïto } _SEH2_END;
842*23b7c7b8SHermès Bélusca-Maïto
843*23b7c7b8SHermès Bélusca-Maïto } else {
844*23b7c7b8SHermès Bélusca-Maïto
845*23b7c7b8SHermès Bélusca-Maïto //
846*23b7c7b8SHermès Bélusca-Maïto // Only do this copy if the two string are indeed different.
847*23b7c7b8SHermès Bélusca-Maïto //
848*23b7c7b8SHermès Bélusca-Maïto
849*23b7c7b8SHermès Bélusca-Maïto if (ShortName != OemName) {
850*23b7c7b8SHermès Bélusca-Maïto ShortName->Length = OemName->Length;
851*23b7c7b8SHermès Bélusca-Maïto
852*23b7c7b8SHermès Bélusca-Maïto //
853*23b7c7b8SHermès Bélusca-Maïto // If FsRtlIsFatDbcsLegal() on OemName fails, we will not
854*23b7c7b8SHermès Bélusca-Maïto // be in this code path, so we infer that ShortName's
855*23b7c7b8SHermès Bélusca-Maïto // buffer is big enough to hold the full FAT file name in
856*23b7c7b8SHermès Bélusca-Maïto // OemName.
857*23b7c7b8SHermès Bélusca-Maïto //
858*23b7c7b8SHermès Bélusca-Maïto
859*23b7c7b8SHermès Bélusca-Maïto _Analysis_assume_(ShortName->MaximumLength <= OemName->Length);
860*23b7c7b8SHermès Bélusca-Maïto
861*23b7c7b8SHermès Bélusca-Maïto RtlCopyMemory( ShortName->Buffer, OemName->Buffer, OemName->Length );
862*23b7c7b8SHermès Bélusca-Maïto }
863*23b7c7b8SHermès Bélusca-Maïto
864*23b7c7b8SHermès Bélusca-Maïto GenerateShortName = FALSE;
865*23b7c7b8SHermès Bélusca-Maïto }
866*23b7c7b8SHermès Bélusca-Maïto
867*23b7c7b8SHermès Bélusca-Maïto //
868*23b7c7b8SHermès Bélusca-Maïto // Now see if the caller will have to use unicode string as an LFN
869*23b7c7b8SHermès Bélusca-Maïto //
870*23b7c7b8SHermès Bélusca-Maïto
871*23b7c7b8SHermès Bélusca-Maïto if (GenerateShortName) {
872*23b7c7b8SHermès Bélusca-Maïto
873*23b7c7b8SHermès Bélusca-Maïto *CreateLfn = TRUE;
874*23b7c7b8SHermès Bélusca-Maïto *AllLowerComponent = FALSE;
875*23b7c7b8SHermès Bélusca-Maïto *AllLowerExtension = FALSE;
876*23b7c7b8SHermès Bélusca-Maïto
877*23b7c7b8SHermès Bélusca-Maïto } else {
878*23b7c7b8SHermès Bélusca-Maïto
879*23b7c7b8SHermès Bélusca-Maïto FatEvaluateNameCase( IrpContext,
880*23b7c7b8SHermès Bélusca-Maïto UnicodeName,
881*23b7c7b8SHermès Bélusca-Maïto AllLowerComponent,
882*23b7c7b8SHermès Bélusca-Maïto AllLowerExtension,
883*23b7c7b8SHermès Bélusca-Maïto CreateLfn );
884*23b7c7b8SHermès Bélusca-Maïto }
885*23b7c7b8SHermès Bélusca-Maïto
886*23b7c7b8SHermès Bélusca-Maïto return;
887*23b7c7b8SHermès Bélusca-Maïto }
888*23b7c7b8SHermès Bélusca-Maïto
889*23b7c7b8SHermès Bélusca-Maïto
890*23b7c7b8SHermès Bélusca-Maïto VOID
FatEvaluateNameCase(IN PIRP_CONTEXT IrpContext,IN PUNICODE_STRING UnicodeName,IN OUT BOOLEAN * AllLowerComponent,IN OUT BOOLEAN * AllLowerExtension,IN OUT BOOLEAN * CreateLfn)891*23b7c7b8SHermès Bélusca-Maïto FatEvaluateNameCase (
892*23b7c7b8SHermès Bélusca-Maïto IN PIRP_CONTEXT IrpContext,
893*23b7c7b8SHermès Bélusca-Maïto IN PUNICODE_STRING UnicodeName,
894*23b7c7b8SHermès Bélusca-Maïto IN OUT BOOLEAN *AllLowerComponent,
895*23b7c7b8SHermès Bélusca-Maïto IN OUT BOOLEAN *AllLowerExtension,
896*23b7c7b8SHermès Bélusca-Maïto IN OUT BOOLEAN *CreateLfn
897*23b7c7b8SHermès Bélusca-Maïto )
898*23b7c7b8SHermès Bélusca-Maïto
899*23b7c7b8SHermès Bélusca-Maïto /*++
900*23b7c7b8SHermès Bélusca-Maïto
901*23b7c7b8SHermès Bélusca-Maïto Routine Description:
902*23b7c7b8SHermès Bélusca-Maïto
903*23b7c7b8SHermès Bélusca-Maïto This routine takes a UNICODE string and sees if it is eligible for
904*23b7c7b8SHermès Bélusca-Maïto the special case optimization.
905*23b7c7b8SHermès Bélusca-Maïto
906*23b7c7b8SHermès Bélusca-Maïto Arguments:
907*23b7c7b8SHermès Bélusca-Maïto
908*23b7c7b8SHermès Bélusca-Maïto UnicodeName - Provides the original final name.
909*23b7c7b8SHermès Bélusca-Maïto
910*23b7c7b8SHermès Bélusca-Maïto AllLowerComponent - Returns whether this compoent was all lower case.
911*23b7c7b8SHermès Bélusca-Maïto
912*23b7c7b8SHermès Bélusca-Maïto AllLowerExtension - Returns wheather the extension was all lower case.
913*23b7c7b8SHermès Bélusca-Maïto
914*23b7c7b8SHermès Bélusca-Maïto CreateLfn - Tells the call if we must create an LFN for the UnicodeName.
915*23b7c7b8SHermès Bélusca-Maïto
916*23b7c7b8SHermès Bélusca-Maïto Return Value:
917*23b7c7b8SHermès Bélusca-Maïto
918*23b7c7b8SHermès Bélusca-Maïto None.
919*23b7c7b8SHermès Bélusca-Maïto
920*23b7c7b8SHermès Bélusca-Maïto --*/
921*23b7c7b8SHermès Bélusca-Maïto
922*23b7c7b8SHermès Bélusca-Maïto {
923*23b7c7b8SHermès Bélusca-Maïto ULONG i;
924*23b7c7b8SHermès Bélusca-Maïto UCHAR Uppers = 0;
925*23b7c7b8SHermès Bélusca-Maïto UCHAR Lowers = 0;
926*23b7c7b8SHermès Bélusca-Maïto
927*23b7c7b8SHermès Bélusca-Maïto BOOLEAN ExtensionPresent = FALSE;
928*23b7c7b8SHermès Bélusca-Maïto
929*23b7c7b8SHermès Bélusca-Maïto PAGED_CODE();
930*23b7c7b8SHermès Bélusca-Maïto UNREFERENCED_PARAMETER( IrpContext );
931*23b7c7b8SHermès Bélusca-Maïto
932*23b7c7b8SHermès Bélusca-Maïto *CreateLfn = FALSE;
933*23b7c7b8SHermès Bélusca-Maïto
934*23b7c7b8SHermès Bélusca-Maïto for (i = 0; i < UnicodeName->Length / sizeof(WCHAR); i++) {
935*23b7c7b8SHermès Bélusca-Maïto
936*23b7c7b8SHermès Bélusca-Maïto WCHAR c;
937*23b7c7b8SHermès Bélusca-Maïto
938*23b7c7b8SHermès Bélusca-Maïto c = UnicodeName->Buffer[i];
939*23b7c7b8SHermès Bélusca-Maïto
940*23b7c7b8SHermès Bélusca-Maïto if ((c >= 'A') && (c <= 'Z')) {
941*23b7c7b8SHermès Bélusca-Maïto
942*23b7c7b8SHermès Bélusca-Maïto Uppers += 1;
943*23b7c7b8SHermès Bélusca-Maïto
944*23b7c7b8SHermès Bélusca-Maïto } else if ((c >= 'a') && (c <= 'z')) {
945*23b7c7b8SHermès Bélusca-Maïto
946*23b7c7b8SHermès Bélusca-Maïto Lowers += 1;
947*23b7c7b8SHermès Bélusca-Maïto
948*23b7c7b8SHermès Bélusca-Maïto } else if ((c >= 0x0080) && FatData.CodePageInvariant) {
949*23b7c7b8SHermès Bélusca-Maïto
950*23b7c7b8SHermès Bélusca-Maïto break;
951*23b7c7b8SHermès Bélusca-Maïto }
952*23b7c7b8SHermès Bélusca-Maïto
953*23b7c7b8SHermès Bélusca-Maïto //
954*23b7c7b8SHermès Bélusca-Maïto // If we come to a period, figure out if the extension was
955*23b7c7b8SHermès Bélusca-Maïto // all one case.
956*23b7c7b8SHermès Bélusca-Maïto //
957*23b7c7b8SHermès Bélusca-Maïto
958*23b7c7b8SHermès Bélusca-Maïto if (c == L'.') {
959*23b7c7b8SHermès Bélusca-Maïto
960*23b7c7b8SHermès Bélusca-Maïto *CreateLfn = (Lowers != 0) && (Uppers != 0);
961*23b7c7b8SHermès Bélusca-Maïto
962*23b7c7b8SHermès Bélusca-Maïto *AllLowerComponent = !(*CreateLfn) && (Lowers != 0);
963*23b7c7b8SHermès Bélusca-Maïto
964*23b7c7b8SHermès Bélusca-Maïto ExtensionPresent = TRUE;
965*23b7c7b8SHermès Bélusca-Maïto
966*23b7c7b8SHermès Bélusca-Maïto //
967*23b7c7b8SHermès Bélusca-Maïto // Now reset the uppers and lowers count.
968*23b7c7b8SHermès Bélusca-Maïto //
969*23b7c7b8SHermès Bélusca-Maïto
970*23b7c7b8SHermès Bélusca-Maïto Uppers = Lowers = 0;
971*23b7c7b8SHermès Bélusca-Maïto }
972*23b7c7b8SHermès Bélusca-Maïto }
973*23b7c7b8SHermès Bélusca-Maïto
974*23b7c7b8SHermès Bélusca-Maïto //
975*23b7c7b8SHermès Bélusca-Maïto // Now check again for creating an LFN.
976*23b7c7b8SHermès Bélusca-Maïto //
977*23b7c7b8SHermès Bélusca-Maïto
978*23b7c7b8SHermès Bélusca-Maïto *CreateLfn = (*CreateLfn ||
979*23b7c7b8SHermès Bélusca-Maïto (i != UnicodeName->Length / sizeof(WCHAR)) ||
980*23b7c7b8SHermès Bélusca-Maïto ((Lowers != 0) && (Uppers != 0)));
981*23b7c7b8SHermès Bélusca-Maïto
982*23b7c7b8SHermès Bélusca-Maïto //
983*23b7c7b8SHermès Bélusca-Maïto // Now we know the final state of CreateLfn, update the two
984*23b7c7b8SHermès Bélusca-Maïto // "AllLower" booleans.
985*23b7c7b8SHermès Bélusca-Maïto //
986*23b7c7b8SHermès Bélusca-Maïto
987*23b7c7b8SHermès Bélusca-Maïto if (ExtensionPresent) {
988*23b7c7b8SHermès Bélusca-Maïto
989*23b7c7b8SHermès Bélusca-Maïto *AllLowerComponent = !(*CreateLfn) && *AllLowerComponent;
990*23b7c7b8SHermès Bélusca-Maïto *AllLowerExtension = !(*CreateLfn) && (Lowers != 0);
991*23b7c7b8SHermès Bélusca-Maïto
992*23b7c7b8SHermès Bélusca-Maïto } else {
993*23b7c7b8SHermès Bélusca-Maïto
994*23b7c7b8SHermès Bélusca-Maïto *AllLowerComponent = !(*CreateLfn) && (Lowers != 0);
995*23b7c7b8SHermès Bélusca-Maïto *AllLowerExtension = FALSE;
996*23b7c7b8SHermès Bélusca-Maïto }
997*23b7c7b8SHermès Bélusca-Maïto
998*23b7c7b8SHermès Bélusca-Maïto return;
999*23b7c7b8SHermès Bélusca-Maïto }
1000*23b7c7b8SHermès Bélusca-Maïto
1001*23b7c7b8SHermès Bélusca-Maïto
1002*23b7c7b8SHermès Bélusca-Maïto BOOLEAN
FatSpaceInName(IN PIRP_CONTEXT IrpContext,IN PUNICODE_STRING UnicodeName)1003*23b7c7b8SHermès Bélusca-Maïto FatSpaceInName (
1004*23b7c7b8SHermès Bélusca-Maïto IN PIRP_CONTEXT IrpContext,
1005*23b7c7b8SHermès Bélusca-Maïto IN PUNICODE_STRING UnicodeName
1006*23b7c7b8SHermès Bélusca-Maïto )
1007*23b7c7b8SHermès Bélusca-Maïto
1008*23b7c7b8SHermès Bélusca-Maïto /*++
1009*23b7c7b8SHermès Bélusca-Maïto
1010*23b7c7b8SHermès Bélusca-Maïto Routine Description:
1011*23b7c7b8SHermès Bélusca-Maïto
1012*23b7c7b8SHermès Bélusca-Maïto This routine takes a UNICODE string and sees if it contains any spaces.
1013*23b7c7b8SHermès Bélusca-Maïto
1014*23b7c7b8SHermès Bélusca-Maïto Arguments:
1015*23b7c7b8SHermès Bélusca-Maïto
1016*23b7c7b8SHermès Bélusca-Maïto UnicodeName - Provides the final name.
1017*23b7c7b8SHermès Bélusca-Maïto
1018*23b7c7b8SHermès Bélusca-Maïto Return Value:
1019*23b7c7b8SHermès Bélusca-Maïto
1020*23b7c7b8SHermès Bélusca-Maïto BOOLEAN - TRUE if it does, FALSE if it doesn't.
1021*23b7c7b8SHermès Bélusca-Maïto
1022*23b7c7b8SHermès Bélusca-Maïto --*/
1023*23b7c7b8SHermès Bélusca-Maïto
1024*23b7c7b8SHermès Bélusca-Maïto {
1025*23b7c7b8SHermès Bélusca-Maïto ULONG i;
1026*23b7c7b8SHermès Bélusca-Maïto
1027*23b7c7b8SHermès Bélusca-Maïto PAGED_CODE();
1028*23b7c7b8SHermès Bélusca-Maïto UNREFERENCED_PARAMETER( IrpContext );
1029*23b7c7b8SHermès Bélusca-Maïto
1030*23b7c7b8SHermès Bélusca-Maïto for (i=0; i < UnicodeName->Length/sizeof(WCHAR); i++) {
1031*23b7c7b8SHermès Bélusca-Maïto
1032*23b7c7b8SHermès Bélusca-Maïto if (UnicodeName->Buffer[i] == L' ') {
1033*23b7c7b8SHermès Bélusca-Maïto return TRUE;
1034*23b7c7b8SHermès Bélusca-Maïto }
1035*23b7c7b8SHermès Bélusca-Maïto }
1036*23b7c7b8SHermès Bélusca-Maïto
1037*23b7c7b8SHermès Bélusca-Maïto return FALSE;
1038*23b7c7b8SHermès Bélusca-Maïto }
1039*23b7c7b8SHermès Bélusca-Maïto
1040*23b7c7b8SHermès Bélusca-Maïto VOID
FatUnicodeRestoreShortNameCase(IN PUNICODE_STRING ShortNameWithCase,IN BOOLEAN LowerCase8,IN BOOLEAN LowerCase3)1041*23b7c7b8SHermès Bélusca-Maïto FatUnicodeRestoreShortNameCase(
1042*23b7c7b8SHermès Bélusca-Maïto IN PUNICODE_STRING ShortNameWithCase,
1043*23b7c7b8SHermès Bélusca-Maïto IN BOOLEAN LowerCase8,
1044*23b7c7b8SHermès Bélusca-Maïto IN BOOLEAN LowerCase3
1045*23b7c7b8SHermès Bélusca-Maïto )
1046*23b7c7b8SHermès Bélusca-Maïto
1047*23b7c7b8SHermès Bélusca-Maïto /*++
1048*23b7c7b8SHermès Bélusca-Maïto
1049*23b7c7b8SHermès Bélusca-Maïto Routine Description:
1050*23b7c7b8SHermès Bélusca-Maïto
1051*23b7c7b8SHermès Bélusca-Maïto Given an 8.3 filename in a UNICODE_STRING, fix the case of the
1052*23b7c7b8SHermès Bélusca-Maïto name given the two 8do3 case flags.
1053*23b7c7b8SHermès Bélusca-Maïto
1054*23b7c7b8SHermès Bélusca-Maïto Arguments:
1055*23b7c7b8SHermès Bélusca-Maïto
1056*23b7c7b8SHermès Bélusca-Maïto ShortNameWithCase - the UNICODE_STRING containing the short name.
1057*23b7c7b8SHermès Bélusca-Maïto LowerCase8, LowerCase3 - the flag indicating whether to downcase the 8dot3 name component.
1058*23b7c7b8SHermès Bélusca-Maïto
1059*23b7c7b8SHermès Bélusca-Maïto Return Value:
1060*23b7c7b8SHermès Bélusca-Maïto
1061*23b7c7b8SHermès Bélusca-Maïto None.
1062*23b7c7b8SHermès Bélusca-Maïto
1063*23b7c7b8SHermès Bélusca-Maïto --*/
1064*23b7c7b8SHermès Bélusca-Maïto {
1065*23b7c7b8SHermès Bélusca-Maïto USHORT i;
1066*23b7c7b8SHermès Bélusca-Maïto UNICODE_STRING DownCaseSeg;
1067*23b7c7b8SHermès Bélusca-Maïto
1068*23b7c7b8SHermès Bélusca-Maïto PAGED_CODE();
1069*23b7c7b8SHermès Bélusca-Maïto
1070*23b7c7b8SHermès Bélusca-Maïto NT_ASSERT( ShortNameWithCase->Length <= 24 );
1071*23b7c7b8SHermès Bélusca-Maïto
1072*23b7c7b8SHermès Bélusca-Maïto //
1073*23b7c7b8SHermès Bélusca-Maïto // Have to repair the case of the short name
1074*23b7c7b8SHermès Bélusca-Maïto //
1075*23b7c7b8SHermès Bélusca-Maïto
1076*23b7c7b8SHermès Bélusca-Maïto for (i = 0; i < (ShortNameWithCase->Length/sizeof(WCHAR)) &&
1077*23b7c7b8SHermès Bélusca-Maïto ShortNameWithCase->Buffer[i] != L'.'; i++);
1078*23b7c7b8SHermès Bélusca-Maïto
1079*23b7c7b8SHermès Bélusca-Maïto //
1080*23b7c7b8SHermès Bélusca-Maïto // Now pointing at the '.', or otherwise the end of name component
1081*23b7c7b8SHermès Bélusca-Maïto //
1082*23b7c7b8SHermès Bélusca-Maïto
1083*23b7c7b8SHermès Bélusca-Maïto if (LowerCase8) {
1084*23b7c7b8SHermès Bélusca-Maïto
1085*23b7c7b8SHermès Bélusca-Maïto DownCaseSeg.Buffer = ShortNameWithCase->Buffer;
1086*23b7c7b8SHermès Bélusca-Maïto DownCaseSeg.MaximumLength = DownCaseSeg.Length = i*sizeof(WCHAR);
1087*23b7c7b8SHermès Bélusca-Maïto
1088*23b7c7b8SHermès Bélusca-Maïto RtlDowncaseUnicodeString(&DownCaseSeg, &DownCaseSeg, FALSE);
1089*23b7c7b8SHermès Bélusca-Maïto }
1090*23b7c7b8SHermès Bélusca-Maïto
1091*23b7c7b8SHermès Bélusca-Maïto i++;
1092*23b7c7b8SHermès Bélusca-Maïto
1093*23b7c7b8SHermès Bélusca-Maïto //
1094*23b7c7b8SHermès Bélusca-Maïto // Now pointing at first wchar of the extension.
1095*23b7c7b8SHermès Bélusca-Maïto //
1096*23b7c7b8SHermès Bélusca-Maïto
1097*23b7c7b8SHermès Bélusca-Maïto if (LowerCase3) {
1098*23b7c7b8SHermès Bélusca-Maïto
1099*23b7c7b8SHermès Bélusca-Maïto //
1100*23b7c7b8SHermès Bélusca-Maïto // It is not neccesarily the case that we can rely on the flag
1101*23b7c7b8SHermès Bélusca-Maïto // indicating that we really have an extension.
1102*23b7c7b8SHermès Bélusca-Maïto //
1103*23b7c7b8SHermès Bélusca-Maïto
1104*23b7c7b8SHermès Bélusca-Maïto if ((i*sizeof(WCHAR)) < ShortNameWithCase->Length) {
1105*23b7c7b8SHermès Bélusca-Maïto DownCaseSeg.Buffer = &ShortNameWithCase->Buffer[i];
1106*23b7c7b8SHermès Bélusca-Maïto DownCaseSeg.MaximumLength = DownCaseSeg.Length = ShortNameWithCase->Length - i*sizeof(WCHAR);
1107*23b7c7b8SHermès Bélusca-Maïto
1108*23b7c7b8SHermès Bélusca-Maïto RtlDowncaseUnicodeString(&DownCaseSeg, &DownCaseSeg, FALSE);
1109*23b7c7b8SHermès Bélusca-Maïto }
1110*23b7c7b8SHermès Bélusca-Maïto }
1111*23b7c7b8SHermès Bélusca-Maïto
1112*23b7c7b8SHermès Bélusca-Maïto }
1113*23b7c7b8SHermès Bélusca-Maïto
1114*23b7c7b8SHermès Bélusca-Maïto
1115