[SHELL32_APITEST] Rename TestShellFolder, test_data and Tests. #179
[reactos.git] / modules / rostests / apitests / shell32 / SHCreateFileExtractIconW.cpp
1 /*
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)
6 */
7
8 #include "shelltest.h"
9
10 #include <wincon.h>
11 #include <wingdi.h>
12
13 ULONG DbgPrint(PCH Format,...);
14 #include <shellutils.h>
15
16 HRESULT (STDAPICALLTYPE *pSHCreateFileExtractIconW)(LPCWSTR pszFile, DWORD dwFileAttributes, REFIID riid, void **ppv);
17
18 struct TestData
19 {
20 const WCHAR* Name;
21 DWORD dwFlags;
22 };
23
24 static TestData IconTests[] =
25 {
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 },
36 };
37
38
39 static void ExtractOneBitmap(HBITMAP hbm, CComHeapPtr<BYTE>& data, DWORD& size)
40 {
41 HDC hdc = CreateCompatibleDC(NULL);
42 HGDIOBJ obj = SelectObject(hdc, hbm);
43
44 CComHeapPtr<BITMAPINFO> pInfoBM;
45
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))
50 return;
51
52 size = pInfoBM->bmiHeader.biSizeImage;
53 data.Allocate(size);
54 GetDIBits(hdc, hbm, 0, pInfoBM->bmiHeader.biHeight, data, pInfoBM, DIB_RGB_COLORS);
55
56 SelectObject(hdc, obj);
57 DeleteDC(hdc);
58 }
59
60 static bool GetIconData(HICON icon, CComHeapPtr<BYTE>& colorData, DWORD& colorSize, CComHeapPtr<BYTE>& maskData, DWORD& maskSize)
61 {
62 ICONINFO iconinfo;
63
64 if (!GetIconInfo(icon, &iconinfo))
65 return false;
66
67 ExtractOneBitmap(iconinfo.hbmColor, colorData, colorSize);
68 ExtractOneBitmap(iconinfo.hbmMask, maskData, maskSize);
69
70 DeleteObject(iconinfo.hbmColor);
71 DeleteObject(iconinfo.hbmMask);
72
73 return true;
74 }
75
76
77 START_TEST(SHCreateFileExtractIconW)
78 {
79 WCHAR CurrentModule[MAX_PATH];
80 HMODULE shell32 = LoadLibraryA("shell32.dll");
81 HICON myIcon;
82 pSHCreateFileExtractIconW = (HRESULT (__stdcall *)(LPCWSTR, DWORD, REFIID, void **))GetProcAddress(shell32, "SHCreateFileExtractIconW");
83
84 CoInitialize(NULL);
85
86 GetModuleFileNameW(NULL, CurrentModule, _countof(CurrentModule));
87 {
88 SHFILEINFOW shfi;
89 ULONG_PTR firet = SHGetFileInfoW(CurrentModule, 0, &shfi, sizeof(shfi), SHGFI_ICON);
90 myIcon = shfi.hIcon;
91 if (!firet)
92 {
93 skip("Unable to get my own icon\n");
94 return;
95 }
96 }
97
98 if (!pSHCreateFileExtractIconW)
99 {
100 skip("SHCreateFileExtractIconW not available\n");
101 return;
102 }
103
104 for (size_t n = 0; n < _countof(IconTests); ++n)
105 {
106 TestData& cur = IconTests[n];
107 bool useMyIcon = false;
108
109 if (cur.Name == NULL)
110 {
111 cur.Name = CurrentModule;
112 useMyIcon = true;
113 }
114
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);
118
119 if (!SUCCEEDED(hr))
120 continue;
121
122 int ilIndex = -1;
123 UINT wFlags = 0xdeaddead;
124 WCHAR Buffer[MAX_PATH];
125
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);
128 if (!SUCCEEDED(hr))
129 continue;
130
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);
133
134 HICON ico;
135 hr = spExtract->Extract(Buffer, ilIndex, &ico, NULL, 0);
136
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);
141
142 CComHeapPtr<BYTE> colorData, maskData;
143 DWORD colorSize = 0, maskSize = 0;
144
145 GetIconData(ico, colorData, colorSize, maskData, maskSize);
146
147 if (!colorSize || !maskSize)
148 continue;
149
150 SHFILEINFOW shfi;
151 ULONG_PTR firet = SHGetFileInfoW(cur.Name, cur.dwFlags, &shfi, sizeof(shfi), SHGFI_USEFILEATTRIBUTES | SHGFI_ICON);
152
153 if (!firet)
154 continue;
155
156 CComHeapPtr<BYTE> colorDataRef, maskDataRef;
157 DWORD colorSizeRef = 0, maskSizeRef = 0;
158 GetIconData(shfi.hIcon, colorDataRef, colorSizeRef, maskDataRef, maskSizeRef);
159
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);
162
163 if (colorSizeRef == colorSize)
164 {
165 ok(!memcmp(colorData, colorDataRef, colorSize), "Expected equal colorData for %S(%lx)\n", cur.Name, cur.dwFlags);
166 }
167
168 if (maskSizeRef == maskSize)
169 {
170 ok(!memcmp(maskData, maskDataRef, maskSize), "Expected equal maskData for %S(%lx)\n", cur.Name, cur.dwFlags);
171 }
172
173 if (useMyIcon)
174 {
175 colorDataRef.Free();
176 maskDataRef.Free();
177 colorSizeRef = maskSizeRef = 0;
178 GetIconData(myIcon, colorDataRef, colorSizeRef, maskDataRef, maskSizeRef);
179
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);
182
183 if (colorSizeRef == colorSize)
184 {
185 /* Incase requested filetype does not match, the exe icon is not used! */
186 if (cur.dwFlags == FILE_ATTRIBUTE_DIRECTORY)
187 {
188 ok(memcmp(colorData, colorDataRef, colorSize), "Expected colorData to be changed for %S(%lx)\n", cur.Name, cur.dwFlags);
189 }
190 else
191 {
192 ok(!memcmp(colorData, colorDataRef, colorSize), "Expected equal colorData for %S(%lx)\n", cur.Name, cur.dwFlags);
193 }
194 }
195
196 // Mask is not reliable for some reason
197 //if (maskSizeRef == maskSize)
198 //{
199 // ok(!memcmp(maskData, maskDataRef, maskSize), "Expected equal maskData for %S(%lx)\n", cur.Name, cur.dwFlags);
200 //}
201 }
202 }
203 }