Please forgive a newbie. I have extensive development background, but am new to wine and, though I've used VB a lot, am somewhat new to API programming.
I have an error while running Pagemaker 7.0 and try to paste text from the clipboard that I put into the clipboard from another app. I tried running with +relay and got a bunch of stuff. I tried +msgbox to find a trace for the message box that's created, but that didn't seem to work for some reason.
At any rate, here's the dump and my questions:
0009:Call user32.GetClipboardData(00000001) ret=00439e26 0009:Call winex11.drv.GetClipboardData(00000001,00000000,7fb8edfc) ret=7f903d20 0009:Call kernel32.TlsGetValue(00000002) ret=7e0ab946 0009:Ret kernel32.TlsGetValue() retval=7fd527e8 ret=7e0ab946 0009:Call kernel32.TlsGetValue(00000002) ret=7e0ab6d9 0009:Ret kernel32.TlsGetValue() retval=7fd527e8 ret=7e0ab6d9 0009:Call kernel32.TlsGetValue(00000002) ret=7e0a950d 0009:Ret kernel32.TlsGetValue() retval=7fd527e8 ret=7e0a950d 0009:Call ntdll.RtlAllocateHeap(7fcf0000,00000008,00000324) ret=7e0a960a 0009:Ret ntdll.RtlAllocateHeap() retval=796d6488 ret=7e0a960a 0009:Call kernel32.GlobalAlloc(00002002,00000325) ret=7e0a9cac 0009:Call ntdll.RtlLockHeap(7fcf0000) ret=7fc39ace 0009:Ret ntdll.RtlLockHeap() retval=00000001 ret=7fc39ace 0009:Call ntdll.RtlAllocateHeap(7fcf0000,00000000,00000008) ret=7fc3997c 0009:Ret ntdll.RtlAllocateHeap() retval=796d6048 ret=7fc3997c 0009:Call ntdll.RtlAllocateHeap(7fcf0000,00000000,0000032d) ret=7fc3997c 0009:Ret ntdll.RtlAllocateHeap() retval=796d67b8 ret=7fc3997c 0009:Call ntdll.RtlUnlockHeap(7fcf0000) ret=7fc39b27 0009:Ret ntdll.RtlUnlockHeap() retval=00000001 ret=7fc39b27 0009:Ret kernel32.GlobalAlloc() retval=796d604a ret=7e0a9cac 0009:Call kernel32.GlobalLock(796d604a) ret=7e0a9cbd 0009:Call ntdll.RtlLockHeap(7fcf0000) ret=7fc3a3ad 0009:Ret ntdll.RtlLockHeap() retval=00000001 ret=7fc3a3ad 0009:Call ntdll.RtlUnlockHeap(7fcf0000) ret=7fc3a43f 0009:Ret ntdll.RtlUnlockHeap() retval=00000001 ret=7fc3a43f 0009:Ret kernel32.GlobalLock() retval=796d67c0 ret=7e0a9cbd 0009:Call kernel32.GlobalUnlock(796d604a) ret=7e0a9d07 0009:Call ntdll.RtlLockHeap(7fcf0000) ret=7fc3a5db 0009:Ret ntdll.RtlLockHeap() retval=00000001 ret=7fc3a5db 0009:Call ntdll.RtlUnlockHeap(7fcf0000) ret=7fc3a646 0009:Ret ntdll.RtlUnlockHeap() retval=00000001 ret=7fc3a646 0009:Ret kernel32.GlobalUnlock() retval=00000000 ret=7e0a9d07 0009:Call ntdll.RtlFreeHeap(7fcf0000,00000000,796d6488) ret=7e0a9d2a 0009:Ret ntdll.RtlFreeHeap() retval=00000001 ret=7e0a9d2a 0009:Call kernel32.GlobalSize(796d604a) ret=7e0ad594 0009:Call ntdll.RtlLockHeap(7fcf0000) ret=7fc3a25c 0009:Ret ntdll.RtlLockHeap() retval=00000001 ret=7fc3a25c 0009:Call ntdll.RtlSizeHeap(7fcf0000,00000000,796d67b8) ret=7fc39a25 0009:Ret ntdll.RtlSizeHeap() retval=0000032d ret=7fc39a25 0009:Call ntdll.RtlUnlockHeap(7fcf0000) ret=7fc3a293 0009:Ret ntdll.RtlUnlockHeap() retval=00000001 ret=7fc3a293 0009:Ret kernel32.GlobalSize() retval=00000325 ret=7e0ad594 0009:Call kernel32.24(00000040,00000325) ret=7e0ad5aa 0009:Call ntdll.RtlAllocateHeap(7fcf0000,00000000,00000340) ret=7fc3997c 0009:Ret ntdll.RtlAllocateHeap() retval=796d6af0 ret=7fc3997c 0009:Ret kernel32.24() retval=000012bf ret=7e0ad5aa 0009:Call kernel32.GlobalLock(796d604a) ret=7e0ad5ca 0009:Call ntdll.RtlLockHeap(7fcf0000) ret=7fc3a3ad 0009:Ret ntdll.RtlLockHeap() retval=00000001 ret=7fc3a3ad 0009:Call ntdll.RtlUnlockHeap(7fcf0000) ret=7fc3a43f 0009:Ret ntdll.RtlUnlockHeap() retval=00000001 ret=7fc3a43f 0009:Ret kernel32.GlobalLock() retval=796d67c0 ret=7e0ad5ca 0009:Call kernel32.25(000012bf) ret=7e0ad5db 0009:Ret kernel32.25() retval=796d6af0 ret=7e0ad5db 0009:Call kernel32.26(000012bf) ret=7e0ad5fd 0009:Ret kernel32.26() retval=00000000 ret=7e0ad5fd 0009:Call kernel32.GlobalUnlock(796d604a) ret=7e0ad60b 0009:Call ntdll.RtlLockHeap(7fcf0000) ret=7fc3a5db 0009:Ret ntdll.RtlLockHeap() retval=00000001 ret=7fc3a5db 0009:Call ntdll.RtlUnlockHeap(7fcf0000) ret=7fc3a646 0009:Ret ntdll.RtlUnlockHeap() retval=00000001 ret=7fc3a646 0009:Ret kernel32.GlobalUnlock() retval=00000000 ret=7e0ad60b 0009:Ret winex11.drv.GetClipboardData() retval=00000001 ret=7f903d20 0009:Ret user32.GetClipboardData() retval=796d604a ret=00439e26 0009:Call kernel32.GlobalLock(796d604a) ret=00438bc5 0009:Call ntdll.RtlLockHeap(7fcf0000) ret=7fc3a3ad 0009:Ret ntdll.RtlLockHeap() retval=00000001 ret=7fc3a3ad 0009:Call ntdll.RtlUnlockHeap(7fcf0000) ret=7fc3a43f 0009:Ret ntdll.RtlUnlockHeap() retval=00000001 ret=7fc3a43f 0009:Ret kernel32.GlobalLock() retval=796d67c0 ret=00438bc5 0009:Call kernel32.GlobalUnlock(796d604a) ret=00438bde 0009:Call kernel32.GlobalLock(796d604a) ret=00438bc5 0009:Call ntdll.RtlLockHeap(7fcf0000) ret=7fc3a3ad 0009:Ret ntdll.RtlLockHeap() retval=00000001 ret=7fc3a3ad 0009:Call ntdll.RtlUnlockHeap(7fcf0000) ret=7fc3a43f 0009:Ret ntdll.RtlUnlockHeap() retval=00000001 ret=7fc3a43f 0009:Ret kernel32.GlobalLock() retval=796d67c0 ret=00438bc5 0009:Call kernel32.GlobalUnlock(796d604a) ret=00438bde 0009:Call ntdll.RtlLockHeap(7fcf0000) ret=7fc3a5db 0009:Ret ntdll.RtlLockHeap() retval=00000001 ret=7fc3a5db 0009:Call ntdll.RtlUnlockHeap(7fcf0000) ret=7fc3a646 0009:Ret ntdll.RtlUnlockHeap() retval=00000001 ret=7fc3a646 0009:Ret kernel32.GlobalUnlock() retval=00000000 ret=00438bde 0009:Call user32.OpenClipboard(00010024) ret=00439e04 0009:Ret user32.OpenClipboard() retval=00000000 ret=00439e04
1. On the line: Call user32.GetClipboardData(00000001) ret=00439e26, what does the ret mean? Isn't the return value posted later in the log?
2. I haven't found a user32.c and have found many, many hits in the source for GetClipboardData that I'm trying to sort through? How do I find the source code for that call?
3. Since I haven't found that, I can't verify the type being passed it. It should be CF_TEXT, but without the source, how do I find the value for that constant?
4. It looks like GetClipboardData returned a handle with a value of 796d604a, then it immediately locks this. It then turns around and unlocks it without doing anything, then never uses this handle again. Is this right?
5. After all that, it appears to allocate and unallocate memory and then re-open the clipboard. Is it doing this because the last time it tried it got nothing? Then, because it returned 0000000, it gave up and generated an error?
Thanks.
On Tue, May 02, 2006 at 09:12:11AM -0700, Thomas Hehl wrote:
- On the line: Call user32.GetClipboardData(00000001) ret=00439e26,
what does the ret mean? Isn't the return value posted later in the log?
a) "ret" is the return address of the function. b) the return value is posted at the end of the line (retval).
- I haven't found a user32.c and have found many, many hits in the
source for GetClipboardData that I'm trying to sort through? How do I find the source code for that call?
The command
% find WINESRCTREE -name "*user32*"
produces the directory 'dlls/user'.
- Since I haven't found that, I can't verify the type being passed
it. It should be CF_TEXT, but without the source, how do I find the value for that constant?
The command
% grep 'define CF_TEXT' . -r ./include/winuser.h:3654:#define CF_TEXT 1
shows it.
- It looks like GetClipboardData returned a handle with a value of
796d604a, then it immediately locks this. It then turns around and unlocks it without doing anything, then never uses this handle again. Is this right?
I don't know, but I suppose there's stuff missing in between.
- After all that, it appears to allocate and unallocate memory and
then re-open the clipboard. Is it doing this because the last time it tried it got nothing? Then, because it returned 0000000, it gave up and generated an error?
This I don't know either.
HTH,
Leslie
On Tue, 02 May 2006 09:12:11 -0700, Thomas Hehl wrote:
Please forgive a newbie. I have extensive development background, but am new to wine and, though I've used VB a lot, am somewhat new to API programming.
Welcome! Don't worry, we all started in the same position as you did :)
I have an error while running Pagemaker 7.0 and try to paste text from the clipboard that I put into the clipboard from another app. I tried running with +relay and got a bunch of stuff. I tried +msgbox to find a trace for the message box that's created, but that didn't seem to work for some reason.
It might be generated by the app itself ... if you're sure it's a win32 message box look at the relay trace for MessageBox
- On the line: Call user32.GetClipboardData(00000001) ret=00439e26,
what does the ret mean? Isn't the return value posted later in the log?
Return address, as already said. Can be occasionally helpful, mostly can be ignored. It's posted twice because as you can see even for a relatively simple API a LOT of data can be generated in between. It's just more convenient to have it at that point.
- I haven't found a user32.c and have found many, many hits in the
source for GetClipboardData that I'm trying to sort through? How do I find the source code for that call?
The Wine source tree is a labyrinthe, mostly because it follows the layout of Windows itself. Believe it or not, it used to be far worse. These days nearly all the code for the APIs is under dlls/ so if you know where an API is implemented in Windows then you can find it there.
In this case "user32.GetClipboardData" means it's in user32.dll, which is implemented in dlls/user (a historical quirk, normally they map 1:1)
I navigate the tree by using etags, which plugs into emacs. If you use emacs or vi then etags/ctags can be very handy to jump around the tree. Run "make etags" or "make ctags" (or maybe it's make tags, I forget) in the source root to generate the file.
- Since I haven't found that, I can't verify the type being passed it.
It should be CF_TEXT, but without the source, how do I find the value for that constant?
CF_TEXT is, like all Windows constants, defined in a header file that can be found in the include/ directory. Usually the best way is to use grep or alternatively MSDN will tell you which header file it's probably in.
- It looks like GetClipboardData returned a handle with a value of
796d604a, then it immediately locks this. It then turns around and unlocks it without doing anything, then never uses this handle again. Is this right?
Looks that way. Remember that a relay trace only shows calls into and out of Wines DLLs. The +snoop channel can be used to see calls to/from native DLLS. Also remember that programs can do a ton of work between calls that will never register in the logs. In this case perhaps it's checking the contents of that memory and finding it's not what it expects?
- After all that, it appears to allocate and unallocate memory and then
re-open the clipboard. Is it doing this because the last time it tried it got nothing? Then, because it returned 0000000, it gave up and generated an error?
Could be! To find out why OpenClipboard fails check the traces for that particular function (you can see which one it uses at the top of the relevant source file). It might be that the app didn't CloseClipboard last time for instance.
A word of warning ... this isn't necessarily the cause of the bug. It could be that if GetClipboardData isn't correct that the app is pushed onto a codepath the developers never tested and the failing OpenClipboard call would be the same under Windows. I'm not saying this IS the case, just that it might be.
You'll need to investigate further to find out.
thanks -mike
Thomas Hehl wrote:
- I haven't found a user32.c and have found many, many hits in the
source for GetClipboardData that I'm trying to sort through? How do I find the source code for that call?
I'll just add one other simple method, since others did not mention it. In:
http://source.winehq.org/ident
You can just type in GetClipboardData, and it will find it for you.