Windows 11 Bug in RtlUnicodeStringToOemString #19570

Closed
opened 2026-01-31 06:47:32 +00:00 by claunia · 10 comments
Owner

Originally created by @leecher1337 on GitHub (Mar 23, 2023).

Originally assigned to: @DHowett on GitHub.

Windows Terminal version

No response

Windows build number

10.0.22000.1696

Other Software

No response

Steps to reproduce

  1. In my example, I'm using a German Windows 11 System which has default OEM Codepage CP850
  2. Enable Legacy console mode:

image

  1. Enable raster font:
    image

  2. Restart console so that it start up.
    Now try to Type Umlauts on your keyboard:

image

All Applications that are using RtlUnicodeStringToOemString API are also affected, i.e. File Save support on NTVDMx64

The bug is due to the incorrect codepage being used in RtlOemToUnicodeN API. The codepage gets properly initialized in RtlpInitCodePageTables, but doesn't get used lateron.
Here is a detailled description of the bug, fixing it should be trivial by using the correct codepage:
Analysis
It also contains a test program.

The bug wasn't there on Windows 10 but seems to have been introduced in Win 11 which also introduced other bugs in the Console Host by removal of the NLS Tables in the PEB which I'm also mentioning for the sake of completeness:

( Sidenote:
The removal of the OemCodePageData pointer from PEB in Windows 11 leads to a crash in ConHost V1 when using OEM codepage there, because GlyphCP doesn't get initialized due to the lack of PEB->OemCodePageData.
This in turn leads to crashes in conhost functions:

         ConvertOutputToUnicode
         FalseUnicodeToRealUnicode
         SB_CharToWcharGlyph

The practical result is that conhost crashes when i.e. not using raster font in console, but TTF like "Lucidia Console" and console application runs with OEM codepage.
)

Here is a complied version of the program that is mentioned in the problem analysis description in order to test:
nlstest.zip

Expected Behavior

Entering Umlauts on the keyboard should display the correct Umlauts:

image

Actual Behavior

See above.

Originally created by @leecher1337 on GitHub (Mar 23, 2023). Originally assigned to: @DHowett on GitHub. ### Windows Terminal version _No response_ ### Windows build number 10.0.22000.1696 ### Other Software _No response_ ### Steps to reproduce 1) In my example, I'm using a German Windows 11 System which has default OEM Codepage CP850 2) Enable Legacy console mode: ![image](https://user-images.githubusercontent.com/6495842/227211734-d4cb7746-ed38-4df2-b579-6fb337d7a80c.png) 3) Enable raster font: ![image](https://user-images.githubusercontent.com/6495842/227215486-28c01e86-978d-4bbf-9838-ecd825aea100.png) 4) Restart console so that it start up. Now try to Type Umlauts on your keyboard: ![image](https://user-images.githubusercontent.com/6495842/227215275-05b19fda-0656-458d-89c6-8cb79b99cbdc.png) All Applications that are using [RtlUnicodeStringToOemString ](https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-rtlunicodestringtooemstring) API are also affected, i.e. File Save support on NTVDMx64 The bug is due to the incorrect codepage being used in [RtlOemToUnicodeN](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtloemtounicoden) API. The codepage gets properly initialized in `RtlpInitCodePageTables`, but doesn't get used lateron. Here is a detailled description of the bug, fixing it should be trivial by using the correct codepage: [Analysis](https://github.com/leecher1337/ntvdmx64/discussions/218) It also contains a test program. The bug wasn't there on Windows 10 but seems to have been introduced in Win 11 which also introduced other bugs in the Console Host by removal of the NLS Tables in the PEB which I'm also mentioning for the sake of completeness: ( Sidenote: The removal of the OemCodePageData pointer from PEB in Windows 11 leads to a crash in ConHost V1 when using OEM codepage there, because GlyphCP doesn't get initialized due to the lack of PEB->OemCodePageData. This in turn leads to crashes in conhost functions: ConvertOutputToUnicode FalseUnicodeToRealUnicode SB_CharToWcharGlyph The practical result is that conhost crashes when i.e. not using raster font in console, but TTF like "Lucidia Console" and console application runs with OEM codepage. ) Here is a complied version of the program that is mentioned in the problem analysis description in order to test: [nlstest.zip](https://github.com/microsoft/terminal/files/11051158/nlstest.zip) ### Expected Behavior Entering Umlauts on the keyboard should display the correct Umlauts: ![image](https://user-images.githubusercontent.com/6495842/227214249-dd121432-1e8c-4671-8705-0878589e462f.png) ### Actual Behavior See above.
claunia added the Needs-TriageIssue-Bug labels 2026-01-31 06:47:32 +00:00
Author
Owner

@lhecker commented on GitHub (Mar 23, 2023):

From what I can tell this is MSFT-42362468 and a fix has merged into build version 25285.
The bug happens because RtlOemToUnicodeN incorrectly uses the ACP and not the OEMCP value. In the disassembler screenshot you linked, you can see how the 1252 codepage value matches the ACP value in the registry.

The removal of the OemCodePageData pointer from PEB in Windows 11 leads to a crash in ConHost V1 when using OEM codepage there, because GlyphCP doesn't get initialized due to the lack of PEB->OemCodePageData.

That sounds like another, unrelated bug, but one we should definitely fix!

@lhecker commented on GitHub (Mar 23, 2023): From what I can tell this is MSFT-42362468 and a fix has merged into build version 25285. The bug happens because `RtlOemToUnicodeN` incorrectly uses the ACP and not the OEMCP value. In the disassembler screenshot you linked, you can see how the 1252 codepage value matches the ACP value in the registry. > The removal of the OemCodePageData pointer from PEB in Windows 11 leads to a crash in ConHost V1 when using OEM codepage there, because GlyphCP doesn't get initialized due to the lack of PEB->OemCodePageData. That sounds like another, unrelated bug, but one we should definitely fix!
Author
Owner

@DHowett commented on GitHub (Mar 23, 2023):

Yeah! It's amazing that somebody actually ran into it in the wild.

In the interest of full disclosure... we're actually looking at removing ConhostV1 from the product or making it an optional feature. It's been around for almost 10 years at this point, and it was always intended to be a stopgap. 😄

@lhecker I actually removed GlyphCP entirely back in !7094496 to fix MSFT-26378124, MSFT-26378186, and MSFT-27802525. That shipped out in SV2 RTM at build 22621.

@DHowett commented on GitHub (Mar 23, 2023): Yeah! It's amazing that somebody actually ran into it in the wild. In the interest of full disclosure... we're actually looking at removing ConhostV1 from the product or making it an optional feature. It's been around for almost 10 years at this point, and it was always intended to be a stopgap. :smile: @lhecker I actually removed GlyphCP entirely back in !7094496 to fix MSFT-26378124, MSFT-26378186, and MSFT-27802525. That shipped out in SV2 RTM at build 22621.
Author
Owner

@lhecker commented on GitHub (Mar 23, 2023):

Ah, I was meaning to ask anyways and I'm genuinely curious: What's your reason to use the old legacy console? Does the modern conhost have some defect due to which it can't be used with ntvdmx64?

@lhecker commented on GitHub (Mar 23, 2023): Ah, I was meaning to ask anyways and I'm genuinely curious: What's your reason to use the old legacy console? Does the modern conhost have some defect due to which it can't be used with ntvdmx64?
Author
Owner

@DHowett commented on GitHub (Mar 23, 2023):

Oh, it absolutely does. We removed a bunch of the things that supported the VDM in the transition to conhostv2.

@DHowett commented on GitHub (Mar 23, 2023): Oh, it absolutely does. We removed a bunch of the things that supported the VDM in the transition to conhostv2.
Author
Owner

@leecher1337 commented on GitHub (Mar 23, 2023):

https://github.com/microsoft/terminal/issues/14885 and https://github.com/microsoft/terminal/issues/246 are show-stoppers for me with ConhostV2.
Removing ConhostV1 will effectively kill NTVDMx64, that's bad news for me indeed

@leecher1337 commented on GitHub (Mar 23, 2023): https://github.com/microsoft/terminal/issues/14885 and https://github.com/microsoft/terminal/issues/246 are show-stoppers for me with ConhostV2. Removing ConhostV1 will effectively kill NTVDMx64, that's bad news for me indeed
Author
Owner

@DHowett commented on GitHub (Mar 23, 2023):

Eh, I came out swinging. I think what we'll really do is make it an optional feature. It would be very cool if we could open-source it . . . hmm

@DHowett commented on GitHub (Mar 23, 2023): Eh, I came out swinging. I think what we'll _really_ do is make it an optional feature. It would be very cool if we could open-source it . . . hmm
Author
Owner

@leecher1337 commented on GitHub (Mar 23, 2023):

Having support for VDM-Stuff in ConhostV2 would be really cool, because i.e. WSL requires conhost V2 and one of the main benefits of NTVDM is the seamless integration with the Windows Console. Of course, mixing conhosts can cause the feature to break, as VDM-application would need to run in a new, seperate console with ConhostV1.
Currently, I'm setting ForceV2 to 0 so that it globally uses the ConhostV1 to prevent this, and in case the user doesn't want to do this, a new DOS application is forced to load in a new ConhostV1 window as a fallback.
But unfortunately ConhostV2 code is too complicated to me to understand in order to implement all of this by myself.

@leecher1337 commented on GitHub (Mar 23, 2023): Having support for VDM-Stuff in ConhostV2 would be really cool, because i.e. WSL requires conhost V2 and one of the main benefits of NTVDM is the seamless integration with the Windows Console. Of course, mixing conhosts can cause the feature to break, as VDM-application would need to run in a new, seperate console with ConhostV1. Currently, I'm setting ForceV2 to 0 so that it globally uses the ConhostV1 to prevent this, and in case the user doesn't want to do this, a new DOS application is forced to load in a new ConhostV1 window as a fallback. But unfortunately ConhostV2 code is too complicated to me to understand in order to implement all of this by myself.
Author
Owner

@Thomasmiller28 commented on GitHub (Mar 29, 2023):

Big question when is Windows 11 build version 25285 being released because the ö, ü, ä translation RtlUnicodeStringToOemString is very problematic?

@Thomasmiller28 commented on GitHub (Mar 29, 2023): Big question when is Windows 11 build version 25285 being released because the ö, ü, ä translation RtlUnicodeStringToOemString is very problematic?
Author
Owner

@DHowett commented on GitHub (Apr 26, 2023):

Unfortunately, I can't comment on the release cycle for Windows and when this fix is going to come out.

Since the issue in the console v1 code has been fixed, I'm gonna close this one out... but please do feel free to continue discussing here or over in our Discussions section!

@DHowett commented on GitHub (Apr 26, 2023): Unfortunately, I can't comment on the release cycle for Windows and when this fix is going to come out. Since the issue in the console v1 code has been fixed, I'm gonna close this one out... but please do feel free to continue discussing here or over in our Discussions section!
Author
Owner

@leecher1337 commented on GitHub (Jul 8, 2023):

Sorry for unrelated off-topic question, but is there a facility to report USER32 problems? Terminal luckily is here on github with developers actively looking at it, but naturally other Windows itnernal components are not available as projects.
Recent Win11 versions killed UserRegisterWowHandlers function and the usage of related pointers, thus killing off WOW32 support completely (why devs are ripping out working code is a mystery to me). This issue cannot be fixed by workaround, as multiple internal USER32.DLL functions are affected (i.e. ECInsertText etc.).
I reported it to Feedback hub at https://aka.ms/AAl858b but posting there normally is quite pointless, I never received any feedback on issues reported over there yet. (Fun fact: 30% of ldntvdm sourcecode is just about fixing MS Windows bugs that were never fixed in various Windows releases)

I guess I'm out of luck and have to bury WOW32 support starting with Windows 11 22H2 due to this breaking change?
Any hints would be appreciated. Thank you.

@leecher1337 commented on GitHub (Jul 8, 2023): Sorry for unrelated off-topic question, but is there a facility to report USER32 problems? Terminal luckily is here on github with developers actively looking at it, but naturally other Windows itnernal components are not available as projects. Recent Win11 versions killed `UserRegisterWowHandlers` function and the usage of related pointers, thus killing off WOW32 support completely (why devs are ripping out working code is a mystery to me). This issue cannot be fixed by workaround, as multiple internal USER32.DLL functions are affected (i.e. `ECInsertText` etc.). I reported it to Feedback hub at https://aka.ms/AAl858b but posting there normally is quite pointless, I never received any feedback on issues reported over there yet. (Fun fact: 30% of ldntvdm sourcecode is just about fixing MS Windows bugs that were never fixed in various Windows releases) I guess I'm out of luck and have to bury WOW32 support starting with Windows 11 22H2 due to this breaking change? Any hints would be appreciated. Thank you.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#19570