Hi all, I observed a program that was bailing out with an absolutely baffling error message. I have traced it to its cause, but now I'm stuck. Basically, it was telling me that it had an error in FindNextFile of "success". I did a relay trace and found out that it was calling FindFirstFile, FindNextFile a bunch of times, FindClose, and then GetLastError.
So, I put together a little test:
#include <windows.h> #include <stdio.h>
WIN32_FIND_DATA fd; HANDLE h;
int main(int argc, char *argv[]) {
h = FindFirstFile("*", &fd); if (h == INVALID_HANDLE_VALUE) { printf("Error finding first file: %d\n", GetLastError()); return 1; } printf("found file: %s\n", fd.cFileName); while (FindNextFile(h, &fd)) { printf("found file: %s\n", fd.cFileName); } FindClose(h); switch (GetLastError()) { case ERROR_NO_MORE_FILES: printf("all done!\n"); return 0; default: printf("Error finding next file: %d\n", GetLastError()); return 1; } return 1; }
Now, on Windows, the output is: G:\testfnf>testfnf found file: . found file: .. found file: testfnf.cpp found file: testfnf.exe all done!
And with Wine the output is: [ajp@toaster testfnf]$ ~/wine/wine testfnf.exe found file: . found file: .. found file: testfnf.cpp found file: testfnf.exe Error finding next file: 0
So, it looks like somewhere in FindClose Wine is resetting the last error. I started digging through there and the functions it calls but I was unable to find where it was getting reset. Can anyone shed some light on this? Is there any way to break on that value changing?
Thanks, -ajp
Alex Pasadyn wrote:
So, it looks like somewhere in FindClose Wine is resetting the last error. I started digging through there and the functions it calls but I was unable to find where it was getting reset. Can anyone shed some light on this? Is there any way to break on that value changing?
GlobalUnlock does set last error to 0 if it's unlocking the last lock.
A+
"Eric Pouech" pouech-eric@wanadoo.fr wrote:
So, it looks like somewhere in FindClose Wine is resetting the last error. I started digging through there and the functions it calls but I was unable to find where it was getting reset. Can anyone shed some light on this? Is there any way to break on that value changing?
GlobalUnlock does set last error to 0 if it's unlocking the last lock.
A way to go might be to use HeapAlloc instead of GlobalAlloc and add a critical section to the allocated data structure to protect the object.
Alex, are you willing to do the job?
Dmitry Timoshkov wrote:
"Eric Pouech" pouech-eric@wanadoo.fr wrote:
So, it looks like somewhere in FindClose Wine is resetting the last error. I started digging through there and the functions it calls but I was unable to find where it was getting reset. Can anyone shed some light on this? Is there any way to break on that value changing?
GlobalUnlock does set last error to 0 if it's unlocking the last lock.
A way to go might be to use HeapAlloc instead of GlobalAlloc and add a critical section to the allocated data structure to protect the object.
Alex, are you willing to do the job?
I'll try that and see how it turns out.
-ajp
Your test doesn't make much sense. The call to FindClose should be done after you check the result of GetLastError, since FindClose <should> change the last error to ERROR_SUCCESS if the close operation was successful.
From your test results, it seems that the FindClose implementation on the
version of windows you're using doesn't seem to do this. I would consider this a bug in windows, not a bug in Wine. If a programmer relies on this behavior, it's their fault, not MS's or Wine's fault that their code does not work.
----- Original Message ----- From: "Alex Pasadyn" ajp@mail.utexas.edu To: wine-devel@winehq.org Sent: Saturday, August 16, 2003 11:55 AM Subject: GetLastError strangeness with FindClose
Hi all, I observed a program that was bailing out with an absolutely baffling error message. I have traced it to its cause, but now I'm stuck. Basically, it was telling me that it had an error in FindNextFile of "success". I did a relay trace and found out that it was calling FindFirstFile, FindNextFile a bunch of times, FindClose, and then GetLastError.
So, I put together a little test:
#include <windows.h> #include <stdio.h>
WIN32_FIND_DATA fd; HANDLE h;
int main(int argc, char *argv[]) {
h = FindFirstFile("*", &fd); if (h == INVALID_HANDLE_VALUE) { printf("Error finding first file: %d\n", GetLastError()); return 1; } printf("found file: %s\n", fd.cFileName); while (FindNextFile(h, &fd)) { printf("found file: %s\n", fd.cFileName); } FindClose(h); switch (GetLastError()) { case ERROR_NO_MORE_FILES: printf("all done!\n"); return 0; default: printf("Error finding next file: %d\n", GetLastError()); return 1; } return 1;
}
Now, on Windows, the output is: G:\testfnf>testfnf found file: . found file: .. found file: testfnf.cpp found file: testfnf.exe all done!
And with Wine the output is: [ajp@toaster testfnf]$ ~/wine/wine testfnf.exe found file: . found file: .. found file: testfnf.cpp found file: testfnf.exe Error finding next file: 0
So, it looks like somewhere in FindClose Wine is resetting the last error. I started digging through there and the functions it calls but I was unable to find where it was getting reset. Can anyone shed some light on this? Is there any way to break on that value changing?
Thanks, -ajp
Kelly Leahy wrote:
Your test doesn't make much sense. The call to FindClose should be done after you check the result of GetLastError, since FindClose <should> change the last error to ERROR_SUCCESS if the close operation was successful.
From your test results, it seems that the FindClose implementation on the
version of windows you're using doesn't seem to do this. I would consider this a bug in windows, not a bug in Wine. If a programmer relies on this behavior, it's their fault, not MS's or Wine's fault that their code does not work
AFAIK, it's never said that a successful function call should set the last error to 0. This only thing MS claims is that when a function fails, the last error is set to a error code explaining that error.
Moreover, wine's goal is not to make a better design than windows, but to mimic windows behavior. So, if FindClose doesn't change the last error on success, wine should do the same (especially if some known program depends on it)
A+
AFAIK, it's never said that a successful function call should set the last error to 0. This only thing MS claims is that when a function fails, the last error is set to a error code explaining that error.
Moreover, wine's goal is not to make a better design than windows, but to mimic windows behavior. So, if FindClose doesn't change the last error on success, wine should do the same (especially if some known program depends on it)
You're missing my point (or maybe you're not and you just don't agree with me - in either case, let me make my point in a clearer way). If windows doesn't say it won't change the last error, we, as programmers, should assume that it might. In my experience, a large number of functions that set last error on failure set it to ERROR_SUCCESS on success. For the few that don't, I would consider this an oversight on MS's part, and I wouldn't expect it to exist in all implementations of a particular function (across OS versions).
Just my 0.02.
Kelly
You're missing my point (or maybe you're not and you just don't agree with me - in either case, let me make my point in a clearer way). If windows doesn't say it won't change the last error, we, as programmers, should assume that it might. In my experience, a large number of functions that set last error on failure set it to ERROR_SUCCESS on success. For the few that don't, I would consider this an oversight on MS's part, and I wouldn't expect it to exist in all implementations of a particular function (across OS versions).
let's just test Alex small test program on various platforms and see what gives... A+
Eric Pouech wrote:
You're missing my point (or maybe you're not and you just don't agree with me - in either case, let me make my point in a clearer way). If windows doesn't say it won't change the last error, we, as programmers, should assume that it might. In my experience, a large number of functions that set last error on failure set it to ERROR_SUCCESS on success. For the few that don't, I would consider this an oversight on MS's part, and I wouldn't expect it to exist in all implementations of a particular function (across OS versions).
let's just test Alex small test program on various platforms and see what gives... A+
FWIW, the original program that was giving me a problem was the Diablo 2 1.09 to 1.10beta updater. The workaround I found was to move all the files from my "save" subdirectory to somewhere else, run the patch, and then move them all back. Having any files in the save directory caused it to bomb out with a message about FindNextFile failing due to "success".
I made that test program based on the series of calls I saw in the relay trace, and it gave a different result with Windows (9x was all I had to test) from Wine.
Anyway, if I were writing it I would put the check for the error code before the FindClose, but it wasn't my program...
Cheers, -ajp
On Sat, 16 Aug 2003, Eric Pouech wrote: [...]
let's just test Alex small test program on various platforms and see what gives...
Alex's program works fine on NT4 so it seems to be a valid test. It looks like a good candidate for Wine's conformance tests. Alex, do you feel up to it?
Alex Pasadyn ajp@mail.utexas.edu writes:
it was telling me that it had an error in FindNextFile of "success". I did a relay trace and found out that it was calling FindFirstFile, FindNextFile a bunch of times, FindClose, and then GetLastError.
What happens if you change the Windows version? To http://www.winehq.org/hypermail/wine-patches/2003/05/0334.html (at the bottom) I got the response that it is probably version dependent, and your problem seems to be similar.
Feri.