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