otya128 / winevdm

16-bit Windows (Windows 1.x, 2.x, 3.0, 3.1, etc.) on 64-bit Windows
GNU General Public License v2.0
2.66k stars 152 forks source link

Can not run from non latin path. #388

Open radjah opened 5 years ago

radjah commented 5 years ago

I get an error "file not found" if I try to run application from folder with non-Latin letters in path.

изображение

Rename or move to folder with only Latin letters in path. изображение

otya128 commented 5 years ago

winevdm can handle non latin path.

Anixx commented 5 years ago

I confirm this: if the path contains Cyrillic, Winevdm does not work. The WineVDM error message also displays garbage instead of Cyrillic letters in the path:

Clipboard_20190622

Programms that have Cyrillic in the path cannot be started neither via command line, nor via double-click.

otya128 commented 5 years ago

code page 1251:И(0xc8)
code page 866:╚(0xc8) Perhaps this is a problem around the OEM code page.

radjah commented 5 years ago

866 - current code page 1251 - win1251 65001 - UTF-8

изображение

https://github.com/otya128/winevdm/blob/master/otvdm/winevdm.c#L503 GetShortPathNameA -> GetShortPathNameW? https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-getshortpathnamew

Anixx commented 5 years ago

I want to point out that NTVDM does not have this problem.

vyv03354 commented 5 years ago

OpenFile16 takes an ANSI-encoded string in the first parameter while OFSTRUCT.szPathname is encoded in the OEM code page. See MS KB Article Q65124.

So strdupAtoW should be used instead of strdupOEMtoW if mode & OF_REOPEN is zero: https://github.com/otya128/winevdm/blob/0c7a6946cd180e30a6bbf9bf604733e9599ba74f/krnl386/file.c#L625

Anixx commented 5 years ago

I tried to run LodeRunner from a folder with Cyrillic name. Now, the main executable starts but says it cannot find the necessary files to start the game. If to rename the folder into Latin, the game starts.

So, I think there is some another location where a similar change is needed. Tetris (which is one-file game) starts well now from a Cyrillic folder.

otya128 commented 5 years ago

I want to find out what functions cause this, so please do the following.

  1. Run command prompt.
  2. SET WINEDEBUG=+all,-snoop,-ldt,-fixup,-module,-global,-local,-disasm,-syslevel
  3. *exe-file* 2> *log-file*
  4. Upload log-file.
radjah commented 5 years ago

chessnet.zip box.zip изображение

vyv03354 commented 5 years ago

I tried to run LodeRunner from a folder with Cyrillic name. Now, the main executable starts but says it cannot find the necessary files to start the game. If to rename the folder into Latin, the game starts.

Apparently, it did not work even with the genuine NTVDM on WinXP 32-bit. (Make sure 8.3 name generation is disabled. If it is enabled, 8.3 names will never contain non-ASCII chars, so the bug will be masked. It is disabled by default for non-system volumes on Win10.) I think the LodeRunner program does not handle non-ASCII filenames correctly, not winevdm's fault.

Anixx commented 5 years ago

From the screenshot above it is evident that winevdm gives wrong path even in the error message. Of course it cannot get the 8.3 filename from that garbage path.

vyv03354 commented 5 years ago

No, only the display is garbled. GetCurrentDirectoryA and GetShortPathNameA will return file paths in ANSI code page: https://github.com/otya128/winevdm/blob/4ed6bf1af8291a86aee15ebc6a7d21561d0393fd/krnl386/task.c#L601-L629 But the console expects the OEM code page (by default), so the display is garbled. It doesn't affect the actual file operation. The path name is correctly encoded in ANSI according to the attached log file. GetShortPathNameA "fails" because "Игры и пр" is longer than 8 characters and 8.3 name generation is disabled on "D:\". More precisely, GetShortPathNameA does not fail. It will return the input without any modification if 8.3 name generation is disabled. But cmd_warnings checks the length of the return value and it fails, so the message is displayed.

vyv03354 commented 5 years ago

That being said, the garbled console output should be fixed because it will confuse reporters. (Making ANSI to GetConsoleOutputCP() conversion if stdout/stderr is a console?).