Reactos

[SHELL32_APITEST] Add test for SHCreateFileExtractIconW CORE-14082

+213
modules/rostests/apitests/shell32/1.ico

This is a binary file and will not be displayed.

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