1 /* Unit test suite for SHLWAPI IQueryAssociations functions 2 * 3 * Copyright 2008 Google (Lei Zhang) 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include <stdarg.h> 21 22 #include "wine/test.h" 23 #include "shlwapi.h" 24 #include "shlguid.h" 25 26 #define expect(expected, got) ok( (expected) == (got), "Expected %d, got %d\n", (expected), (got)) 27 #define expect_hr(expected, got) ok( (expected) == (got), "Expected %08x, got %08x\n", (expected), (got)) 28 29 static HRESULT (WINAPI *pAssocQueryStringA)(ASSOCF,ASSOCSTR,LPCSTR,LPCSTR,LPSTR,LPDWORD) = NULL; 30 static HRESULT (WINAPI *pAssocQueryStringW)(ASSOCF,ASSOCSTR,LPCWSTR,LPCWSTR,LPWSTR,LPDWORD) = NULL; 31 static HRESULT (WINAPI *pAssocCreate)(CLSID, REFIID, void **) = NULL; 32 static HRESULT (WINAPI *pAssocGetPerceivedType)(LPCWSTR, PERCEIVED *, INT *, LPWSTR *) = NULL; 33 34 /* Every version of Windows with IE should have this association? */ 35 static const WCHAR dotHtml[] = { '.','h','t','m','l',0 }; 36 static const WCHAR badBad[] = { 'b','a','d','b','a','d',0 }; 37 static const WCHAR dotBad[] = { '.','b','a','d',0 }; 38 static const WCHAR open[] = { 'o','p','e','n',0 }; 39 static const WCHAR invalid[] = { 'i','n','v','a','l','i','d',0 }; 40 41 static void test_getstring_bad(void) 42 { 43 static const WCHAR openwith[] = {'O','p','e','n','W','i','t','h','.','e','x','e',0}; 44 WCHAR buf[MAX_PATH]; 45 HRESULT hr; 46 DWORD len; 47 48 if (!pAssocQueryStringW) 49 { 50 win_skip("AssocQueryStringW() is missing\n"); 51 return; 52 } 53 54 len = 0xdeadbeef; 55 hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, NULL, open, NULL, &len); 56 expect_hr(E_INVALIDARG, hr); 57 ok(len == 0xdeadbeef, "got %u\n", len); 58 59 len = 0xdeadbeef; 60 hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, badBad, open, NULL, &len); 61 ok(hr == E_FAIL || 62 hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION), /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ 63 "Unexpected result : %08x\n", hr); 64 ok(len == 0xdeadbeef, "got %u\n", len); 65 66 len = ARRAY_SIZE(buf); 67 hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotBad, open, buf, &len); 68 ok(hr == E_FAIL || 69 hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ || 70 hr == S_OK /* Win8 */, 71 "Unexpected result : %08x\n", hr); 72 if (hr == S_OK) 73 { 74 ok(len < ARRAY_SIZE(buf), "got %u\n", len); 75 ok(!lstrcmpiW(buf + len - ARRAY_SIZE(openwith), openwith), "wrong data\n"); 76 } 77 78 len = 0xdeadbeef; 79 hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, invalid, NULL, &len); 80 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || 81 hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION), /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ 82 "Unexpected result : %08x\n", hr); 83 ok(len == 0xdeadbeef, "got %u\n", len); 84 85 hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, open, NULL, NULL); 86 ok(hr == E_UNEXPECTED || 87 hr == E_INVALIDARG, /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ 88 "Unexpected result : %08x\n", hr); 89 90 len = 0xdeadbeef; 91 hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, NULL, open, NULL, &len); 92 expect_hr(E_INVALIDARG, hr); 93 ok(len == 0xdeadbeef, "got %u\n", len); 94 95 len = 0xdeadbeef; 96 hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, badBad, open, NULL, &len); 97 ok(hr == E_FAIL || 98 hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION), /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ 99 "Unexpected result : %08x\n", hr); 100 ok(len == 0xdeadbeef, "got %u\n", len); 101 102 len = 0xdeadbeef; 103 hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotBad, open, NULL, &len); 104 ok(hr == E_FAIL || 105 hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ || 106 hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND) /* Win8 */ || 107 hr == S_FALSE, /* Win10 */ 108 "Unexpected result : %08x\n", hr); 109 ok((hr == S_FALSE && len < ARRAY_SIZE(buf)) || len == 0xdeadbeef, 110 "got hr=%08x and len=%u\n", hr, len); 111 112 len = 0xdeadbeef; 113 hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, invalid, NULL, &len); 114 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || 115 hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) || /* W2K/Vista/W2K8 */ 116 hr == E_FAIL, /* Win9x/WinMe/NT4 */ 117 "Unexpected result : %08x\n", hr); 118 ok(len == 0xdeadbeef, "got %u\n", len); 119 120 hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, open, NULL, NULL); 121 ok(hr == E_UNEXPECTED || 122 hr == E_INVALIDARG, /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ 123 "Unexpected result : %08x\n", hr); 124 } 125 126 static void test_getstring_basic(void) 127 { 128 HRESULT hr; 129 WCHAR * friendlyName; 130 WCHAR * executableName; 131 DWORD len, len2, slen; 132 133 if (!pAssocQueryStringW) 134 { 135 win_skip("AssocQueryStringW() is missing\n"); 136 return; 137 } 138 139 hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, open, NULL, &len); 140 expect_hr(S_FALSE, hr); 141 if (hr != S_FALSE) 142 { 143 skip("failed to get initial len\n"); 144 return; 145 } 146 147 executableName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 148 len * sizeof(WCHAR)); 149 if (!executableName) 150 { 151 skip("failed to allocate memory\n"); 152 return; 153 } 154 155 len2 = len; 156 hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, open, 157 executableName, &len2); 158 expect_hr(S_OK, hr); 159 slen = lstrlenW(executableName) + 1; 160 expect(len, len2); 161 expect(len, slen); 162 163 hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, open, NULL, 164 &len); 165 ok(hr == S_FALSE || 166 hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /* Win9x/NT4 */ || 167 hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), /* Win8 */ 168 "Unexpected result : %08x\n", hr); 169 if (hr != S_FALSE) 170 { 171 HeapFree(GetProcessHeap(), 0, executableName); 172 skip("failed to get initial len\n"); 173 return; 174 } 175 176 friendlyName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 177 len * sizeof(WCHAR)); 178 if (!friendlyName) 179 { 180 HeapFree(GetProcessHeap(), 0, executableName); 181 skip("failed to allocate memory\n"); 182 return; 183 } 184 185 len2 = len; 186 hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, open, 187 friendlyName, &len2); 188 expect_hr(S_OK, hr); 189 slen = lstrlenW(friendlyName) + 1; 190 expect(len, len2); 191 expect(len, slen); 192 193 HeapFree(GetProcessHeap(), 0, executableName); 194 HeapFree(GetProcessHeap(), 0, friendlyName); 195 } 196 197 static void test_getstring_no_extra(void) 198 { 199 LONG ret; 200 HKEY hkey; 201 HRESULT hr; 202 static const CHAR dotWinetest[] = { 203 '.','w','i','n','e','t','e','s','t',0 204 }; 205 static const CHAR winetestfile[] = { 206 'w','i','n','e','t','e','s','t', 'f','i','l','e',0 207 }; 208 static const CHAR winetestfileAction[] = { 209 'w','i','n','e','t','e','s','t','f','i','l','e', 210 '\\','s','h','e','l','l', 211 '\\','f','o','o', 212 '\\','c','o','m','m','a','n','d',0 213 }; 214 static const CHAR action[] = { 215 'n','o','t','e','p','a','d','.','e','x','e',0 216 }; 217 CHAR buf[MAX_PATH]; 218 DWORD len = MAX_PATH; 219 220 if (!pAssocQueryStringA) 221 { 222 win_skip("AssocQueryStringA() is missing\n"); 223 return; 224 } 225 226 buf[0] = '\0'; 227 ret = RegCreateKeyA(HKEY_CLASSES_ROOT, dotWinetest, &hkey); 228 if (ret != ERROR_SUCCESS) { 229 skip("failed to create dotWinetest key\n"); 230 return; 231 } 232 233 ret = RegSetValueA(hkey, NULL, REG_SZ, winetestfile, lstrlenA(winetestfile)); 234 RegCloseKey(hkey); 235 if (ret != ERROR_SUCCESS) 236 { 237 skip("failed to set dotWinetest key\n"); 238 goto cleanup; 239 } 240 241 ret = RegCreateKeyA(HKEY_CLASSES_ROOT, winetestfileAction, &hkey); 242 if (ret != ERROR_SUCCESS) 243 { 244 skip("failed to create winetestfileAction key\n"); 245 goto cleanup; 246 } 247 248 ret = RegSetValueA(hkey, NULL, REG_SZ, action, lstrlenA(action)); 249 RegCloseKey(hkey); 250 if (ret != ERROR_SUCCESS) 251 { 252 skip("failed to set winetestfileAction key\n"); 253 goto cleanup; 254 } 255 256 hr = pAssocQueryStringA(0, ASSOCSTR_EXECUTABLE, dotWinetest, NULL, buf, &len); 257 ok(hr == S_OK || 258 hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), /* XP and W2K3 */ 259 "Unexpected result : %08x\n", hr); 260 hr = pAssocQueryStringA(0, ASSOCSTR_EXECUTABLE, dotWinetest, "foo", buf, &len); 261 expect_hr(S_OK, hr); 262 ok(strstr(buf, action) != NULL, 263 "got '%s' (Expected result to include 'notepad.exe')\n", buf); 264 265 cleanup: 266 SHDeleteKeyA(HKEY_CLASSES_ROOT, dotWinetest); 267 SHDeleteKeyA(HKEY_CLASSES_ROOT, winetestfile); 268 269 } 270 271 static void test_assoc_create(void) 272 { 273 HRESULT hr; 274 IQueryAssociations *pqa; 275 276 if (!pAssocCreate) 277 { 278 win_skip("AssocCreate() is missing\n"); 279 return; 280 } 281 282 hr = pAssocCreate(IID_NULL, &IID_NULL, NULL); 283 ok(hr == E_INVALIDARG, "Unexpected result : %08x\n", hr); 284 285 hr = pAssocCreate(CLSID_QueryAssociations, &IID_NULL, (LPVOID*)&pqa); 286 ok(hr == CLASS_E_CLASSNOTAVAILABLE || hr == E_NOTIMPL || hr == E_NOINTERFACE 287 , "Unexpected result : %08x\n", hr); 288 289 hr = pAssocCreate(IID_NULL, &IID_IQueryAssociations, (LPVOID*)&pqa); 290 ok(hr == CLASS_E_CLASSNOTAVAILABLE || hr == E_NOTIMPL || hr == E_INVALIDARG 291 , "Unexpected result : %08x\n", hr); 292 293 hr = pAssocCreate(CLSID_QueryAssociations, &IID_IQueryAssociations, (LPVOID*)&pqa); 294 ok(hr == S_OK || hr == E_NOTIMPL /* win98 */ 295 , "Unexpected result : %08x\n", hr); 296 if(hr == S_OK) 297 { 298 IQueryAssociations_Release(pqa); 299 } 300 301 hr = pAssocCreate(CLSID_QueryAssociations, &IID_IUnknown, (LPVOID*)&pqa); 302 ok(hr == S_OK || hr == E_NOTIMPL /* win98 */ 303 , "Unexpected result : %08x\n", hr); 304 if(hr == S_OK) 305 { 306 IQueryAssociations_Release(pqa); 307 } 308 } 309 310 /* Based on http://www.geoffchappell.com/studies/windows/shell/shlwapi/api/assocapi/getperceivedtype.htm */ 311 struct assoc_test_struct 312 { 313 PCSTR extension; 314 PERCEIVED perceived; 315 INT flags; 316 PCSTR type; 317 DWORD minversion; 318 HRESULT hr; 319 }; 320 321 #define HARDCODED_NATIVE_WMSDK (PERCEIVEDFLAG_HARDCODED | PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_WMSDK) 322 #define HARDCODED_NATIVE_GDIPLUS (PERCEIVEDFLAG_HARDCODED | PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_GDIPLUS) 323 #define HARDCODED_NATIVE_ZIPFLDR (PERCEIVEDFLAG_HARDCODED | PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_ZIPFOLDER) 324 #define SOFTCODED_NATIVESUPPORT (PERCEIVEDFLAG_SOFTCODED | PERCEIVEDFLAG_NATIVESUPPORT) 325 326 static const struct assoc_test_struct assoc_perceived_types[] = 327 { 328 /* builtins */ 329 { ".aif", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 330 { ".aifc", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 331 { ".aiff", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 332 { ".asf", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 333 { ".asx", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 334 { ".au", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 335 { ".avi", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 336 { ".bas", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 337 { ".bat", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 338 { ".bmp", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 339 { ".cmd", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 340 { ".com", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 341 { ".cpl", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_HARDCODED, "system", 0x600 }, 342 { ".dib", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 343 { ".dvr-ms", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 344 { ".emf", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 345 { ".exe", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 346 { ".gif", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 347 { ".hta", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 348 /* htm & html are PERCEIVED_TYPE_TEXT, PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_SOFTCODED in w2k3 */ 349 { ".htm", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_HARDCODED, "document", 0x600 }, 350 { ".html", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_HARDCODED, "document", 0x600 }, 351 { ".ico", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 352 { ".IVF", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 353 { ".jfif", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 354 { ".jpe", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 355 { ".jpeg", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 356 { ".jpg", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 357 { ".lnk", PERCEIVED_TYPE_UNSPECIFIED, PERCEIVEDFLAG_HARDCODED, NULL, 0x600, E_FAIL }, 358 { ".m1v", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 359 { ".m3u", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 360 { ".mht", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_HARDCODED, "document", 0x600 }, 361 { ".mid", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 362 { ".midi", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 363 { ".msi", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 364 /* below win8 this is defined to be video */ 365 { ".mp2", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio", 0x602 }, 366 { ".mp2v", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 367 { ".mp3", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 368 { ".mpa", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 369 { ".mpe", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 370 { ".mpeg", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 371 { ".mpg", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 372 { ".mpv2", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 373 { ".pif", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 374 { ".png", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 375 { ".reg", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 376 { ".rle", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 377 { ".rmi", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 378 { ".scr", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 379 { ".search-ms", PERCEIVED_TYPE_UNSPECIFIED, PERCEIVEDFLAG_HARDCODED, NULL, 0x600, E_FAIL }, 380 { ".snd", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 381 { ".tif", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 382 { ".tiff", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 383 { ".vb", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, 384 { ".wav", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 385 { ".wax", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 386 { ".wm", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 387 { ".wma", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, 388 { ".wmf", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, 389 { ".wmv", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 390 { ".wmx", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 391 { ".wvx", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, 392 { ".zip", PERCEIVED_TYPE_COMPRESSED, HARDCODED_NATIVE_ZIPFLDR, "compressed" }, 393 /* found in the registry under HKEY_CLASSES_ROOT on a new Win7 VM */ 394 { ".386", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, 395 { ".3g2", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 396 { ".3gp", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 397 { ".3gp2", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 398 { ".3gpp", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 399 { ".AAC", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, 400 { ".ADT", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, 401 { ".ADTS", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, 402 { ".asm", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 403 { ".asmx", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 404 { ".aspx", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 405 { ".c", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 406 { ".cab", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed", 0x600 }, 407 { ".chk", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, 408 { ".cpp", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 409 { ".css", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 410 { ".cxx", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 411 { ".def", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 412 { ".diz", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 413 { ".docx", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x601 }, 414 { ".drv", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system", 0x600 }, 415 { ".gz", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, 416 { ".h", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 417 { ".hpp", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 418 { ".hxx", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 419 { ".inc", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 420 { ".ini", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text", 0x600 }, 421 { ".java", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 422 { ".local", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, 423 { ".M2T", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 424 { ".M2TS", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 425 { ".M2V", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 426 { ".m4a", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, 427 { ".m4b", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, 428 { ".m4p", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, 429 { ".m4v", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 430 { ".manifest", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, 431 { ".MOD", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 432 { ".mov", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 433 { ".mp4", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 434 { ".mp4v", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 435 { ".MTS", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 436 { ".nvr", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 437 { ".ocx", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, 438 { ".odt", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x601 }, 439 { ".php3", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 440 { ".pl", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 441 { ".plg", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 442 { ".ps1xml", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "Text" }, 443 { ".rtf", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, 444 { ".sed", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 445 { ".shtml", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 446 { ".sql", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 447 { ".sys", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system", 0x600 }, 448 { ".tar", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, 449 { ".text", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 450 { ".tgz", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, 451 { ".TS", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 452 { ".tsv", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 453 { ".TTS", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 454 { ".txt", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 455 { ".vob", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, 456 { ".vxd", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, 457 { ".wdp", PERCEIVED_TYPE_IMAGE, PERCEIVEDFLAG_SOFTCODED, "image" }, 458 { ".wmz", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, 459 { ".wpl", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, 460 { ".wsz", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, 461 { ".x", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, 462 { ".xml", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text", 0x601 }, 463 { ".xsl", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text", 0x601 }, 464 { ".z", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, 465 /* found in the registry under HKEY_CLASSES_ROOT\PerceivedType */ 466 { ".doc", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, 467 { ".dot", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, 468 { ".mhtml", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, 469 { ".pot", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, 470 { ".ppt", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, 471 { ".rtf", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, 472 { ".wri", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, 473 { ".xls", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, 474 { ".xlt", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, 475 476 }; 477 478 static void test_assoc_one(const struct assoc_test_struct* test) 479 { 480 LPWSTR extension, type_expected, type_returned; 481 PERCEIVED perceived; 482 HRESULT hr; 483 INT flags; 484 485 /* if SHStrDupA receives a nullptr as input, it will null the output */ 486 SHStrDupA(test->extension, &extension); 487 SHStrDupA(test->type, &type_expected); 488 489 perceived = 0xdeadbeef; 490 flags = 0xdeadbeef; 491 492 hr = pAssocGetPerceivedType(extension, &perceived, &flags, NULL); 493 expect_hr(type_expected ? S_OK : test->hr, hr); 494 ok(perceived == test->perceived, "%s: got perceived 0x%x, expected 0x%x\n", 495 test->extension, perceived, test->perceived); 496 ok(flags == test->flags, "%s: got flags 0x%x, expected 0x%x\n", 497 test->extension, flags, test->flags); 498 499 type_returned = (void *)0xdeadbeef; 500 perceived = 0xdeadbeef; 501 flags = 0xdeadbeef; 502 503 hr = pAssocGetPerceivedType(extension, &perceived, &flags, &type_returned); 504 expect_hr(type_expected ? S_OK : test->hr, hr); 505 ok(perceived == test->perceived, "%s: got perceived 0x%x, expected 0x%x\n", 506 test->extension, perceived, test->perceived); 507 ok(flags == test->flags, "%s: got flags 0x%x, expected 0x%x\n", 508 test->extension, flags, test->flags); 509 510 if (!type_expected) 511 { 512 ok(type_returned == (void *)0xdeadbeef || broken(type_returned == NULL) /* Win 8 */, 513 "%s: got type %p, expected 0xdeadbeef\n", test->extension, type_returned); 514 } 515 else if (type_returned == (void *)0xdeadbeef) 516 { 517 ok(type_returned != (void *)0xdeadbeef, "%s: got type %p, expected '%s'\n", 518 test->extension, type_returned, test->type); 519 } 520 else 521 { 522 ok(StrCmpIW(type_expected, type_returned) == 0, "%s: got type %s, expected '%s'\n", 523 test->extension, wine_dbgstr_w(type_returned), test->type); 524 } 525 526 CoTaskMemFree(type_returned); 527 CoTaskMemFree(extension); 528 CoTaskMemFree(type_expected); 529 } 530 531 static void test_assoc_perceived(void) 532 { 533 static const struct assoc_test_struct should_not_exist = 534 { ".should_not_exist", PERCEIVED_TYPE_UNSPECIFIED, PERCEIVEDFLAG_UNDEFINED, NULL, 0, 0x80070002 }; 535 static const struct assoc_test_struct htm[] = 536 { 537 { ".htm", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text", 0x600 }, 538 { ".html", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text", 0x600 }, 539 }; 540 static const struct assoc_test_struct mp2 = 541 { ".mp2", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }; 542 543 OSVERSIONINFOEXW osvi; 544 DWORD version; 545 size_t i; 546 547 if (!pAssocGetPerceivedType) 548 { 549 win_skip("AssocGetPerceivedType() is missing\n"); 550 return; 551 } 552 553 memset(&osvi, 0, sizeof(osvi)); 554 osvi.dwOSVersionInfoSize = sizeof(osvi); 555 GetVersionExW((LPOSVERSIONINFOW)&osvi); 556 version = (osvi.dwMajorVersion << 8) | osvi.dwMinorVersion; 557 558 /* invalid entry results in HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) */ 559 test_assoc_one(&should_not_exist); 560 561 for (i = 0; i < sizeof(assoc_perceived_types) / sizeof(assoc_perceived_types[0]); ++i) 562 { 563 if (assoc_perceived_types[i].minversion && assoc_perceived_types[i].minversion > version) 564 continue; 565 if (!(assoc_perceived_types[i].flags & PERCEIVEDFLAG_HARDCODED)) 566 todo_wine test_assoc_one(&assoc_perceived_types[i]); 567 else 568 test_assoc_one(&assoc_perceived_types[i]); 569 } 570 571 /* below Vista */ 572 if (version < 0x600) 573 { 574 todo_wine 575 test_assoc_one(&htm[0]); 576 todo_wine 577 test_assoc_one(&htm[1]); 578 } 579 580 /* below Win8 */ 581 if (version < 0x602) 582 { 583 test_assoc_one(&mp2); 584 } 585 } 586 587 START_TEST(assoc) 588 { 589 HMODULE hshlwapi; 590 hshlwapi = GetModuleHandleA("shlwapi.dll"); 591 pAssocQueryStringA = (void*)GetProcAddress(hshlwapi, "AssocQueryStringA"); 592 pAssocQueryStringW = (void*)GetProcAddress(hshlwapi, "AssocQueryStringW"); 593 pAssocCreate = (void*)GetProcAddress(hshlwapi, "AssocCreate"); 594 pAssocGetPerceivedType = (void*)GetProcAddress(hshlwapi, "AssocGetPerceivedType"); 595 596 test_getstring_bad(); 597 test_getstring_basic(); 598 test_getstring_no_extra(); 599 test_assoc_create(); 600 test_assoc_perceived(); 601 } 602