From: Denis Malikov Subject: [PATCH v2] comctl32/imagelist: fix ImageList_Read/Write. Message-Id: <1529592821.292012986@f318.i.mail.ru> Date: Thu, 21 Jun 2018 17:53:41 +0300 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 --- dlls/comctl32/imagelist.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c index a08d60752e..eadbf134b4 100644 --- a/dlls/comctl32/imagelist.c +++ b/dlls/comctl32/imagelist.c @@ -80,9 +80,11 @@ struct _IMAGELIST BOOL color_table_set; LONG ref; /* reference count */ + USHORT usVersion; /* keep stream version here */ }; #define IMAGELIST_MAGIC 0x53414D58 +#define IMAGELIST_VERSION 0x101 /* Header used by ImageList_Read() and ImageList_Write() */ #include "pshpack2.h" @@ -806,6 +808,7 @@ ImageList_Create (INT cx, INT cy, UINT flags, himl->clrFg = CLR_DEFAULT; himl->clrBk = CLR_NONE; himl->color_table_set = FALSE; + himl->usVersion = 0; /* initialize overlay mask indices */ for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++) @@ -2267,7 +2270,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 != IMAGELIST_VERSION && + 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", @@ -2277,6 +2282,9 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm) if (!himl) return NULL; + /* keep version from stream */ + himl->usVersion = ilHead.usVersion; + if (!(image_bits = read_bitmap(pstm, image_info))) { WARN("failed to read bitmap from stream\n"); @@ -2296,23 +2304,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 != IMAGELIST_VERSION ? himl->cx : image_info->bmiHeader.biWidth); + int image_step = ilHead.usVersion != IMAGELIST_VERSION ? 1 : TILE_COUNT; + int mask_step = ilHead.usVersion != IMAGELIST_VERSION ? 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 -- 2.16.2.windows.1