Hi Alexandre,

On Mon, 31 Jan 2011, Alexandre Julliard wrote:

And: from a design perspective it sounds very strange that a fast
track optimisation *silently* changes protection bits!

There's nothing silent about it, the protection bits have to match the
DIB state.

Hmm. In which way changes StretchDIBits() the DIB state? Or: why should be a DIB, that is created using CreateDIBSection() as READWRITE, silently change it's state into READONLY? (At least, msdn-docs don't tell me anything about that... Can you provide me with a link? )

But, let's say for a moment, that this is true and the right(tm) behaviour:

Then create_alpha_bitmap() (within user32/cursoricon.c) seems to be broken.

It does the following:

* create a DIBSection

  alpha = CreateDIBSection( hdc, info, DIB_RGB_COLORS, &bits, NULL, 0)

* here we can savely expect bits to be writable (at least the
  msdn-documentation says so)

* in certain cases (if we are provided with a src_info-pointer), we do
  now:

  StretchDIBits( hdc, 0, 0, bm.bmWidth, bm.bmHeight,
                 0, 0, src_info->bmiHeader.biWidth,
                 src_info->bmiHeader.biHeight,
                 color_bits, src_info, DIB_RGB_COLORS, SRCCOPY );

* after that, bits is *probably* non-writable (depending on fast path or
  not) (I still find that *really* strange. Again: it depends on certain
  parameters of this function, specifically: if in and out parameters do
  match at enough places, the DIB bitmap *changes* it's state to
  READONLY, in other cases it doesn't. If that isn't a big surprise, what
  is? :) ).

* and here...

    /* pre-multiply by alpha */
    for (i = 0, ptr = bits; i < bm.bmWidth * bm.bmHeight; i++, ptr += 4)
    {
        unsigned int alpha = ptr[3];
        ptr[0] = ptr[0] * alpha / 255;
        ptr[1] = ptr[1] * alpha / 255;
        ptr[2] = ptr[2] * alpha / 255;
    }

* ... we write to the now readonly bits-array, which leads to a page
  fault.

This is everything within wine code, the application only called CreateIconFromResourceEx(), which then called create_alpha_bitmap() (so: no, I don't think, the app is broken :) It only triggered a seldomly used code path within wine. ).

Where is the page fault handler within wine and what should the page fault handler actually do in that situation?

If we can't expect the "bits"-pointer to be writable after a call to StretchDIBs(), create_alpha_bitmap() should be rewritten.

That wouldn't be a problem, if windows behaved exactly the same way.
(which it most likely does not, otherwise PNClient wouldn't crash,
right?).

I wouldn't be surprised if there was a way to crash it on Windows too,
that app is broken, it never gives the code a chance to handle the
exception. This is not how exception handlers are supposed to work.

Well, it doesn't crash on Windows and is actually rock solid there.

And: do you want to say, that there is a page fault handler within wine, that can handle *that* case above?

We either have to rewrite create_alpha_bitmap() in a way, that doesn't call StretchDIBits() in the fast path case and solves problems differently or: we should fix it at the source (which I still think my patch does, since it follows the rules of least surprise...).

In either way, I hope we can agree on the following:

a) the app is *not* broken (at least not regarding it's usage of
   CreateIconFromResourceEx() )
b) wine code *is* broken here
c) we can work around the problem within create_alpha_bitmap() or
d) make StretchDIBits() a function a lot less surprising to call...

Of course this specific issue would be fixed by a DIB engine, but there are
other places where exceptions can happen internally, even on Windows.

At least, they seem to install the handler in such a clever way, that no problems seem to occur within Windows (several different versions). That said: I'd have prefered, if they didn't do that, since it made my debugging session a lot longer...

Are you sure? 0 means: everything is transparent, and that sounds
like: we need an alpha channel, right?

0 means there's no alpha channel, which is what we are checking here.

Ouch! If that is really Windows behaviour, then it is really broken but bug-to-bug compatible :)

Cheers,
Peter

----
Peter Schlaile


Reply via email to