Hi, I thought it was a handle management problem but it seems to be just a GetDC one. I found out when a pOWNED dc or dc owned by a window or window class after the first GetDC the DCX_CACHE bit become set. This is wrong behavior. Our UserGetDCEx code is a hodgepodge of wine and poorly RE, coded by the original authors and does not comply with known semantics. Sorry I guess? Well~ still rewriting it has become a headache for me and I guess I'm asking for help. I have attempted more than twice to rewrite it with porting wine code, etc. All ended in major crashes, thus validating my claim, if you write code based on bad code you end up with more bad code.
Using wine testing, Use32 dce test, everything works upto line 93.
hdc = GetDC( hwnd_owndc ); <----------------- first GetDC call SetROP2( hdc, R2_WHITE ); rop = GetROP2( hdc ); ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop );
old_hdc = hdc; ReleaseDC( hwnd_owndc, hdc ); <---------------------- first ReleaseDC hdc = GetDC( hwnd_owndc ); <---------------------------2nd GetDC ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc ); rop = GetROP2( hdc ); -> ok( rop == R2_WHITE, "wrong ROP2 %d after release\n", rop ); ReleaseDC( hwnd_owndc, hdc ); rop = GetROP2( hdc ); ok( rop == R2_WHITE, "wrong ROP2 %d after second release\n", rop );
After the first GetDC the DC is cached by setting bit DCX_CACHE and this is wrong (BUG) since this DC is owned by a window. The second GetDC is called and the DC is now a DCX_CACHE. The original data is now lost due to the first ReleaseDC freeing DC_ATTR, thus normal behavior for this type of DC with DCX_CACHE set. This results in the failure at line 93 with the data in the DC_ATTR is set to a CleanDC state. This is correct for DCX_CACHE'ed DC but not for DCX_WINDOW DC. DCX_WINDOW DCs keep the original DC_ATTR data and it is not freed after a ReleaseDC call. The same goes on with class DC tests.
The BUG is in UserGetDCEx, the freeing and allocating DC_ATTR is correct but somewhere the DCX_CACHE bit get set and that should not happen for window/class owned DCs.
I hope this clears it up.
I need someone with fresh eyes to help us fix this. Thanks, James