Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

gen8dot3.c File Reference

#include "ntrtlp.h"
#include <stdio.h>

Go to the source code of this file.

Defines

#define IsDbcsCharacter(WC)

Functions

WCHAR GetNextWchar (IN PUNICODE_STRING Name, IN PULONG CurrentIndex, IN BOOLEAN SkipDots, IN BOOLEAN AllowExtendedCharacters)
USHORT RtlComputeLfnChecksum (PUNICODE_STRING Name)
VOID RtlGenerate8dot3Name (IN PUNICODE_STRING Name, IN BOOLEAN AllowExtendedCharacters, IN OUT PGENERATE_NAME_CONTEXT Context, OUT PUNICODE_STRING Name8dot3)
BOOLEAN RtlIsValidOemCharacter (IN PWCHAR Char)
BOOLEAN RtlIsNameLegalDOS8Dot3 (IN PUNICODE_STRING Name, IN OUT POEM_STRING OemName OPTIONAL, OUT PBOOLEAN NameContainsSpaces OPTIONAL)

Variables

PUSHORT NlsUnicodeToMbOemData
PUSHORT NlsOemToUnicodeData
PCH NlsUnicodeToOemData
PUSHORT NlsMbOemCodePageTables
BOOLEAN NlsMbOemCodePageTag
PUSHORT NlsOemLeadByteInfo
USHORT OemDefaultChar
const ULONG RtlFatIllegalTable []


Define Documentation

#define IsDbcsCharacter WC   ) 
 

Value:

( \ ((WC) > 127) && \ (HIBYTE(NlsUnicodeToMbOemData[(WC)])) \ )

Definition at line 66 of file gen8dot3.c.

Referenced by RtlGenerate8dot3Name().


Function Documentation

WCHAR GetNextWchar IN PUNICODE_STRING  Name,
IN PULONG  CurrentIndex,
IN BOOLEAN  SkipDots,
IN BOOLEAN  AllowExtendedCharacters
 

Definition at line 555 of file gen8dot3.c.

References L, Name, RtlFatIllegalTable, and RtlIsValidOemCharacter().

Referenced by RtlGenerate8dot3Name().

00564 : 00565 00566 This routine scans the input name starting at the current index and 00567 returns the next valid character for the long name to 8.3 generation 00568 algorithm. It also updates the current index to point to the 00569 next character to examine. 00570 00571 The user can specify if dots are skipped over or passed back. The 00572 filtering done by the procedure is: 00573 00574 1. Skip characters less then blanks, and larger than 127 if 00575 AllowExtendedCharacters is FALSE 00576 2. Optionally skip over dots 00577 3. translate the special 7 characters : + , ; = [ ] into underscores 00578 00579 Arguments: 00580 00581 Name - Supplies the name being examined 00582 00583 CurrentIndex - Supplies the index to start our examination and also 00584 receives the index of one beyond the character we return. 00585 00586 SkipDots - Indicates whether this routine will also skip over periods 00587 00588 AllowExtendedCharacters - Tell whether charaacters >= 127 are valid. 00589 00590 Return Value: 00591 00592 WCHAR - returns the next wchar in the name string 00593 00594 --*/ 00595 00596 { 00597 WCHAR wc; 00598 00599 // 00600 // Until we find out otherwise the character we are going to return 00601 // is 0 00602 // 00603 00604 wc = 0; 00605 00606 // 00607 // Now loop through updating the current index until we either have a character to 00608 // return or until we exhaust the name buffer 00609 // 00610 00611 while (*CurrentIndex < (ULONG)(Name->Length/2)) { 00612 00613 // 00614 // Get the next character in the buffer 00615 // 00616 00617 wc = Name->Buffer[*CurrentIndex]; 00618 *CurrentIndex += 1; 00619 00620 // 00621 // If the character is to be skipped over then reset wc to 0 00622 // 00623 00624 if ((wc <= L' ') || 00625 ((wc >= 127) && (!AllowExtendedCharacters || !RtlIsValidOemCharacter(&wc))) || 00626 ((wc == L'.') && SkipDots)) { 00627 00628 wc = 0; 00629 00630 } else { 00631 00632 // 00633 // We have a character to return, but first translate the character is necessary 00634 // 00635 00636 if ((wc < 0x80) && (RtlFatIllegalTable[wc/32] & (1 << (wc%32)))) { 00637 00638 wc = L'_'; 00639 } 00640 00641 // 00642 // Do an a-z upcase. 00643 // 00644 00645 if ((wc >= L'a') && (wc <= L'z')) { 00646 00647 wc -= L'a' - L'A'; 00648 } 00649 00650 // 00651 // And break out of the loop to return to our caller 00652 // 00653 00654 break; 00655 } 00656 } 00657 00658 //DebugTrace( 0, Dbg, "GetNextWchar -> %08x\n", wc); 00659 00660 return wc; 00661 }

USHORT RtlComputeLfnChecksum PUNICODE_STRING  Name  ) 
 

Definition at line 669 of file gen8dot3.c.

References Name, RTL_PAGED_CODE, and USHORT.

Referenced by RtlGenerate8dot3Name().

00675 : 00676 00677 This routine computes the Chicago long file name checksum. 00678 00679 Arguments: 00680 00681 Name - Supplies the name to compute the checksum on. Note that one 00682 character names don't have interesting checksums. 00683 00684 Return Value: 00685 00686 The checksum. 00687 00688 --*/ 00689 00690 { 00691 ULONG i; 00692 USHORT Checksum; 00693 00694 RTL_PAGED_CODE(); 00695 00696 if (Name->Length == sizeof(WCHAR)) { 00697 00698 return Name->Buffer[0]; 00699 } 00700 00701 Checksum = ((Name->Buffer[0] << 8) + Name->Buffer[1]) & 0xffff; 00702 00703 // 00704 // This checksum is kinda strange because we want to still have 00705 // a good range even if all the characters are < 0x00ff. 00706 // 00707 00708 for (i=2; i < Name->Length / sizeof(WCHAR); i+=2) { 00709 00710 Checksum = (Checksum & 1 ? 0x8000 : 0) + 00711 (Checksum >> 1) + 00712 (Name->Buffer[i] << 8); 00713 00714 // 00715 // Be carefull to not walk off the end of the string. 00716 // 00717 00718 if (i+1 < Name->Length / sizeof(WCHAR)) { 00719 00720 Checksum += Name->Buffer[i+1] & 0xffff; 00721 } 00722 } 00723 00724 return Checksum; 00725 }

VOID RtlGenerate8dot3Name IN PUNICODE_STRING  Name,
IN BOOLEAN  AllowExtendedCharacters,
IN OUT PGENERATE_NAME_CONTEXT  Context,
OUT PUNICODE_STRING  Name8dot3
 

Definition at line 81 of file gen8dot3.c.

References FALSE, FsRtlSafeExtensions, GetNextWchar(), IsDbcsCharacter, L, Name, NlsMbOemCodePageTag, RtlComputeLfnChecksum(), TRUE, and USHORT.

00090 : 00091 00092 This routine is used to generate an 8.3 name from a long name. It can 00093 be called repeatedly to generate different 8.3 name variations for the 00094 same long name. This is necessary if the gernerated 8.3 name conflicts 00095 with an existing 8.3 name. 00096 00097 Arguments: 00098 00099 Name - Supplies the original long name that is being translated from. 00100 00101 AllowExtendedCharacters - If TRUE, then extended characters, including 00102 DBCS characters, are allowed in the basis of the short name if they 00103 map to an upcased Oem character. 00104 00105 Context - Supplies a context for the translation. This is a private structure 00106 needed by this routine to help enumerate the different long name 00107 possibilities. The caller is responsible with providing a "zeroed out" 00108 context structure on the first call for each given input name. 00109 00110 Name8dot3 - Receives the new 8.3 name. Pool for the buffer must be allocated 00111 by the caller and should be 12 characters wide (i.e., 24 bytes). 00112 00113 Return Value: 00114 00115 None. 00116 00117 --*/ 00118 00119 { 00120 BOOLEAN DbcsAware; 00121 BOOLEAN IndexAll9s = TRUE; 00122 ULONG OemLength; 00123 ULONG IndexLength; 00124 WCHAR IndexBuffer[8]; 00125 ULONG i; 00126 00127 #ifdef NTOS_KERNEL_RUNTIME 00128 extern BOOLEAN FsRtlSafeExtensions; 00129 #else 00130 BOOLEAN FsRtlSafeExtensions = TRUE; 00131 #endif 00132 00133 DbcsAware = AllowExtendedCharacters && NlsMbOemCodePageTag; 00134 00135 // 00136 // Check if this is the first time we are being called, and if so then 00137 // initialize the context fields. 00138 // 00139 00140 if (Context->NameLength == 0) { 00141 00142 ULONG LastDotIndex; 00143 00144 ULONG CurrentIndex; 00145 BOOLEAN SkipDots; 00146 WCHAR wc; 00147 00148 // 00149 // Skip down the name remembering the index of the last dot we 00150 // will skip over the first dot provided the name starts with 00151 // a dot. 00152 // 00153 00154 LastDotIndex = MAXULONG; 00155 00156 CurrentIndex = 0; 00157 SkipDots = ((Name->Length > 0) && (Name->Buffer[0] == L'.')); 00158 00159 while ((wc = GetNextWchar( Name, 00160 &CurrentIndex, 00161 SkipDots, 00162 AllowExtendedCharacters )) != 0) { 00163 00164 SkipDots = FALSE; 00165 if (wc == L'.') { LastDotIndex = CurrentIndex; } 00166 } 00167 00168 // 00169 // If the LastDotIndex is the last character in the name, 00170 // then there really isn't an extension, so reset LastDotIndex. 00171 // 00172 00173 if (LastDotIndex == Name->Length/sizeof(WCHAR)) { 00174 00175 LastDotIndex = MAXULONG; 00176 } 00177 00178 // 00179 // Build up the name part. This can be at most 6 characters 00180 // (because of the ~# appeneded on the end) and we skip over 00181 // dots, except the last dot, which terminates the loop. 00182 // 00183 // We exit the loop if: 00184 // 00185 // - The input Name has been exhausted 00186 // - We have consumed the input name up to the last dot 00187 // - We have filled 6 characters of short name basis 00188 // 00189 00190 CurrentIndex = 0; 00191 OemLength = 0; 00192 Context->NameLength = 0; 00193 00194 while ((wc = GetNextWchar( Name, &CurrentIndex, TRUE, AllowExtendedCharacters)) && 00195 (CurrentIndex < LastDotIndex) && 00196 (Context->NameLength < 6)) { 00197 00198 // 00199 // If we are on a multi-byte code page we have to be careful 00200 // here because the short name (when converted to Oem) must 00201 // be 8.3 compliant. Note that if AllowExtendedCharacters 00202 // is FALSE, then GetNextWchar will never return a DBCS 00203 // character, so we don't care what kind of code page we 00204 // are on. 00205 // 00206 00207 if (DbcsAware) { 00208 00209 OemLength += IsDbcsCharacter(wc) ? 2 : 1; 00210 00211 if (OemLength > 6) { break; } 00212 } 00213 00214 // 00215 // Copy the UNICODE character into the name buffer 00216 // 00217 00218 Context->NameBuffer[Context->NameLength++] = wc; 00219 } 00220 00221 // 00222 // Now if the name part of the basis is 2 or less bytes (when 00223 // represented in Oem) then append a four character checksum 00224 // to make the short name space less sparse. 00225 // 00226 00227 if ((DbcsAware ? OemLength : Context->NameLength) <= 2) { 00228 00229 USHORT Checksum; 00230 WCHAR Nibble; 00231 00232 Checksum = 00233 Context->Checksum = RtlComputeLfnChecksum( Name ); 00234 00235 for (i = 0; i < 4; i++, Checksum >>= 4) { 00236 00237 Nibble = Checksum & 0xf; 00238 Nibble += Nibble <= 9 ? '0' : 'A' - 10; 00239 00240 Context->NameBuffer[ Context->NameLength + i ] = Nibble; 00241 } 00242 00243 Context->NameLength += 4; 00244 Context->ChecksumInserted = TRUE; 00245 } 00246 00247 // 00248 // Now process the last extension (if there is one). 00249 // If the last dot index is not MAXULONG then we 00250 // have located the last dot in the name 00251 // 00252 00253 if (LastDotIndex != MAXULONG) { 00254 00255 // 00256 // Put in the "." 00257 // 00258 00259 Context->ExtensionBuffer[0] = L'.'; 00260 00261 // 00262 // Process the extension similar to how we processed the name 00263 // 00264 // We exit the loop if: 00265 // 00266 // - The input Name has been exhausted 00267 // - We have filled . + 3 characters of extension 00268 // 00269 00270 OemLength = 1; 00271 Context->ExtensionLength = 1; 00272 00273 while ((wc = GetNextWchar( Name, &LastDotIndex, TRUE, AllowExtendedCharacters)) && 00274 (Context->ExtensionLength < 4)) { 00275 00276 if (DbcsAware) { 00277 00278 OemLength += IsDbcsCharacter(wc) ? 2 : 1; 00279 00280 if (OemLength > 4) { break; } 00281 } 00282 00283 Context->ExtensionBuffer[Context->ExtensionLength++] = wc; 00284 } 00285 00286 // 00287 // If we had to truncate the extension (i.e. input name was not 00288 // exhausted), change the last char of the truncated extension 00289 // to a ~ is user has selected safe extensions. 00290 // 00291 00292 if (wc && FsRtlSafeExtensions) { 00293 00294 Context->ExtensionBuffer[Context->ExtensionLength - 1] = L'~'; 00295 } 00296 00297 } else { 00298 00299 Context->ExtensionLength = 0; 00300 } 00301 } 00302 00303 // 00304 // In all cases we add one to the index value and this is the value 00305 // of the index we are going to generate this time around 00306 // 00307 00308 Context->LastIndexValue += 1; 00309 00310 // 00311 // Now if the new index value is greater than 4 then we've had too 00312 // many collisions and we should alter our basis if possible 00313 // 00314 00315 if ((Context->LastIndexValue > 4) && !Context->ChecksumInserted) { 00316 00317 USHORT Checksum; 00318 WCHAR Nibble; 00319 00320 // 00321 // 'XX' is represented A DBCS character. 00322 // 00323 // LongName -> ShortName | DbcsBias Oem Unicode 00324 // -----------------------------+------------------------ 00325 // XXXXThisisapen -> XX1234 | 1 6 5 00326 // XXThisisapen -> XX1234 | 1 6 5 00327 // aXXThisisapen -> a1234 | 1 5 5 00328 // aaThisisapen -> aa1234 | 0 6 6 00329 // 00330 00331 ULONG DbcsBias; 00332 00333 if (DbcsAware) { 00334 00335 DbcsBias = ((IsDbcsCharacter(Context->NameBuffer[0]) ? 1 : 0) | 00336 (IsDbcsCharacter(Context->NameBuffer[1]) ? 1 : 0)); 00337 00338 } else { 00339 00340 DbcsBias = 0; 00341 } 00342 00343 Checksum = 00344 Context->Checksum = RtlComputeLfnChecksum( Name ); 00345 00346 for (i = (2-DbcsBias); i < (6-DbcsBias); i++, Checksum >>= 4) { 00347 00348 Nibble = Checksum & 0xf; 00349 Nibble += Nibble <= 9 ? '0' : 'A' - 10; 00350 00351 Context->NameBuffer[ i ] = Nibble; 00352 } 00353 00354 Context->NameLength = (UCHAR)(6-DbcsBias); 00355 Context->LastIndexValue = 1; 00356 Context->ChecksumInserted = TRUE; 00357 } 00358 00359 // 00360 // Now build the index buffer from high index to low index because we 00361 // use a mod & div operation to build the string from the index value. 00362 // 00363 // We also want to remember is we are about to rollover in base 10. 00364 // 00365 00366 for (IndexLength = 1, i = Context->LastIndexValue; 00367 (IndexLength <= 7) && (i > 0); 00368 IndexLength += 1, i /= 10) { 00369 00370 if ((IndexBuffer[ 8 - IndexLength] = (WCHAR)(L'0' + (i % 10))) != L'9') { 00371 00372 IndexAll9s = FALSE; 00373 } 00374 } 00375 00376 // 00377 // And tack on the preceding dash 00378 // 00379 00380 IndexBuffer[ 8 - IndexLength ] = L'~'; 00381 00382 // 00383 // At this point everything is set up to copy to the output buffer. First 00384 // copy over the name and then only copy the index and extension if they exist 00385 // 00386 00387 if (Context->NameLength != 0) { 00388 00389 RtlCopyMemory( &Name8dot3->Buffer[0], 00390 &Context->NameBuffer[0], 00391 Context->NameLength * 2 ); 00392 00393 Name8dot3->Length = (USHORT)(Context->NameLength * 2); 00394 00395 } else { 00396 00397 Name8dot3->Length = 0; 00398 } 00399 00400 // 00401 // Now do the index. 00402 // 00403 00404 RtlCopyMemory( &Name8dot3->Buffer[ Name8dot3->Length/2 ], 00405 &IndexBuffer[ 8 - IndexLength ], 00406 IndexLength * 2 ); 00407 00408 Name8dot3->Length += (USHORT) (IndexLength * 2); 00409 00410 // 00411 // Now conditionally do the extension 00412 // 00413 00414 if (Context->ExtensionLength != 0) { 00415 00416 RtlCopyMemory( &Name8dot3->Buffer[ Name8dot3->Length/2 ], 00417 &Context->ExtensionBuffer[0], 00418 Context->ExtensionLength * 2 ); 00419 00420 Name8dot3->Length += (USHORT) (Context->ExtensionLength * 2); 00421 } 00422 00423 // 00424 // If current index value is all 9s, then the next value will cause the 00425 // index string to grow from it's current size. In this case recompute 00426 // Context->NameLength so that is will be correct for next time. 00427 // 00428 00429 if (IndexAll9s) { 00430 00431 if (DbcsAware) { 00432 00433 for (i = 0, OemLength = 0; i < Context->NameLength; i++) { 00434 00435 OemLength += IsDbcsCharacter(Context->NameBuffer[i]) ? 2 : 1; 00436 00437 if (OemLength >= 8 - (IndexLength + 1)) { 00438 break; 00439 } 00440 } 00441 00442 Context->NameLength = (UCHAR)i; 00443 00444 } else { 00445 00446 Context->NameLength -= 1; 00447 } 00448 } 00449 00450 // 00451 // And return to our caller 00452 // 00453 00454 return; 00455 }

BOOLEAN RtlIsNameLegalDOS8Dot3 IN PUNICODE_STRING  Name,
IN OUT POEM_STRING OemName  OPTIONAL,
OUT PBOOLEAN NameContainsSpaces  OPTIONAL
 

Definition at line 729 of file gen8dot3.c.

References FALSE, Index, Name, NlsMbOemCodePageTag, NlsOemLeadByteInfo, NT_SUCCESS, RtlFatIllegalTable, RtlUpcaseUnicodeStringToCountedOemString(), and TRUE.

Referenced by LB_CreateLBLine().

00736 : 00737 00738 This routine takes an input string and gives a definitive answer 00739 on whether this name can successfully be used to create a file 00740 on the FAT file system. 00741 00742 This routine can therefore also be used to determine if a name is 00743 appropriate to be passed back to a Win31 or DOS app, i.e. whether 00744 the downlevel APP will understand the name. 00745 00746 Note: an important part of this test is the mapping from UNICODE 00747 to Oem, which is why it is important that the input parameter be 00748 received in UNICODE. 00749 00750 Arguments: 00751 00752 Name - The UNICODE name to test for conformance to 8.3 symantics. 00753 00754 OemName - If specified, will receive the Oem name corresponding 00755 to the passed in Name. Storage must be provided by the caller. 00756 The name is undefined if the routine returns FALSE. 00757 00758 NameContainsSpaces - If the function returns TRUE, then this 00759 parameter will indicate if the names contains spaces. If 00760 the function returns FALSE, this parameter is undefined. In 00761 many instances, the alternate name is more appropriate to 00762 use if spaces are present in the principle name, even if 00763 it is 8.3 compliant. 00764 00765 Return Value: 00766 00767 BOOLEAN - TRUE if the passed in UNICODE name forms a valid 8.3 00768 FAT name when upcased to the current Oem code page. 00769 00770 --*/ 00771 00772 { 00773 ULONG Index; 00774 BOOLEAN ExtensionPresent = FALSE; 00775 BOOLEAN SpacesPresent = FALSE; 00776 OEM_STRING LocalOemName; 00777 UCHAR Char; 00778 UCHAR OemBuffer[12]; 00779 00780 // 00781 // If the name is more than 12 chars, bail. 00782 // 00783 00784 if (Name->Length > 12*sizeof(WCHAR)) { 00785 return FALSE; 00786 } 00787 00788 // 00789 // Now upcase this name to Oem. If anything goes wrong, 00790 // return FALSE. 00791 // 00792 00793 if (!ARGUMENT_PRESENT(OemName)) { 00794 00795 OemName = &LocalOemName; 00796 00797 OemName->Buffer = &OemBuffer[0]; 00798 OemName->Length = 0; 00799 OemName->MaximumLength = 12; 00800 } 00801 00802 if (!NT_SUCCESS(RtlUpcaseUnicodeStringToCountedOemString(OemName, Name, FALSE))) { 00803 return FALSE; 00804 } 00805 00806 // 00807 // Special case . and .. 00808 // 00809 00810 if (((OemName->Length == 1) && (OemName->Buffer[0] == '.')) || 00811 ((OemName->Length == 2) && (OemName->Buffer[0] == '.') && (OemName->Buffer[1] == '.'))) { 00812 00813 if (ARGUMENT_PRESENT(NameContainsSpaces)) { 00814 *NameContainsSpaces = FALSE; 00815 } 00816 return TRUE; 00817 } 00818 00819 // 00820 // Now we are going to walk through the string looking for 00821 // illegal characters and/or incorrect syntax. 00822 // 00823 00824 for ( Index = 0; Index < OemName->Length; Index += 1 ) { 00825 00826 Char = OemName->Buffer[ Index ]; 00827 00828 // 00829 // Skip over and Dbcs chacters 00830 // 00831 00832 if (NlsMbOemCodePageTag && NlsOemLeadByteInfo[Char]) { 00833 00834 // 00835 // 1) if we're looking at base part ( !ExtensionPresent ) and the 8th byte 00836 // is in the dbcs leading byte range, it's error ( Index == 7 ). If the 00837 // length of base part is more than 8 ( Index > 7 ), it's definitely error. 00838 // 00839 // 2) if the last byte ( Index == DbcsName.Length - 1 ) is in the dbcs leading 00840 // byte range, it's error 00841 // 00842 00843 if ((!ExtensionPresent && (Index >= 7)) || 00844 (Index == (ULONG)(OemName->Length - 1))) { 00845 return FALSE; 00846 } 00847 00848 Index += 1; 00849 00850 continue; 00851 } 00852 00853 // 00854 // Make sure this character is legal. 00855 // 00856 00857 if ((Char < 0x80) && 00858 (RtlFatIllegalTable[Char/32] & (1 << (Char%32)))) { 00859 return FALSE; 00860 } 00861 00862 // 00863 // Remember if there was a space. 00864 // 00865 00866 if (Char == ' ') { 00867 SpacesPresent = TRUE; 00868 } 00869 00870 if (Char == '.') { 00871 00872 // 00873 // We stepped onto a period. We require the following things: 00874 // 00875 // - There can only be one 00876 // - It can't be the first character 00877 // - The previous character can't be a space. 00878 // - There can't be more than 3 bytes following 00879 // 00880 00881 if (ExtensionPresent || 00882 (Index == 0) || 00883 (OemName->Buffer[Index - 1] == ' ') || 00884 (OemName->Length - (Index + 1) > 3)) { 00885 00886 return FALSE; 00887 } 00888 00889 ExtensionPresent = TRUE; 00890 } 00891 00892 // 00893 // The base part of the name can't be more than 8 characters long. 00894 // 00895 00896 if ((Index >= 8) && !ExtensionPresent) { return FALSE; } 00897 } 00898 00899 // 00900 // The name cannot end in a space or a period. 00901 // 00902 00903 if ((Char == ' ') || (Char == '.')) { return FALSE; } 00904 00905 if (ARGUMENT_PRESENT(NameContainsSpaces)) { 00906 *NameContainsSpaces = SpacesPresent; 00907 } 00908 return TRUE; 00909 }

BOOLEAN RtlIsValidOemCharacter IN PWCHAR  Char  ) 
 

Definition at line 459 of file gen8dot3.c.

References FALSE, HIBYTE, LOBYTE, NLS_UPCASE, NlsMbOemCodePageTables, NlsMbOemCodePageTag, NlsOemLeadByteInfo, NlsOemToUnicodeData, NlsUnicodeToMbOemData, NlsUnicodeToOemData, OemDefaultChar, TRUE, and USHORT.

Referenced by GetNextWchar().

00465 : 00466 00467 This routine determines if the best-fitted and upcased version of the 00468 input unicode char is a valid Oem character. 00469 00470 Arguments: 00471 00472 Char - Supplies the Unicode char and receives the best-fitted and 00473 upcased version if it was indeed valid. 00474 00475 Return Value: 00476 00477 TRUE if the character was valid. 00478 00479 --*/ 00480 00481 { 00482 WCHAR UniTmp; 00483 WCHAR OemChar; 00484 00485 // 00486 // First try to make a round trip from Unicode->Oem->Unicode. 00487 // 00488 00489 if (!NlsMbOemCodePageTag) { 00490 00491 UniTmp = (WCHAR)NLS_UPCASE(NlsOemToUnicodeData[(UCHAR)NlsUnicodeToOemData[*Char]]); 00492 OemChar = NlsUnicodeToOemData[UniTmp]; 00493 00494 } else { 00495 00496 // 00497 // Convert to OEM and back to Unicode before upper casing 00498 // to ensure the visual best fits are converted and 00499 // upper cased properly. 00500 // 00501 00502 OemChar = NlsUnicodeToMbOemData[ *Char ]; 00503 00504 if (NlsOemLeadByteInfo[HIBYTE(OemChar)]) { 00505 00506 USHORT Entry; 00507 00508 // 00509 // Lead byte - translate the trail byte using the table 00510 // that corresponds to this lead byte. 00511 // 00512 00513 Entry = NlsOemLeadByteInfo[HIBYTE(OemChar)]; 00514 UniTmp = (WCHAR)NlsMbOemCodePageTables[ Entry + LOBYTE(OemChar) ]; 00515 00516 } else { 00517 00518 // 00519 // Single byte character. 00520 // 00521 00522 UniTmp = NlsOemToUnicodeData[LOBYTE(OemChar)]; 00523 } 00524 00525 // 00526 // Now upcase this UNICODE character, and convert it to Oem. 00527 // 00528 00529 UniTmp = (WCHAR)NLS_UPCASE(UniTmp); 00530 OemChar = NlsUnicodeToMbOemData[UniTmp]; 00531 } 00532 00533 // 00534 // Now if the final OemChar is the default one, then there was no 00535 // mapping for this UNICODE character. 00536 // 00537 00538 if (OemChar == OemDefaultChar) { 00539 00540 return FALSE; 00541 00542 } else { 00543 00544 *Char = UniTmp; 00545 return TRUE; 00546 } 00547 }


Variable Documentation

PUSHORT NlsMbOemCodePageTables
 

Definition at line 31 of file gen8dot3.c.

Referenced by RtlIsValidOemCharacter(), RtlOemToUnicodeN(), RtlResetRtlTranslations(), and RtlUpcaseUnicodeToOemN().

BOOLEAN NlsMbOemCodePageTag
 

Definition at line 32 of file gen8dot3.c.

Referenced by FsRtlIsDbcsInExpression(), RtlGenerate8dot3Name(), RtlIsNameLegalDOS8Dot3(), RtlIsValidOemCharacter(), RtlOemToUnicodeN(), RtlpDidUnicodeToOemWork(), RtlResetRtlTranslations(), RtlUnicodeToOemN(), and RtlUpcaseUnicodeToOemN().

PUSHORT NlsOemLeadByteInfo
 

Definition at line 33 of file gen8dot3.c.

Referenced by RtlIsNameLegalDOS8Dot3(), RtlIsValidOemCharacter(), RtlOemToUnicodeN(), RtlpDidUnicodeToOemWork(), RtlResetRtlTranslations(), and RtlUpcaseUnicodeToOemN().

PUSHORT NlsOemToUnicodeData
 

Definition at line 29 of file gen8dot3.c.

Referenced by RtlIsValidOemCharacter(), RtlOemToUnicodeN(), RtlResetRtlTranslations(), and RtlUpcaseUnicodeToOemN().

PUSHORT NlsUnicodeToMbOemData
 

Definition at line 28 of file gen8dot3.c.

Referenced by RtlIsValidOemCharacter(), RtlResetRtlTranslations(), RtlUnicodeToOemN(), and RtlUpcaseUnicodeToOemN().

PCH NlsUnicodeToOemData
 

Definition at line 30 of file gen8dot3.c.

Referenced by RtlIsValidOemCharacter(), RtlResetRtlTranslations(), RtlUnicodeToOemN(), and RtlUpcaseUnicodeToOemN().

USHORT OemDefaultChar
 

Definition at line 34 of file gen8dot3.c.

Referenced by RtlIsValidOemCharacter(), RtlpDidUnicodeToOemWork(), and RtlResetRtlTranslations().

const ULONG RtlFatIllegalTable[]
 

Initial value:

{ 0xffffffff, 0xfc009c04, 0x38000000, 0x10000000 }

Definition at line 41 of file gen8dot3.c.

Referenced by GetNextWchar(), and RtlIsNameLegalDOS8Dot3().


Generated on Sat May 15 19:43:48 2004 for test by doxygen 1.3.7