1 /* 2 * Misc tests 3 * 4 * Copyright 2006 Paul Vriens 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "precomp.h" 22 23 static PVOID (WINAPI * pAlloc)(LONG); 24 static PVOID (WINAPI * pReAlloc)(PVOID, LONG); 25 static BOOL (WINAPI * pFree)(PVOID); 26 static LONG (WINAPI * pGetSize)(PVOID); 27 28 static INT (WINAPI * pStr_GetPtrA)(LPCSTR, LPSTR, INT); 29 static BOOL (WINAPI * pStr_SetPtrA)(LPSTR, LPCSTR); 30 static INT (WINAPI * pStr_GetPtrW)(LPCWSTR, LPWSTR, INT); 31 static BOOL (WINAPI * pStr_SetPtrW)(LPWSTR, LPCWSTR); 32 33 static HMODULE hComctl32 = 0; 34 35 static char testicon_data[] = 36 { 37 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 38 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 39 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 40 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x12, 0x0b, 41 0x00, 0x00, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 0x00, 0x00, 0xde, 0xde, 0xde, 0xff, 0xde, 0xde, 0xde, 0xff, 0xde, 0xde, 43 0xde, 0xff, 0xde, 0xde, 0xde, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 0x00, 0x00 45 }; 46 47 #define COMCTL32_GET_PROC(ordinal, func) \ 48 p ## func = (void*)GetProcAddress(hComctl32, (LPSTR)ordinal); \ 49 if(!p ## func) { \ 50 trace("GetProcAddress(%d)(%s) failed\n", ordinal, #func); \ 51 FreeLibrary(hComctl32); \ 52 } 53 54 static BOOL InitFunctionPtrs(void) 55 { 56 hComctl32 = LoadLibraryA("comctl32.dll"); 57 58 if(!hComctl32) 59 { 60 trace("Could not load comctl32.dll\n"); 61 return FALSE; 62 } 63 64 COMCTL32_GET_PROC(71, Alloc); 65 COMCTL32_GET_PROC(72, ReAlloc); 66 COMCTL32_GET_PROC(73, Free); 67 COMCTL32_GET_PROC(74, GetSize); 68 69 COMCTL32_GET_PROC(233, Str_GetPtrA) 70 COMCTL32_GET_PROC(234, Str_SetPtrA) 71 COMCTL32_GET_PROC(235, Str_GetPtrW) 72 COMCTL32_GET_PROC(236, Str_SetPtrW) 73 74 return TRUE; 75 } 76 77 static void test_GetPtrAW(void) 78 { 79 if (pStr_GetPtrA) 80 { 81 static const char source[] = "Just a source string"; 82 static const char desttest[] = "Just a destination string"; 83 static char dest[MAX_PATH]; 84 int sourcelen; 85 int destsize = MAX_PATH; 86 int count; 87 88 sourcelen = strlen(source) + 1; 89 90 count = pStr_GetPtrA(NULL, NULL, 0); 91 ok (count == 0, "Expected count to be 0, it was %d\n", count); 92 93 if (0) 94 { 95 /* Crashes on W98, NT4, W2K, XP, W2K3 96 * Our implementation also crashes and we should probably leave 97 * it like that. 98 */ 99 count = pStr_GetPtrA(NULL, NULL, destsize); 100 trace("count : %d\n", count); 101 } 102 103 count = pStr_GetPtrA(source, NULL, 0); 104 ok (count == sourcelen || 105 broken(count == sourcelen - 1), /* win9x */ 106 "Expected count to be %d, it was %d\n", sourcelen, count); 107 108 strcpy(dest, desttest); 109 count = pStr_GetPtrA(source, dest, 0); 110 ok (count == sourcelen || 111 broken(count == 0), /* win9x */ 112 "Expected count to be %d, it was %d\n", sourcelen, count); 113 ok (!lstrcmpA(dest, desttest) || 114 broken(!lstrcmpA(dest, "")), /* Win7 */ 115 "Expected destination to not have changed\n"); 116 117 count = pStr_GetPtrA(source, NULL, destsize); 118 ok (count == sourcelen || 119 broken(count == sourcelen - 1), /* win9x */ 120 "Expected count to be %d, it was %d\n", sourcelen, count); 121 122 count = pStr_GetPtrA(source, dest, destsize); 123 ok (count == sourcelen || 124 broken(count == sourcelen - 1), /* win9x */ 125 "Expected count to be %d, it was %d\n", sourcelen, count); 126 ok (!lstrcmpA(source, dest), "Expected source and destination to be the same\n"); 127 128 strcpy(dest, desttest); 129 count = pStr_GetPtrA(NULL, dest, destsize); 130 ok (count == 0, "Expected count to be 0, it was %d\n", count); 131 ok (dest[0] == '\0', "Expected destination to be cut-off and 0 terminated\n"); 132 133 destsize = 15; 134 count = pStr_GetPtrA(source, dest, destsize); 135 ok (count == 15 || 136 broken(count == 14), /* win9x */ 137 "Expected count to be 15, it was %d\n", count); 138 ok (!memcmp(source, dest, 14), "Expected first part of source and destination to be the same\n"); 139 ok (dest[14] == '\0', "Expected destination to be cut-off and 0 terminated\n"); 140 } 141 } 142 143 static void test_Alloc(void) 144 { 145 PCHAR p; 146 BOOL res; 147 DWORD size, min; 148 149 /* allocate size 0 */ 150 p = pAlloc(0); 151 ok(p != NULL, "Expected non-NULL ptr\n"); 152 153 /* get the minimum size */ 154 min = pGetSize(p); 155 156 /* free the block */ 157 res = pFree(p); 158 ok(res == TRUE, "Expected TRUE, got %d\n", res); 159 160 /* allocate size 1 */ 161 p = pAlloc(1); 162 ok(p != NULL, "Expected non-NULL ptr\n"); 163 164 /* get the allocated size */ 165 size = pGetSize(p); 166 ok(size == 1 || 167 broken(size == min), /* win9x */ 168 "Expected 1, got %d\n", size); 169 170 /* reallocate the block */ 171 p = pReAlloc(p, 2); 172 ok(p != NULL, "Expected non-NULL ptr\n"); 173 174 /* get the new size */ 175 size = pGetSize(p); 176 ok(size == 2 || 177 broken(size == min), /* win9x */ 178 "Expected 2, got %d\n", size); 179 180 /* free the block */ 181 res = pFree(p); 182 ok(res == TRUE, "Expected TRUE, got %d\n", res); 183 184 /* free a NULL ptr */ 185 res = pFree(NULL); 186 ok(res == TRUE || 187 broken(res == FALSE), /* win9x */ 188 "Expected TRUE, got %d\n", res); 189 190 /* reallocate a NULL ptr */ 191 p = pReAlloc(NULL, 2); 192 ok(p != NULL, "Expected non-NULL ptr\n"); 193 194 res = pFree(p); 195 ok(res == TRUE, "Expected TRUE, got %d\n", res); 196 } 197 198 static void test_LoadIconWithScaleDown(void) 199 { 200 static const WCHAR nonexisting_fileW[] = {'n','o','n','e','x','i','s','t','i','n','g','.','i','c','o',0}; 201 static const WCHAR nonexisting_resourceW[] = {'N','o','n','e','x','i','s','t','i','n','g',0}; 202 static const WCHAR prefixW[] = {'I','C','O',0}; 203 HRESULT (WINAPI *pLoadIconMetric)(HINSTANCE, const WCHAR *, int, HICON *); 204 HRESULT (WINAPI *pLoadIconWithScaleDown)(HINSTANCE, const WCHAR *, int, int, HICON *); 205 WCHAR tmp_path[MAX_PATH], icon_path[MAX_PATH]; 206 ICONINFO info; 207 HMODULE hinst; 208 HANDLE handle; 209 DWORD written; 210 HRESULT hr; 211 BITMAP bmp; 212 HICON icon; 213 void *ptr; 214 int bytes; 215 BOOL res; 216 217 hinst = LoadLibraryA("comctl32.dll"); 218 pLoadIconMetric = (void *)GetProcAddress(hinst, "LoadIconMetric"); 219 pLoadIconWithScaleDown = (void *)GetProcAddress(hinst, "LoadIconWithScaleDown"); 220 if (!pLoadIconMetric || !pLoadIconWithScaleDown) 221 { 222 #ifdef __REACTOS__ 223 skip("LoadIconMetric or pLoadIconWithScaleDown not exported by name\n"); 224 #else 225 win_skip("LoadIconMetric or pLoadIconWithScaleDown not exported by name\n"); 226 #endif 227 FreeLibrary(hinst); 228 return; 229 } 230 231 GetTempPathW(MAX_PATH, tmp_path); 232 GetTempFileNameW(tmp_path, prefixW, 0, icon_path); 233 handle = CreateFileW(icon_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 234 FILE_ATTRIBUTE_NORMAL, NULL); 235 ok(handle != INVALID_HANDLE_VALUE, "CreateFileW failed with error %u\n", GetLastError()); 236 res = WriteFile(handle, testicon_data, sizeof(testicon_data), &written, NULL); 237 ok(res && written == sizeof(testicon_data), "Failed to write icon file\n"); 238 CloseHandle(handle); 239 240 /* test ordinals */ 241 ptr = GetProcAddress(hinst, (const char *)380); 242 ok(ptr == pLoadIconMetric, 243 "got wrong pointer for ordinal 380, %p expected %p\n", ptr, pLoadIconMetric); 244 245 ptr = GetProcAddress(hinst, (const char *)381); 246 ok(ptr == pLoadIconWithScaleDown, 247 "got wrong pointer for ordinal 381, %p expected %p\n", ptr, pLoadIconWithScaleDown); 248 249 /* invalid arguments */ 250 icon = (HICON)0x1234; 251 hr = pLoadIconMetric(NULL, (LPWSTR)IDI_APPLICATION, 0x100, &icon); 252 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr); 253 ok(icon == NULL, "Expected NULL, got %p\n", icon); 254 255 icon = (HICON)0x1234; 256 hr = pLoadIconMetric(NULL, NULL, LIM_LARGE, &icon); 257 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr); 258 ok(icon == NULL, "Expected NULL, got %p\n", icon); 259 260 icon = (HICON)0x1234; 261 hr = pLoadIconWithScaleDown(NULL, NULL, 32, 32, &icon); 262 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %x\n", hr); 263 ok(icon == NULL, "Expected NULL, got %p\n", icon); 264 265 /* non-existing filename */ 266 hr = pLoadIconMetric(NULL, nonexisting_fileW, LIM_LARGE, &icon); 267 todo_wine 268 ok(hr == HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), 269 "Expected HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), got %x\n", hr); 270 271 hr = pLoadIconWithScaleDown(NULL, nonexisting_fileW, 32, 32, &icon); 272 todo_wine 273 ok(hr == HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), 274 "Expected HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), got %x\n", hr); 275 276 /* non-existing resource name */ 277 hr = pLoadIconMetric(hinst, nonexisting_resourceW, LIM_LARGE, &icon); 278 ok(hr == HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), 279 "Expected HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), got %x\n", hr); 280 281 hr = pLoadIconWithScaleDown(hinst, nonexisting_resourceW, 32, 32, &icon); 282 ok(hr == HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), 283 "Expected HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), got %x\n", hr); 284 285 /* load icon using predefined identifier */ 286 hr = pLoadIconMetric(NULL, (LPWSTR)IDI_APPLICATION, LIM_SMALL, &icon); 287 ok(hr == S_OK, "Expected S_OK, got %x\n", hr); 288 res = GetIconInfo(icon, &info); 289 ok(res, "Failed to get icon info, error %u\n", GetLastError()); 290 bytes = GetObjectA(info.hbmColor, sizeof(bmp), &bmp); 291 ok(bytes > 0, "Failed to get bitmap info for icon\n"); 292 ok(bmp.bmWidth == GetSystemMetrics(SM_CXSMICON), "Wrong icon width %d\n", bmp.bmWidth); 293 ok(bmp.bmHeight == GetSystemMetrics(SM_CYSMICON), "Wrong icon height %d\n", bmp.bmHeight); 294 DestroyIcon(icon); 295 296 hr = pLoadIconMetric(NULL, (LPWSTR)IDI_APPLICATION, LIM_LARGE, &icon); 297 ok(hr == S_OK, "Expected S_OK, got %x\n", hr); 298 res = GetIconInfo(icon, &info); 299 ok(res, "Failed to get icon info, error %u\n", GetLastError()); 300 bytes = GetObjectA(info.hbmColor, sizeof(bmp), &bmp); 301 ok(bytes > 0, "Failed to get bitmap info for icon\n"); 302 ok(bmp.bmWidth == GetSystemMetrics(SM_CXICON), "Wrong icon width %d\n", bmp.bmWidth); 303 ok(bmp.bmHeight == GetSystemMetrics(SM_CYICON), "Wrong icon height %d\n", bmp.bmHeight); 304 DestroyIcon(icon); 305 306 hr = pLoadIconWithScaleDown(NULL, (LPWSTR)IDI_APPLICATION, 42, 42, &icon); 307 ok(hr == S_OK, "Expected S_OK, got %x\n", hr); 308 res = GetIconInfo(icon, &info); 309 ok(res, "Failed to get icon info, error %u\n", GetLastError()); 310 bytes = GetObjectA(info.hbmColor, sizeof(bmp), &bmp); 311 ok(bytes > 0, "Failed to get bitmap info for icon\n"); 312 ok(bmp.bmWidth == 42, "Wrong icon width %d\n", bmp.bmWidth); 313 ok(bmp.bmHeight == 42, "Wrong icon height %d\n", bmp.bmHeight); 314 DestroyIcon(icon); 315 316 /* load icon from file */ 317 hr = pLoadIconMetric(NULL, icon_path, LIM_SMALL, &icon); 318 ok(hr == S_OK, "Expected S_OK, got %x\n", hr); 319 res = GetIconInfo(icon, &info); 320 ok(res, "Failed to get icon info, error %u\n", GetLastError()); 321 bytes = GetObjectA(info.hbmColor, sizeof(bmp), &bmp); 322 ok(bytes > 0, "Failed to get bitmap info for icon\n"); 323 ok(bmp.bmWidth == GetSystemMetrics(SM_CXSMICON), "Wrong icon width %d\n", bmp.bmWidth); 324 ok(bmp.bmHeight == GetSystemMetrics(SM_CYSMICON), "Wrong icon height %d\n", bmp.bmHeight); 325 DestroyIcon(icon); 326 327 hr = pLoadIconWithScaleDown(NULL, icon_path, 42, 42, &icon); 328 ok(hr == S_OK, "Expected S_OK, got %x\n", hr); 329 res = GetIconInfo(icon, &info); 330 ok(res, "Failed to get icon info, error %u\n", GetLastError()); 331 bytes = GetObjectA(info.hbmColor, sizeof(bmp), &bmp); 332 ok(bytes > 0, "Failed to get bitmap info for icon\n"); 333 ok(bmp.bmWidth == 42, "Wrong icon width %d\n", bmp.bmWidth); 334 ok(bmp.bmHeight == 42, "Wrong icon height %d\n", bmp.bmHeight); 335 DestroyIcon(icon); 336 337 DeleteFileW(icon_path); 338 FreeLibrary(hinst); 339 } 340 341 static void check_class( const char *name, int must_exist, UINT style, UINT ignore ) 342 { 343 WNDCLASSA wc; 344 345 if (GetClassInfoA( 0, name, &wc )) 346 { 347 todo_wine 348 ok( !(~wc.style & style & ~ignore), "System class %s is missing bits %x (%08x/%08x)\n", 349 name, ~wc.style & style, wc.style, style ); 350 ok( !(wc.style & ~style), "System class %s has extra bits %x (%08x/%08x)\n", 351 name, wc.style & ~style, wc.style, style ); 352 ok( !wc.hInstance, "System class %s has hInstance %p\n", name, wc.hInstance ); 353 } 354 else 355 ok( !must_exist, "System class %s does not exist\n", name ); 356 } 357 358 /* test styles of system classes */ 359 static void test_builtin_classes(void) 360 { 361 /* check style bits */ 362 check_class( "Button", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0 ); 363 check_class( "ComboBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0 ); 364 check_class( "Edit", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0 ); 365 check_class( "ListBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0 ); 366 check_class( "ScrollBar", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0 ); 367 check_class( "Static", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0 ); 368 check_class( "ComboLBox", 1, CS_SAVEBITS | CS_DBLCLKS | CS_DROPSHADOW | CS_GLOBALCLASS, CS_DROPSHADOW ); 369 } 370 371 START_TEST(misc) 372 { 373 ULONG_PTR ctx_cookie; 374 HANDLE hCtx; 375 376 if(!InitFunctionPtrs()) 377 return; 378 379 test_GetPtrAW(); 380 test_Alloc(); 381 382 if (!load_v6_module(&ctx_cookie, &hCtx)) 383 return; 384 385 test_builtin_classes(); 386 test_LoadIconWithScaleDown(); 387 388 unload_v6_module(ctx_cookie, hCtx); 389 } 390