Index: lib/rtl/nls.c =================================================================== --- lib/rtl/nls.c (revision 41188) +++ lib/rtl/nls.c (working copy) @@ -33,6 +33,10 @@ PWCHAR NlsDbcsUnicodeToOemTable = NULL; PUSHORT _NlsOemLeadByteInfo = NULL; /* exported */ +USHORT NlsOemDefaultChar = '\0'; /* exported */ +USHORT NlsUnicodeDefaultChar = 0; /* exported */ + + #define NlsOemLeadByteInfo _NlsOemLeadByteInfo #define INIT_FUNCTION @@ -435,6 +439,10 @@ /* 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; } Index: lib/rtl/unicode.c =================================================================== --- lib/rtl/unicode.c (revision 41188) +++ lib/rtl/unicode.c (working copy) @@ -23,6 +23,9 @@ extern BOOLEAN NlsMbOemCodePageTag; extern PUSHORT NlsLeadByteInfo; +extern USHORT NlsOemDefaultChar; +extern USHORT NlsUnicodeDefaultChar; + /* FUNCTIONS *****************************************************************/ /* @@ -395,7 +398,42 @@ } } + /* + * @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 PUNICODE_STRING UnicodeString,IN POEM_STRING OemString) +{ + ULONG i; + + if ((OemString != NULL) && (OemString->Buffer != NULL)) + { + i = 0; + while ((OemString->Buffer[i]!=0) && (iLength)) + { + if ((OemString->Buffer[i]==NlsOemDefaultChar) && + (UnicodeString->Buffer[i]!=NlsUnicodeDefaultChar)) + { + return FALSE; + } + i++; + } + return TRUE; + } + + return FALSE; +} + +/* * @unimplemented */ BOOLEAN @@ -1534,8 +1572,14 @@ UniSource->Buffer, UniSource->Length); - /* FIXME: Check if everything mapped correctly and - * return STATUS_UNMAPPABLE_CHARACTER */ + if (NT_SUCCESS(Status)) + { + /* check for unmapped character */ + if (RtlpDidUnicodeToOemWork(UniSource,OemDest) == FALSE) + { + Status = STATUS_UNMAPPABLE_CHARACTER; + } + } if (!NT_SUCCESS(Status) && AllocateDestinationString) { @@ -1763,7 +1807,14 @@ UniSource->Buffer, UniSource->Length); - /* FIXME: Special check needed and return STATUS_UNMAPPABLE_CHARACTER */ + if (NT_SUCCESS(Status)) + { + /* check for unmapped character */ + if (RtlpDidUnicodeToOemWork((PUNICODE_STRING)UniSource,OemDest) == FALSE) + { + Status = STATUS_UNMAPPABLE_CHARACTER; + } + } if (!NT_SUCCESS(Status) && AllocateDestinationString) { @@ -1816,7 +1867,14 @@ UniSource->Buffer, UniSource->Length); - /* FIXME: Special check needed and return STATUS_UNMAPPABLE_CHARACTER */ + if (NT_SUCCESS(Status)) + { + /* check for unmapped character */ + if (RtlpDidUnicodeToOemWork((PUNICODE_STRING)UniSource,OemDest) == FALSE) + { + Status = STATUS_UNMAPPABLE_CHARACTER; + } + } if (!NT_SUCCESS(Status) && AllocateDestinationString) {