ReactOS  0.4.13-dev-1149-g95dd1c6
namesup.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  NameSup.c
8 
9 Abstract:
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 
34 BOOLEAN
36  IN PIRP_CONTEXT IrpContext,
39  )
40 
41 /*++
42 
43 Routine 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 
49 Arguments:
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 
57 Return 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 
78 VOID
80  _In_ PIRP_CONTEXT IrpContext,
81  _In_ OEM_STRING InputString,
82  _Out_writes_bytes_(11) PFAT8DOT3 Output8dot3
83  )
84 
85 /*++
86 
87 Routine Description:
88 
89  Convert a string into fat 8.3 format. The string must not contain
90  any wildcards.
91 
92 Arguments:
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 
99 Return 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 
178 VOID
180  _In_ PIRP_CONTEXT IrpContext,
182  _In_ BOOLEAN RestoreCase,
183  _Out_ POEM_STRING OutputString
184  )
185 
186 /*++
187 
188 Routine Description:
189 
190  Convert fat 8.3 format into a string. The 8.3 name must be well formed.
191 
192 Arguments:
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 
202 Return Value:
203 
204  None
205 
206 --*/
207 
208 {
209  ULONG StringIndex;
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_)
377 VOID
378 FatGetUnicodeNameFromFcb (
379  IN PIRP_CONTEXT IrpContext,
380  IN PFCB Fcb,
382  )
383 
384 /*++
385 
386 Routine 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 
392 Arguments:
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 
399 Return Value:
400 
401  None
402 
403 --*/
404 
405 {
406  PDIRENT Dirent;
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_)
505 VOID
506 FatSetFullFileNameInFcb (
507  IN PIRP_CONTEXT IrpContext,
508  IN PFCB Fcb
509  )
510 
511 /*++
512 
513 Routine Description:
514 
515  If the FullFileName field in the Fcb has not yet been filled in, we
516  proceed to do so.
517 
518 Arguments:
519 
520  Fcb - Supplies the file.
521 
522 Return 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 
564  PathLength,
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 
586  PathLength,
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 
626  ExFreePool( Lfn.Buffer );
627  } _SEH2_END;
628  }
629 }
630 
631 VOID
633  IN PIRP_CONTEXT IrpContext,
636  )
637 
638 /*++
639 
640 Routine 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 
648 Arguments:
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 
656 Return 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_)
699 VOID
700 FatSelectNames (
701  IN PIRP_CONTEXT IrpContext,
702  IN PDCB Parent,
706  IN PUNICODE_STRING SuggestedShortName OPTIONAL,
710  )
711 
712 /*++
713 
714 Routine 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 
724 Arguments:
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 
744 Return 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 
768  PDIRENT Dirent;
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
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 
833  _SEH2_LEAVE;
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,
880  UnicodeName,
883  CreateLfn );
884  }
885 
886  return;
887 }
888 
889 
890 VOID
892  IN PIRP_CONTEXT IrpContext,
897  )
898 
899 /*++
900 
901 Routine Description:
902 
903  This routine takes a UNICODE string and sees if it is eligible for
904  the special case optimization.
905 
906 Arguments:
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 
916 Return 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 
1002 BOOLEAN
1004  IN PIRP_CONTEXT IrpContext,
1006  )
1007 
1008 /*++
1009 
1010 Routine Description:
1011 
1012  This routine takes a UNICODE string and sees if it contains any spaces.
1013 
1014 Arguments:
1015 
1016  UnicodeName - Provides the final name.
1017 
1018 Return 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 
1040 VOID
1042  IN PUNICODE_STRING ShortNameWithCase,
1043  IN BOOLEAN LowerCase8,
1044  IN BOOLEAN LowerCase3
1045  )
1046 
1047 /*++
1048 
1049 Routine 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 
1054 Arguments:
1055 
1056  ShortNameWithCase - the UNICODE_STRING containing the short name.
1057  LowerCase8, LowerCase3 - the flag indicating whether to downcase the 8dot3 name component.
1058 
1059 Return 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 
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:1294
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1294
*BytesInOemString PCHAR OemString
Definition: rtlfuncs.h:1561
#define IN
Definition: typedefs.h:38
PCWSTR Expression
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2983
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:402
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING IN PUNICODE_STRING SuggestedShortName IN OUT BOOLEAN * AllLowerComponent
Definition: fatprocs.h:1294
USHORT MaximumLength
Definition: env_spec_w32.h:370
_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:4157
Definition: cdstruc.h:908
BOOLEAN FatSpaceInName(IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING UnicodeName)
Definition: namesup.c:1003
Definition: cdstruc.h:1073
unsigned char * PUCHAR
Definition: retypes.h:3
BOOLEAN FatIsNameInExpression(IN PIRP_CONTEXT IrpContext, IN OEM_STRING Expression, IN OEM_STRING Name)
Definition: namesup.c:35
#define FAT_DIRENT_REALLY_0E5
Definition: fat.h:335
BOOLEAN ContainsWildCards
Definition: fatstruc.h:1374
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1294
UNICODE_STRING UnicodeQueryTemplate
Definition: fatstruc.h:1425
VOID FatUnicodeToUpcaseOem(IN PIRP_CONTEXT IrpContext, IN POEM_STRING OemString, IN PUNICODE_STRING UnicodeString)
Definition: namesup.c:632
NTSTATUS NTAPI RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING UniDest, IN PCOEM_STRING OemSource, IN BOOLEAN AllocateDestinationString)
Definition: unicode.c:1463
BOOLEAN ChicagoMode
Definition: fatstruc.h:86
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:722
uint16_t * PWCHAR
Definition: typedefs.h:54
#define STATUS_FILE_INVALID
Definition: ntstatus.h:374
union _FILE_NAME_NODE::@691 Name
STRING OEM_STRING
Definition: umtypes.h:203
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2965
static USHORT PathLength
struct _FCB * ParentDcb
Definition: fatstruc.h:835
_SEH2_TRY
Definition: create.c:4250
#define FAT_DIRENT_NT_BYTE_8_LOWER_CASE
Definition: fat.h:361
BOOLEAN CodePageInvariant
Definition: fatstruc.h:114
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
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:537
_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:4157
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define _Out_writes_bytes_(size)
Definition: no_sal2.h:370
#define _Out_
Definition: no_sal2.h:323
ULONG Flags
Definition: cdstruc.h:1086
BOOLEAN NTAPI FsRtlIsDbcsInExpression(IN PANSI_STRING Expression, IN PANSI_STRING Name)
Definition: dbcsname.c:160
switch(r->id)
Definition: btrfs.c:2932
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
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
OEM_STRING Oem
Definition: fatstruc.h:692
#define PCHAR
Definition: match.c:90
#define FatIsNameShortOemValid(IRPCONTEXT, NAME, CAN_CONTAIN_WILD_CARDS, PATH_NAME_OK, LEADING_BACKSLASH_OK)
Definition: fatprocs.h:1189
FAT_DATA FatData
Definition: fatdata.c:56
#define d
Definition: ke_i.h:81
#define UCHAR_SP
Definition: nodetype.h:143
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _FCB * RootDcb
Definition: fatstruc.h:284
VBO LfnOffsetWithinDirectory
Definition: fatstruc.h:912
#define MAX_LFN_CHARACTERS
Definition: lfn.h:50
const GLubyte * c
Definition: glext.h:8905
PAGED_CODE()
FAT8DOT3 * PFAT8DOT3
Definition: fat.h:296
#define TAG_FILENAME_BUFFER
Definition: nodetype.h:167
UNICODE_STRING FullFileName
Definition: fatstruc.h:1121
_Requires_lock_held_(_Global_critical_region_)
Definition: namesup.c:376
VOID FatUnicodeRestoreShortNameCase(IN PUNICODE_STRING ShortNameWithCase, IN BOOLEAN LowerCase8, IN BOOLEAN LowerCase3)
Definition: namesup.c:1041
unsigned char UCHAR
Definition: xmlstorage.h:181
VBO * PVBO
Definition: fat.h:39
static const WCHAR L[]
Definition: oid.c:1250
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
union _CCB::@696::@698::@700 OemQueryTemplate
#define FAT_DIRENT_NT_BYTE_3_LOWER_CASE
Definition: fat.h:362
_SEH2_END
Definition: create.c:4424
VBO DirentOffsetWithinDirectory
Definition: fatstruc.h:905
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
#define STATUS_UNMAPPABLE_CHARACTER
Definition: ntstatus.h:576
unsigned short USHORT
Definition: pedump.c:61
VOID FatStringTo8dot3(_In_ PIRP_CONTEXT IrpContext, _In_ OEM_STRING InputString, _Out_writes_bytes_(11) PFAT8DOT3 Output8dot3)
Definition: namesup.c:79
NTSYSAPI VOID NTAPI RtlGenerate8dot3Name(_In_ PCUNICODE_STRING Name, _In_ BOOLEAN AllowExtendedCharacters, _Inout_ PGENERATE_NAME_CONTEXT Context, _Inout_ PUNICODE_STRING Name8dot3)
_SEH2_FINALLY
Definition: create.c:4395
NTSTATUS NTAPI RtlUnicodeStringToCountedOemString(IN OUT POEM_STRING OemDest, IN PCUNICODE_STRING UniSource, IN BOOLEAN AllocateDestinationString)
Definition: unicode.c:1780
#define Dbg
Definition: namesup.c:18
#define OUT
Definition: typedefs.h:39
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:1294
#define c
Definition: ke_i.h:80
struct tagContext Context
Definition: acpixf.h:1024
unsigned int ULONG
Definition: retypes.h:1
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:429
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PVCB Vcb
Definition: cdstruc.h:939
NTSYSAPI NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN)
#define _SEH2_LEAVE
Definition: filesup.c:20
NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING *, const UNICODE_STRING *, BOOLEAN)
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1294
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
USHORT FinalNameLength
Definition: fatstruc.h:1123
#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR)
Definition: init.c:417
UNREFERENCED_PARAMETER(IrpContext)
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1114
VOID Fat8dot3ToString(_In_ PIRP_CONTEXT IrpContext, _In_ PDIRENT Dirent, _In_ BOOLEAN RestoreCase, _Out_ POEM_STRING OutputString)
Definition: namesup.c:179
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716
#define _Analysis_assume_(expr)
Definition: no_sal2.h:10
#define NT_ASSERT
Definition: rtlfuncs.h:3312
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68