There seems to be some form of error in the Wine implementation of MSVCRT - with three separate programs (Delorme MapNGo 6.0, Delorme Street Atlas 5, Microsoft Trip Planner 5), if I use Wine's builtin MSVCRT, the programs do not work, but if I use the version of MSVCRT the program supplies, they work.
I don't know much about what is going on, but I do know this: With the Wine MSVCRT, the Delorme packages err trying to load a "vector font" file that is supplied with the Delorme programs. This font file is read by a DLL supplied by Delorme, and is a simple text file describing some of the icons they use in their program (like a house, or a car, etc.). Tracing the operation of the Wine MSVCRT shows that the whole file is read by the DLL, and the DLL does not throw the error until EOF.
I conjecture that there is some difference in behavior between the Wine MSVCRT on EOF and Microsoft's MSVCRT - what I have no idea.
OK, so anybody have any good idea on how I can get more information on this?
"David" == David D Hagood wowbagger@sktc.net writes:
David> There seems to be some form of error in the Wine implementation David> of MSVCRT - with three separate programs (Delorme MapNGo 6.0, David> Delorme Street Atlas 5, Microsoft Trip Planner 5), if I use David> Wine's builtin MSVCRT, the programs do not work, but if I use the David> version of MSVCRT the program supplies, they work.
David> I don't know much about what is going on, but I do know this: David> With the Wine MSVCRT, the Delorme packages err trying to load a David> "vector font" file that is supplied with the Delorme David> programs. This font file is read by a DLL supplied by Delorme, David> and is a simple text file describing some of the icons they use David> in their program (like a house, or a car, etc.). Tracing the David> operation of the Wine MSVCRT shows that the whole file is read by David> the DLL, and the DLL does not throw the error until EOF.
David> I conjecture that there is some difference in behavior between David> the Wine MSVCRT on EOF and Microsoft's MSVCRT - what I have no David> idea.
David> OK, so anybody have any good idea on how I can get more David> information on this?
Run with WINEDEBUG=+relay,+snoop WINEDLLOVERRIDES=msvcrt=n wine <your.program> and WINEDEBUG=+relay,+snoop,+msvcrt WINEDLLOVERRIDES=msvcrt=b wine <your.program> and compare how the msvcrt calls are handled step by step. Tedious, but promising...
Bye
Uwe Bonnes wrote:
Run with WINEDEBUG=+relay,+snoop WINEDLLOVERRIDES=msvcrt=n wine <your.program> and WINEDEBUG=+relay,+snoop,+msvcrt WINEDLLOVERRIDES=msvcrt=b wine <your.program> and compare how the msvcrt calls are handled step by step. Tedious, but promising...
Tedious, but productive. Wine's fgets does not behave as does Microsoft's on EOF:
The Microsoft version: // This is the read of the last line MSVCRT.fgets(7fa3f8e0,00000050,78034ca8) ret=7f5f4e12 000d:RET MSVCRT.fgets() retval=7fa3f8e0 ret=7f5f4e12 000d:CALL MSVCRT.strlen(7fa3f8e0) ret=7f5f4e68 000d:RET MSVCRT.strlen() retval=0000001b ret=7f5f4e68 // This is the read of EOF 000d:CALL MSVCRT.fgets(7fa3f96c,00000050,78034ca8) ret=7f5f4cc2 000d:RET MSVCRT.fgets() retval=00000000 ret=7f5f4cc2 // Notice the fgets returns NULL. 000d:CALL MSVCRT.fclose(78034ca8) ret=7f5f4dc6 // OK, done with file, close and clean up. 000d:RET MSVCRT.fclose() retval=00000000 ret=7f5f4dc6
And the WINE version // Again - the gets of the last line msvcrt.fgets(7fa3f8e0,00000050,7fe04ff8) ret=7f594e12 trace:msvcrt:MSVCRT_fgets :file(0x7fe04ff8) fd (4) str (0x7fa3f8e0) len (80) trace:msvcrt:MSVCRT_fgets :got "1a 2b 4c 6c 7b 7a 68 67 75\n" 000b:Ret msvcrt.fgets() retval=7fa3f8e0 ret=7f594e12 000b:Call msvcrt.strlen(7fa3f8e0 "1a 2b 4c 6c 7b 7a 68 67 75\n") ret=7f594e68 000b:Ret msvcrt.strlen() retval=0000001b ret=7f594e68 // This is the gets of EOF 000b:Call msvcrt.fgets(7fa3f96c,00000050,7fe04ff8) ret=7f594cc2 trace:msvcrt:MSVCRT_fgets :file(0x7fe04ff8) fd (4) str (0x7fa3f96c) len (80) trace:msvcrt:_read :fd (4) handle (0xb8) buf (0x7fe07e40) len (512) // Yup - EOF trace:msvcrt:_read :EOF trace:msvcrt:_read ""... // Gets thinks it got a CTRL-Z trace:msvcrt:MSVCRT_fgets :got "\x1a" // Gets therefor returns that 000b:Ret msvcrt.fgets() retval=7fa3f96c ret=7f594cc2 000b:Call msvcrt.fclose(7fe04ff8) ret=7f594d7a trace:msvcrt:_close :fd (4) handle (0xb8) trace:msvcrt:msvcrt_free_fd :fd (4) freed trace:msvcrt:_close :ok 000b:Ret msvcrt.fclose() retval=00000000 ret=7f594d7a // The program says WTF? 000b:Call msvcrt.vsprintf(7fa3f8c4,7f5d5664 "Error loading
The file in question has an old-style DOS 0x1A at the end of file - evidently the MS version of MSVCRT removes any CTRL-Z at EOF.
I've attached a patch that corrects the problem.
Changelog
dlls/msvcrt/file.c David Hagood (wowbagger@sktc.net) When reading a file in text mode, remove any old-style DOS EOF characters (CTRL-Z) from the end of file.
Index: dlls/msvcrt/file.c =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/file.c,v retrieving revision 1.91 diff -u -r1.91 file.c --- dlls/msvcrt/file.c 7 Oct 2005 15:01:15 -0000 1.91 +++ dlls/msvcrt/file.c 7 Nov 2005 01:15:55 -0000 @@ -1657,7 +1657,16 @@ TRACE(":EOF\n"); MSVCRT_fdesc[fd].wxflag |= WX_ATEOF; if (MSVCRT_fdesc[fd].wxflag & WX_TEXT) + { num_read -= remove_cr(bufstart+all_read,num_read); + /* we also need to remove any CTRL-Z at EOF */ + while (num_read && (bufstart[all_read+num_read-1] == 0x1a)) + { + TRACE("Removing CTRL-Z from EOF\n"); + bufstart[all_read+num_read-1] = 0; + num_read --; + } + } all_read += num_read; if (count > 4) TRACE("%s\n",debugstr_an(buf,all_read));
"David" == David D Hagood wowbagger@sktc.net writes:
... David> I've attached a patch that corrects the problem.
David> Changelog
It is also a good idea to add a test case in our test suite. Send the test/patch to wine-patches for inclusion, perhaps also stating if you allow rewind (wine fork with old X11 license) to reuse the patch
Uwe Bonnes wrote:
"David" == David D Hagood wowbagger@sktc.net writes:
... David> I've attached a patch that corrects the problem.
David> Changelog
It is also a good idea to add a test case in our test suite. Send the test/patch to wine-patches for inclusion, perhaps also stating if you allow rewind (wine fork with old X11 license) to reuse the patch
OK, but I've found another app which works with native MSVCRT but not built-in - so I want to try to track that down as well.
On Mon, 07 Nov 2005 13:14:16 +0100, David D. Hagood wowbagger@sktc.net wrote:
Uwe Bonnes wrote:
> "David" == David D Hagood wowbagger@sktc.net writes:
... David> I've attached a patch that corrects the problem. David> Changelog It is also a good idea to add a test case in our test suite. Send the test/patch to wine-patches for inclusion, perhaps also stating if you allow rewind (wine fork with old X11 license) to reuse the patch
OK, but I've found another app which works with native MSVCRT but not built-in - so I want to try to track that down as well.
Add Dragon to the list if you like, I added some version info to msvcrt.dll to get around the version check but there seemed to be a number of issues with the built-in dll.
"David D. Hagood" wowbagger@sktc.net wrote:
--- dlls/msvcrt/file.c 7 Oct 2005 15:01:15 -0000 1.91 +++ dlls/msvcrt/file.c 7 Nov 2005 01:15:55 -0000 @@ -1657,7 +1657,16 @@ TRACE(":EOF\n"); MSVCRT_fdesc[fd].wxflag |= WX_ATEOF; if (MSVCRT_fdesc[fd].wxflag & WX_TEXT)
{ num_read -= remove_cr(bufstart+all_read,num_read);
/* we also need to remove any CTRL-Z at EOF */
while (num_read && (bufstart[all_read+num_read-1] == 0x1a))
{
TRACE("Removing CTRL-Z from EOF\n");
bufstart[all_read+num_read-1] = 0;
num_read --;
}
}
We need a test to see what happens if there are more characters after 0x1a.