1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory 4 * PURPOSE: Test for PrivateExtractIcons 5 * PROGRAMMER: Hermes Belusca-Maito 6 * Doug Lyons <douglyons@douglyons.com> 7 */ 8 9 #include "precomp.h" 10 #include <stdio.h> 11 12 BOOL FileExists(PCWSTR FileName) 13 { 14 DWORD Attribute = GetFileAttributesW(FileName); 15 16 return (Attribute != INVALID_FILE_ATTRIBUTES && 17 !(Attribute & FILE_ATTRIBUTE_DIRECTORY)); 18 } 19 20 BOOL ResourceToFile(INT i, PCWSTR FileName) 21 { 22 FILE *fout; 23 HGLOBAL hData; 24 HRSRC hRes; 25 PVOID pResLock; 26 UINT iSize; 27 28 if (FileExists(FileName)) 29 { 30 /* We should only be using %temp% paths, so deleting here should be OK */ 31 printf("Deleting '%S' that already exists.\n", FileName); 32 DeleteFileW(FileName); 33 } 34 35 hRes = FindResourceW(NULL, MAKEINTRESOURCEW(i), MAKEINTRESOURCEW(RT_RCDATA)); 36 if (hRes == NULL) 37 { 38 skip("Could not locate resource (%d). Exiting now\n", i); 39 return FALSE; 40 } 41 42 iSize = SizeofResource(NULL, hRes); 43 44 hData = LoadResource(NULL, hRes); 45 if (hData == NULL) 46 { 47 skip("Could not load resource (%d). Exiting now\n", i); 48 return FALSE; 49 } 50 51 // Lock the resource into global memory. 52 pResLock = LockResource(hData); 53 if (pResLock == NULL) 54 { 55 skip("Could not lock resource (%d). Exiting now\n", i); 56 return FALSE; 57 } 58 59 fout = _wfopen(FileName, L"wb"); 60 fwrite(pResLock, iSize, 1, fout); 61 fclose(fout); 62 return TRUE; 63 } 64 65 static struct 66 { 67 PCWSTR FilePath; 68 UINT cIcons; // Return value of the first icon group extracted (should be 1 if no error) 69 UINT cTotalIcons; // Return value of total icon groups in file 70 BOOL bhIconValid; // Whether or not the returned icon handle is not NULL. 71 } IconTests[] = 72 { 73 /* Executables with just one icon group */ 74 {L"notepad.exe", 1, 1, TRUE}, 75 {L"%SystemRoot%\\System32\\cmd.exe", 1, 1, TRUE}, 76 77 /* Executable without icon groups */ 78 {L"%SystemRoot%\\System32\\autochk.exe", 0, 0, FALSE}, 79 80 /* Existing file (shell32 has 233 icon groups in ReactOS only) */ 81 {L"%SystemRoot%\\System32\\shell32.dll", 1, 233, TRUE}, 82 83 /* Non-existing files */ 84 {L"%SystemRoot%\\non-existent-file.sdf", 0xFFFFFFFF, 0, FALSE}, 85 86 /* Executable with 18 icon groups */ 87 {L"%SystemRoot%\\explorer.exe", 1, 18, TRUE}, 88 89 /* Icon group file containing 6 icons */ 90 {L"%temp%\\sysicon.ico", 1, 1, TRUE}, 91 92 /* Icon group file containing one PNG icon and one normal icon */ 93 {L"%temp%\\ROS.ico", 1, 1, TRUE}, 94 95 /* Executable file with bad 'Icon Group' but good 'Icons'. 96 * Windows explorer shows the program's icon correctly in WinXP/Win2K3 97 * but Windows 7 shows only a default icon. This is analogous 98 * to EXE's generated by older Watcom C/C++ versions. */ 99 {L"%temp%\\cpimg2e.exe", 1, 1, TRUE}, 100 }; 101 102 static struct 103 { 104 PCWSTR FileName; 105 INT ResourceId; 106 } IconFiles[] = 107 { 108 {L"%temp%\\ROS.ico", IDR_ICONS_PNG}, 109 {L"%temp%\\sysicon.ico", IDR_ICONS_NORMAL}, 110 {L"%temp%\\cpimg2e.exe", IDR_EXE_NORMAL} 111 }; 112 113 START_TEST(PrivateExtractIcons) 114 { 115 HICON ahIcon; 116 UINT i, aIconId, cIcons, cIcoTotal; 117 WCHAR PathBuffer[MAX_PATH]; 118 119 /* Extract icons */ 120 for (i = 0; i < _countof(IconFiles); ++i) 121 { 122 ExpandEnvironmentStringsW(IconFiles[i].FileName, PathBuffer, _countof(PathBuffer)); 123 124 if (!ResourceToFile(IconFiles[i].ResourceId, PathBuffer)) 125 goto Cleanup; 126 } 127 128 for (i = 0; i < _countof(IconTests); ++i) 129 { 130 /* Get total number of icon groups in file. 131 * None of the hard numbers in the function matter since we have 132 * two NULLs for the Icon Handle and Count to be set. */ 133 cIcoTotal = PrivateExtractIconsW(IconTests[i].FilePath, 0, 16, 16, NULL, NULL, 0, 0); 134 ok((i == 3 ? 135 cIcoTotal > 232 && cIcoTotal < 240 : /* shell32 case: ROS has 233, W2K2SP2 has 239 icon groups. */ 136 cIcoTotal == IconTests[i].cTotalIcons), 137 "PrivateExtractIconsW(%u): " 138 "got %u, expected %u\n", i, cIcoTotal, IconTests[i].cTotalIcons); 139 140 /* Always test extraction of the FIRST icon (index 0) */ 141 ahIcon = (HICON)UlongToHandle(0xdeadbeef); 142 aIconId = 0xdeadbeef; 143 cIcons = PrivateExtractIconsW(IconTests[i].FilePath, 0, 16, 16, &ahIcon, &aIconId, 1, 0); 144 ok(cIcons == IconTests[i].cIcons, "PrivateExtractIconsW(%u): got %u, expected %u\n", i, cIcons, IconTests[i].cIcons); 145 ok(ahIcon != (HICON)UlongToHandle(0xdeadbeef), "PrivateExtractIconsW(%u): icon not set\n", i); 146 ok((IconTests[i].bhIconValid && ahIcon) || (!IconTests[i].bhIconValid && !ahIcon), 147 "PrivateExtractIconsW(%u): icon expected to be %s, but got 0x%p\n", 148 i, IconTests[i].bhIconValid ? "valid" : "not valid", ahIcon); 149 if (cIcons == 0xFFFFFFFF) 150 { 151 ok(aIconId == 0xdeadbeef, 152 "PrivateExtractIconsW(%u): id should not be set to 0x%x\n", 153 i, aIconId); 154 } 155 else 156 { 157 ok(aIconId != 0xdeadbeef, "PrivateExtractIconsW(%u): id not set\n", i); 158 } 159 if (ahIcon && ahIcon != (HICON)UlongToHandle(0xdeadbeef)) 160 DestroyIcon(ahIcon); 161 } 162 163 Cleanup: 164 for (i = 0; i < _countof(IconFiles); ++i) 165 { 166 ExpandEnvironmentStringsW(IconFiles[i].FileName, PathBuffer, _countof(PathBuffer)); 167 DeleteFileW(PathBuffer); 168 } 169 } 170