From: Dmitry Timoshkov
"Ge van Geldorp" ge@gse.nl wrote:
Another idea just popped up: the basic problem we're having is translating the handle passed in to a table containing the accelerator entries. How about using CopyAcceleratorTableA/W to do that? This function is designed to do that job and is located in user32. That dll is not shared between Wine and ReactOS anyway, so we can mess around in it anyway we like without disturbing Wine.
IMHO it would be much better to fix LoadAcceleratorsA/W and avoid to use LockResource16 at all in all callers in Wine. Yes, it's slightly more work, but that's a usual case with all Wine bugs.
Just to be sure: if I understand you correctly you suggest doing the LockResource16 in LoadAcceleratorsA/W, then GlobalAlloc a new block of memory, copy the table to the new block and return the global memory handle as the HACCEL. Then in IsAccelerator use GlobalLock to get at the contents. Please correct me if I'm wrong.
Doesn't that still violate DLL separation? Ole32.dll "knows" that a HACCEL is actually a HGLOBAL and even "knows" how the accelerator table is stored internally. IMHO that stuff should only be known to user32. Put another way: if you run the proposed ole32 IsAccelerator code on MS Windows it would fail. Using CopyAcceleratorTable (a user32 function) fixes this, knowledge of the internal structure is limited to user32. Incidentally, MS ole32 (NT4/2K/XP) imports CopyAcceleratorTableW.
Somewhat to my surprise, it turns out that HACCEL handles can be shared between processes. I've attached a simple test program which uses an accelerator table with one entry, for the Alt-T key. Pressing Alt-T while the programs window has input focus displays a message box. If you run this program for the first time, the accelerator table is loaded from a resource. It will display the handle in hex. While the program is still running, start it a second time, with the 8 hex-digit handle as command line argument. The second copy will then use that number as the HACCEL to pass to IsAccelerator, without loading a new accelerator table. When running on NT4/2K/XP the second instance will also flag Alt-T as an accelerator. If you close the first instance (destroying the accelerator table it loaded) the second instance will no longer flag Alt-T as an accelerator.
I guess this means that at some point the accelerator implementation should be moved to the server. When that happens HACCEL can no longer be a HGLOBAL and as a result the code making that assumption in ole32 will cease working. Why not fix the ole32 code right away to use CopyAcceleratorTable? Obviously CopyAcceleratorTable itself will have to be changed when the implementation is moved, but that needs to be done anyhow.
So, my vote still is for the CopyAcceleratorTable approach.
Ge van Geldorp.