[ros-dev] DCE problem

James Tabor jimtabor.rosdev at gmail.com
Fri May 16 04:22:07 CEST 2008

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.

More information about the Ros-dev mailing list