2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Test for SHCreateFileExtractIconW
5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
11 ULONG
DbgPrint(PCH Format
,...);
12 #include <shellutils.h>
17 HRESULT (STDAPICALLTYPE
*pSHCreateFileExtractIconW
)(LPCWSTR pszFile
, DWORD dwFileAttributes
, REFIID riid
, void **ppv
);
25 static test_data Tests
[] =
27 { L
"xxx.zip", FILE_ATTRIBUTE_NORMAL
},
28 { L
"xxx.zip", FILE_ATTRIBUTE_DIRECTORY
},
29 { L
"xxx.exe", FILE_ATTRIBUTE_NORMAL
},
30 { L
"xxx.exe", FILE_ATTRIBUTE_DIRECTORY
},
31 { L
"xxx.dll", FILE_ATTRIBUTE_NORMAL
},
32 { L
"xxx.dll", FILE_ATTRIBUTE_DIRECTORY
},
33 { L
"xxx.txt", FILE_ATTRIBUTE_NORMAL
},
34 { L
"xxx.txt", FILE_ATTRIBUTE_DIRECTORY
},
35 { NULL
, FILE_ATTRIBUTE_NORMAL
},
36 { NULL
, FILE_ATTRIBUTE_DIRECTORY
},
40 static void ExtractOneBitmap(HBITMAP hbm
, CComHeapPtr
<BYTE
>& data
, DWORD
& size
)
42 HDC hdc
= CreateCompatibleDC(NULL
);
43 HGDIOBJ obj
= SelectObject(hdc
, hbm
);
45 CComHeapPtr
<BITMAPINFO
> pInfoBM
;
47 pInfoBM
.AllocateBytes(sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
48 memset(pInfoBM
, 0, sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
49 pInfoBM
->bmiHeader
.biSize
= sizeof(pInfoBM
->bmiHeader
);
50 if (!GetDIBits(hdc
, hbm
, 0, 0, NULL
, pInfoBM
, DIB_RGB_COLORS
))
53 size
= pInfoBM
->bmiHeader
.biSizeImage
;
55 GetDIBits(hdc
, hbm
, 0, pInfoBM
->bmiHeader
.biHeight
, data
, pInfoBM
, DIB_RGB_COLORS
);
57 SelectObject(hdc
, obj
);
61 static bool GetIconData(HICON icon
, CComHeapPtr
<BYTE
>& colorData
, DWORD
& colorSize
, CComHeapPtr
<BYTE
>& maskData
, DWORD
& maskSize
)
65 if (!GetIconInfo(icon
, &iconinfo
))
68 ExtractOneBitmap(iconinfo
.hbmColor
, colorData
, colorSize
);
69 ExtractOneBitmap(iconinfo
.hbmMask
, maskData
, maskSize
);
71 DeleteObject(iconinfo
.hbmColor
);
72 DeleteObject(iconinfo
.hbmMask
);
78 START_TEST(SHCreateFileExtractIconW
)
80 WCHAR CurrentModule
[MAX_PATH
];
81 HMODULE shell32
= LoadLibraryA("shell32.dll");
83 pSHCreateFileExtractIconW
= (HRESULT (__stdcall
*)(LPCWSTR
, DWORD
, REFIID
, void **))GetProcAddress(shell32
, "SHCreateFileExtractIconW");
87 GetModuleFileNameW(NULL
, CurrentModule
, _countof(CurrentModule
));
90 ULONG_PTR firet
= SHGetFileInfoW(CurrentModule
, 0, &shfi
, sizeof(shfi
), SHGFI_ICON
);
94 skip("Unable to get my own icon\n");
99 if (!pSHCreateFileExtractIconW
)
101 skip("SHCreateFileExtractIconW not available\n");
105 for (size_t n
= 0; n
< _countof(Tests
); ++n
)
107 test_data
& cur
= Tests
[n
];
108 bool useMyIcon
= false;
110 if (cur
.Name
== NULL
)
112 cur
.Name
= CurrentModule
;
116 CComPtr
<IExtractIconW
> spExtract
;
117 HRESULT hr
= pSHCreateFileExtractIconW(cur
.Name
, cur
.dwFlags
, IID_PPV_ARG(IExtractIconW
, &spExtract
));
118 ok(hr
== S_OK
, "Expected hr to be S_OK, was 0x%lx for %S(%lx)\n", hr
, cur
.Name
, cur
.dwFlags
);
124 UINT wFlags
= 0xdeaddead;
125 WCHAR Buffer
[MAX_PATH
];
127 hr
= spExtract
->GetIconLocation(0, Buffer
, _countof(Buffer
), &ilIndex
, &wFlags
);
128 ok(hr
== S_OK
, "Expected hr to be S_OK, was 0x%lx for %S(%lx)\n", hr
, cur
.Name
, cur
.dwFlags
);
132 ok(wFlags
& (GIL_NOTFILENAME
|GIL_PERCLASS
), "Expected GIL_NOTFILENAME|GIL_PERCLASS to be set for %S(%lx)\n", cur
.Name
, cur
.dwFlags
);
133 ok(!wcscmp(Buffer
, L
"*"), "Expected '*', was '%S' for %S(%lx)\n", Buffer
, cur
.Name
, cur
.dwFlags
);
136 hr
= spExtract
->Extract(Buffer
, ilIndex
, &ico
, NULL
, 0);
138 /* Visualize the icon extracted for whoever is stepping through this code. */
139 HWND console
= GetConsoleWindow();
140 SendMessage(console
, WM_SETICON
, ICON_BIG
, (LPARAM
)ico
);
141 SendMessage(console
, WM_SETICON
, ICON_SMALL
, (LPARAM
)ico
);
143 CComHeapPtr
<BYTE
> colorData
, maskData
;
144 DWORD colorSize
= 0, maskSize
= 0;
146 GetIconData(ico
, colorData
, colorSize
, maskData
, maskSize
);
148 if (!colorSize
|| !maskSize
)
152 ULONG_PTR firet
= SHGetFileInfoW(cur
.Name
, cur
.dwFlags
, &shfi
, sizeof(shfi
), SHGFI_USEFILEATTRIBUTES
| SHGFI_ICON
);
157 CComHeapPtr
<BYTE
> colorDataRef
, maskDataRef
;
158 DWORD colorSizeRef
= 0, maskSizeRef
= 0;
159 GetIconData(shfi
.hIcon
, colorDataRef
, colorSizeRef
, maskDataRef
, maskSizeRef
);
161 ok(colorSizeRef
== colorSize
, "Expected %lu, was %lu for %S(%lx)\n", colorSizeRef
, colorSize
, cur
.Name
, cur
.dwFlags
);
162 ok(maskSizeRef
== maskSize
, "Expected %lu, was %lu for %S(%lx)\n", maskSizeRef
, maskSize
, cur
.Name
, cur
.dwFlags
);
164 if (colorSizeRef
== colorSize
)
166 ok(!memcmp(colorData
, colorDataRef
, colorSize
), "Expected equal colorData for %S(%lx)\n", cur
.Name
, cur
.dwFlags
);
169 if (maskSizeRef
== maskSize
)
171 ok(!memcmp(maskData
, maskDataRef
, maskSize
), "Expected equal maskData for %S(%lx)\n", cur
.Name
, cur
.dwFlags
);
178 colorSizeRef
= maskSizeRef
= 0;
179 GetIconData(myIcon
, colorDataRef
, colorSizeRef
, maskDataRef
, maskSizeRef
);
181 ok(colorSizeRef
== colorSize
, "Expected %lu, was %lu for %S(%lx)\n", colorSizeRef
, colorSize
, cur
.Name
, cur
.dwFlags
);
182 ok(maskSizeRef
== maskSize
, "Expected %lu, was %lu for %S(%lx)\n", maskSizeRef
, maskSize
, cur
.Name
, cur
.dwFlags
);
184 if (colorSizeRef
== colorSize
)
186 /* Incase requested filetype does not match, the exe icon is not used! */
187 if (cur
.dwFlags
== FILE_ATTRIBUTE_DIRECTORY
)
189 ok(memcmp(colorData
, colorDataRef
, colorSize
), "Expected colorData to be changed for %S(%lx)\n", cur
.Name
, cur
.dwFlags
);
193 ok(!memcmp(colorData
, colorDataRef
, colorSize
), "Expected equal colorData for %S(%lx)\n", cur
.Name
, cur
.dwFlags
);
197 // Mask is not reliable for some reason
198 //if (maskSizeRef == maskSize)
200 // ok(!memcmp(maskData, maskDataRef, maskSize), "Expected equal maskData for %S(%lx)\n", cur.Name, cur.dwFlags);