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)
13 ULONG
DbgPrint(PCH Format
,...);
14 #include <shellutils.h>
16 HRESULT (STDAPICALLTYPE
*pSHCreateFileExtractIconW
)(LPCWSTR pszFile
, DWORD dwFileAttributes
, REFIID riid
, void **ppv
);
24 static TestData IconTests
[] =
26 { L
"xxx.zip", FILE_ATTRIBUTE_NORMAL
},
27 { L
"xxx.zip", FILE_ATTRIBUTE_DIRECTORY
},
28 { L
"xxx.exe", FILE_ATTRIBUTE_NORMAL
},
29 { L
"xxx.exe", FILE_ATTRIBUTE_DIRECTORY
},
30 { L
"xxx.dll", FILE_ATTRIBUTE_NORMAL
},
31 { L
"xxx.dll", FILE_ATTRIBUTE_DIRECTORY
},
32 { L
"xxx.txt", FILE_ATTRIBUTE_NORMAL
},
33 { L
"xxx.txt", FILE_ATTRIBUTE_DIRECTORY
},
34 { NULL
, FILE_ATTRIBUTE_NORMAL
},
35 { NULL
, FILE_ATTRIBUTE_DIRECTORY
},
39 static void ExtractOneBitmap(HBITMAP hbm
, CComHeapPtr
<BYTE
>& data
, DWORD
& size
)
41 HDC hdc
= CreateCompatibleDC(NULL
);
42 HGDIOBJ obj
= SelectObject(hdc
, hbm
);
44 CComHeapPtr
<BITMAPINFO
> pInfoBM
;
46 pInfoBM
.AllocateBytes(sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
47 memset(pInfoBM
, 0, sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
48 pInfoBM
->bmiHeader
.biSize
= sizeof(pInfoBM
->bmiHeader
);
49 if (!GetDIBits(hdc
, hbm
, 0, 0, NULL
, pInfoBM
, DIB_RGB_COLORS
))
52 size
= pInfoBM
->bmiHeader
.biSizeImage
;
54 GetDIBits(hdc
, hbm
, 0, pInfoBM
->bmiHeader
.biHeight
, data
, pInfoBM
, DIB_RGB_COLORS
);
56 SelectObject(hdc
, obj
);
60 static bool GetIconData(HICON icon
, CComHeapPtr
<BYTE
>& colorData
, DWORD
& colorSize
, CComHeapPtr
<BYTE
>& maskData
, DWORD
& maskSize
)
64 if (!GetIconInfo(icon
, &iconinfo
))
67 ExtractOneBitmap(iconinfo
.hbmColor
, colorData
, colorSize
);
68 ExtractOneBitmap(iconinfo
.hbmMask
, maskData
, maskSize
);
70 DeleteObject(iconinfo
.hbmColor
);
71 DeleteObject(iconinfo
.hbmMask
);
77 START_TEST(SHCreateFileExtractIconW
)
79 WCHAR CurrentModule
[MAX_PATH
];
80 HMODULE shell32
= LoadLibraryA("shell32.dll");
82 pSHCreateFileExtractIconW
= (HRESULT (__stdcall
*)(LPCWSTR
, DWORD
, REFIID
, void **))GetProcAddress(shell32
, "SHCreateFileExtractIconW");
86 GetModuleFileNameW(NULL
, CurrentModule
, _countof(CurrentModule
));
89 ULONG_PTR firet
= SHGetFileInfoW(CurrentModule
, 0, &shfi
, sizeof(shfi
), SHGFI_ICON
);
93 skip("Unable to get my own icon\n");
98 if (!pSHCreateFileExtractIconW
)
100 skip("SHCreateFileExtractIconW not available\n");
104 for (size_t n
= 0; n
< _countof(IconTests
); ++n
)
106 TestData
& cur
= IconTests
[n
];
107 bool useMyIcon
= false;
109 if (cur
.Name
== NULL
)
111 cur
.Name
= CurrentModule
;
115 CComPtr
<IExtractIconW
> spExtract
;
116 HRESULT hr
= pSHCreateFileExtractIconW(cur
.Name
, cur
.dwFlags
, IID_PPV_ARG(IExtractIconW
, &spExtract
));
117 ok(hr
== S_OK
, "Expected hr to be S_OK, was 0x%lx for %S(%lx)\n", hr
, cur
.Name
, cur
.dwFlags
);
123 UINT wFlags
= 0xdeaddead;
124 WCHAR Buffer
[MAX_PATH
];
126 hr
= spExtract
->GetIconLocation(0, Buffer
, _countof(Buffer
), &ilIndex
, &wFlags
);
127 ok(hr
== S_OK
, "Expected hr to be S_OK, was 0x%lx for %S(%lx)\n", hr
, cur
.Name
, cur
.dwFlags
);
131 ok(wFlags
& (GIL_NOTFILENAME
|GIL_PERCLASS
), "Expected GIL_NOTFILENAME|GIL_PERCLASS to be set for %S(%lx)\n", cur
.Name
, cur
.dwFlags
);
132 ok(!wcscmp(Buffer
, L
"*"), "Expected '*', was '%S' for %S(%lx)\n", Buffer
, cur
.Name
, cur
.dwFlags
);
135 hr
= spExtract
->Extract(Buffer
, ilIndex
, &ico
, NULL
, 0);
137 /* Visualize the icon extracted for whoever is stepping through this code. */
138 HWND console
= GetConsoleWindow();
139 SendMessage(console
, WM_SETICON
, ICON_BIG
, (LPARAM
)ico
);
140 SendMessage(console
, WM_SETICON
, ICON_SMALL
, (LPARAM
)ico
);
142 CComHeapPtr
<BYTE
> colorData
, maskData
;
143 DWORD colorSize
= 0, maskSize
= 0;
145 GetIconData(ico
, colorData
, colorSize
, maskData
, maskSize
);
147 if (!colorSize
|| !maskSize
)
151 ULONG_PTR firet
= SHGetFileInfoW(cur
.Name
, cur
.dwFlags
, &shfi
, sizeof(shfi
), SHGFI_USEFILEATTRIBUTES
| SHGFI_ICON
);
156 CComHeapPtr
<BYTE
> colorDataRef
, maskDataRef
;
157 DWORD colorSizeRef
= 0, maskSizeRef
= 0;
158 GetIconData(shfi
.hIcon
, colorDataRef
, colorSizeRef
, maskDataRef
, maskSizeRef
);
160 ok(colorSizeRef
== colorSize
, "Expected %lu, was %lu for %S(%lx)\n", colorSizeRef
, colorSize
, cur
.Name
, cur
.dwFlags
);
161 ok(maskSizeRef
== maskSize
, "Expected %lu, was %lu for %S(%lx)\n", maskSizeRef
, maskSize
, cur
.Name
, cur
.dwFlags
);
163 if (colorSizeRef
== colorSize
)
165 ok(!memcmp(colorData
, colorDataRef
, colorSize
), "Expected equal colorData for %S(%lx)\n", cur
.Name
, cur
.dwFlags
);
168 if (maskSizeRef
== maskSize
)
170 ok(!memcmp(maskData
, maskDataRef
, maskSize
), "Expected equal maskData for %S(%lx)\n", cur
.Name
, cur
.dwFlags
);
177 colorSizeRef
= maskSizeRef
= 0;
178 GetIconData(myIcon
, colorDataRef
, colorSizeRef
, maskDataRef
, maskSizeRef
);
180 ok(colorSizeRef
== colorSize
, "Expected %lu, was %lu for %S(%lx)\n", colorSizeRef
, colorSize
, cur
.Name
, cur
.dwFlags
);
181 ok(maskSizeRef
== maskSize
, "Expected %lu, was %lu for %S(%lx)\n", maskSizeRef
, maskSize
, cur
.Name
, cur
.dwFlags
);
183 if (colorSizeRef
== colorSize
)
185 /* Incase requested filetype does not match, the exe icon is not used! */
186 if (cur
.dwFlags
== FILE_ATTRIBUTE_DIRECTORY
)
188 ok(memcmp(colorData
, colorDataRef
, colorSize
), "Expected colorData to be changed for %S(%lx)\n", cur
.Name
, cur
.dwFlags
);
192 ok(!memcmp(colorData
, colorDataRef
, colorSize
), "Expected equal colorData for %S(%lx)\n", cur
.Name
, cur
.dwFlags
);
196 // Mask is not reliable for some reason
197 //if (maskSizeRef == maskSize)
199 // ok(!memcmp(maskData, maskDataRef, maskSize), "Expected equal maskData for %S(%lx)\n", cur.Name, cur.dwFlags);