From: Aleksey Bragin Date: Sat, 10 Oct 2009 13:22:41 +0000 (+0000) Subject: - Implement RtlpDidUnicodeToOemWork to check for unmapped characters. Based on a... X-Git-Tag: ReactOS-0.3.11~569 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=fcd17ff4fbf63d542c59bc686437f95ddca3bf2b - Implement RtlpDidUnicodeToOemWork to check for unmapped characters. Based on a patch by Daniel Zimmerman. See issue #4548 for more details. svn path=/trunk/; revision=43363 --- diff --git a/reactos/lib/rtl/nls.c b/reactos/lib/rtl/nls.c index 389297cec78..319cbcf02c5 100644 --- a/reactos/lib/rtl/nls.c +++ b/reactos/lib/rtl/nls.c @@ -33,6 +33,10 @@ PCHAR NlsUnicodeToOemTable =NULL; PWCHAR NlsDbcsUnicodeToOemTable = NULL; PUSHORT _NlsOemLeadByteInfo = NULL; /* exported */ +USHORT NlsOemDefaultChar = '\0'; +USHORT NlsUnicodeDefaultChar = 0; + + #define NlsOemLeadByteInfo _NlsOemLeadByteInfo #define INIT_FUNCTION @@ -435,6 +439,10 @@ RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable) /* Set Unicode case map data */ NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable; NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable; + + /* set the default characters for RtlpDidUnicodeToOemWork */ + NlsOemDefaultChar = NlsTable->OemTableInfo.DefaultChar; + NlsUnicodeDefaultChar = NlsTable->OemTableInfo.TransDefaultChar; } diff --git a/reactos/lib/rtl/unicode.c b/reactos/lib/rtl/unicode.c index cd7927c5739..c1f23583723 100644 --- a/reactos/lib/rtl/unicode.c +++ b/reactos/lib/rtl/unicode.c @@ -23,6 +23,9 @@ extern BOOLEAN NlsMbCodePageTag; extern BOOLEAN NlsMbOemCodePageTag; extern PUSHORT NlsLeadByteInfo; +extern USHORT NlsOemDefaultChar; +extern USHORT NlsUnicodeDefaultChar; + /* FUNCTIONS *****************************************************************/ /* @@ -395,6 +398,45 @@ RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString) } } + +/* + * @implemented + * + * NOTES + * Check the oem-string to match the uincoded-string. + * + * Functions who convert unicode strings to oem strings will set a DefaultChar from + * the OemCodepage when the character are unknown. So check it against the unicode string + * and return false when the unicode string not contain an TransDefaultChar. + */ +BOOLEAN +NTAPI +RtlpDidUnicodeToOemWork(IN PCUNICODE_STRING UnicodeString, + IN POEM_STRING OemString) +{ + ULONG i = 0; + + /* Go through all characters of a string */ + while ((OemString->Buffer[i] != 0) && + (i < OemString->Length)) + { + /* Check if it got translated into '?', but source char + wasn't '?' equivalent */ + if ((OemString->Buffer[i] == NlsOemDefaultChar) && + (UnicodeString->Buffer[i] != NlsUnicodeDefaultChar)) + { + /* Yes, it means unmappable characters were found */ + return FALSE; + } + + /* Move to the next char */ + i++; + } + + /* All chars were translated successfuly */ + return TRUE; +} + /* * @unimplemented */ @@ -1534,8 +1576,9 @@ RtlUnicodeStringToCountedOemString( UniSource->Buffer, UniSource->Length); - /* FIXME: Check if everything mapped correctly and - * return STATUS_UNMAPPABLE_CHARACTER */ + /* Check for unmapped character */ + if (NT_SUCCESS(Status) && !RtlpDidUnicodeToOemWork(UniSource, OemDest)) + Status = STATUS_UNMAPPABLE_CHARACTER; if (!NT_SUCCESS(Status) && AllocateDestinationString) { @@ -1763,7 +1806,9 @@ RtlUpcaseUnicodeStringToCountedOemString( UniSource->Buffer, UniSource->Length); - /* FIXME: Special check needed and return STATUS_UNMAPPABLE_CHARACTER */ + /* Check for unmapped characters */ + if (NT_SUCCESS(Status) && !RtlpDidUnicodeToOemWork(UniSource, OemDest)) + Status = STATUS_UNMAPPABLE_CHARACTER; if (!NT_SUCCESS(Status) && AllocateDestinationString) { @@ -1816,7 +1861,9 @@ RtlUpcaseUnicodeStringToOemString ( UniSource->Buffer, UniSource->Length); - /* FIXME: Special check needed and return STATUS_UNMAPPABLE_CHARACTER */ + /* Check for unmapped characters */ + if (NT_SUCCESS(Status) && !RtlpDidUnicodeToOemWork(UniSource, OemDest)) + Status = STATUS_UNMAPPABLE_CHARACTER; if (!NT_SUCCESS(Status) && AllocateDestinationString) {