[PATCH v3] comctl32/imagelist: fix ImageList_Read

Nikolay Sivov nsivov at codeweavers.com
Thu Jul 5 10:48:26 CDT 2018


On 06/25/2018 04:27 PM, Denis Malikov wrote:

> Fix for versions x600 and x620 and pointer calculation for mixing image and mask bits.
>
> Tested on *.reg files extracted from:
>   - XP/2003 key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\TrayNotify;
>   - Vista/7 key HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify
>
> Signed-off-by: Denis Malikov <mdn40000 at mail.ru>
> ---
>   dlls/comctl32/imagelist.c | 16 ++++++++++------
>   1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
> index a08d60752e..be901462a0 100644
> --- a/dlls/comctl32/imagelist.c
> +++ b/dlls/comctl32/imagelist.c
> @@ -2267,7 +2267,9 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
>   	return NULL;
>       if (ilHead.usMagic != (('L' << 8) | 'I'))
>   	return NULL;
> -    if (ilHead.usVersion != 0x101) /* probably version? */
> +    if (ilHead.usVersion != 0x101 &&
> +        ilHead.usVersion != 0x600 && /* XP/2003 version */
> +        ilHead.usVersion != 0x620)   /* Vista/7 version */
>   	return NULL;
>   
>       TRACE("cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n",
> @@ -2296,23 +2298,25 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
>       {
>           DWORD *ptr = image_bits;
>           BYTE *mask_ptr = mask_bits;
> -        int stride = himl->cy * image_info->bmiHeader.biWidth;
> +        int stride = himl->cy * (ilHead.usVersion != 0x101 ? himl->cx : image_info->bmiHeader.biWidth);
> +        int image_step = ilHead.usVersion != 0x101 ? 1 : TILE_COUNT;
> +        int mask_step = ilHead.usVersion != 0x101 ? 4 : 8;
>   
>           if (image_info->bmiHeader.biHeight > 0)  /* bottom-up */
>           {
>               ptr += image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride;
> -            mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / 8;
> +            mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / mask_step;
>               stride = -stride;
>               image_info->bmiHeader.biHeight = himl->cy;
>           }
>           else image_info->bmiHeader.biHeight = -himl->cy;
>   
> -        for (i = 0; i < ilHead.cCurImage; i += TILE_COUNT)
> +        for (i = 0; i < ilHead.cCurImage; i += image_step)
>           {
> -            add_dib_bits( himl, i, min( ilHead.cCurImage - i, TILE_COUNT ),
> +            add_dib_bits( himl, i, min( ilHead.cCurImage - i, image_step ),
>                             himl->cx, himl->cy, image_info, mask_info, ptr, mask_ptr );
>               ptr += stride;
> -            mask_ptr += stride / 8;
> +            mask_ptr += stride / mask_step;
>           }
>       }
>       else

I think that it's possible 'else' branch also needs adjusting, when 
something else than ILC_COLOR32 is used. I'm not sure if we have a test 
for it, something like "Create -> Save -> check stream output".



More information about the wine-devel mailing list