ReactOS  0.4.14-dev-583-g2a1ba2c
assoc.c
Go to the documentation of this file.
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};
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);
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);
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);
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);
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 
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);
287  , "Unexpected result : %08x\n", hr);
288 
289  hr = pAssocCreate(IID_NULL, &IID_IQueryAssociations, (LPVOID*)&pqa);
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  {
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  {
307  }
308 }
309 
310 /* Based on http://www.geoffchappell.com/studies/windows/shell/shlwapi/api/assocapi/getperceivedtype.htm */
312 {
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 
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;
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);
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 
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);
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  {
564  continue;
565  if (!(assoc_perceived_types[i].flags & PERCEIVEDFLAG_HARDCODED))
567  else
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 
588 {
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 
601 }
static const WCHAR invalid[]
Definition: assoc.c:39
#define HARDCODED_NATIVE_WMSDK
Definition: assoc.c:321
static void test_getstring_bad(void)
Definition: assoc.c:41
START_TEST(assoc)
Definition: assoc.c:297
ULONG dwMajorVersion
Definition: rtltypes.h:234
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:420
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT hr
Definition: shlfolder.c:183
static LPSTR
Definition: assoc.c:29
OSVERSIONINFO osvi
Definition: ver.c:28
static void test_assoc_create(void)
Definition: assoc.c:271
#define HARDCODED_NATIVE_ZIPFLDR
Definition: assoc.c:323
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
PERCEIVED perceived
Definition: assoc.c:314
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
static ASSOCSTR
Definition: assoc.c:29
char CHAR
Definition: xmlstorage.h:175
#define HARDCODED_NATIVE_GDIPLUS
Definition: assoc.c:322
LONG WINAPI RegSetValueA(HKEY hKeyOriginal, LPCSTR lpSubKey, DWORD dwType, LPCSTR lpData, DWORD cbData)
Definition: reg.c:4968
#define test
Definition: rosglue.h:37
static void test_assoc_perceived(void)
Definition: assoc.c:531
BOOL WINAPI GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)
Definition: version.c:37
#define lstrlenW
Definition: compat.h:415
#define E_FAIL
Definition: ddrawi.h:102
static HMODULE hshlwapi
Definition: shreg.c:35
#define CLASS_E_CLASSNOTAVAILABLE
Definition: winerror.h:2663
int32_t INT
Definition: typedefs.h:56
static void test_getstring_no_extra(void)
Definition: assoc.c:197
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
HRESULT WINAPI SHStrDupA(LPCSTR lpszStr, LPWSTR *lppszDest)
Definition: string.c:1946
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
long LONG
Definition: pedump.c:60
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:66
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define SOFTCODED_NATIVESUPPORT
Definition: assoc.c:324
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1177
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:233
static void **static PERCEIVED INT LPWSTR *static const WCHAR dotHtml[]
Definition: assoc.c:35
HRESULT hr
Definition: assoc.c:318
static REFIID
Definition: assoc.c:31
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
REFFOLDERTYPEID enum tagPERCEIVED PERCEIVED
GLbitfield flags
Definition: glext.h:7161
int ret
static const struct assoc_test_struct assoc_perceived_types[]
Definition: assoc.c:326
#define IID_NULL
Definition: guiddef.h:98
#define todo_wine
Definition: test.h:163
static void test_assoc_one(const struct assoc_test_struct *test)
Definition: assoc.c:478
GLenum GLsizei len
Definition: glext.h:6722
ULONG dwMinorVersion
Definition: rtltypes.h:235
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
static LPCSTR
Definition: assoc.c:29
static LPDWORD
Definition: assoc.c:29
#define expect(expected, got)
Definition: assoc.c:26
#define broken(x)
Definition: _sntprintf.h:21
#define expect_hr(expected, got)
Definition: assoc.c:27
#define S_OK
Definition: intsafe.h:59
DWORD WINAPI SHDeleteKeyA(HKEY hKey, LPCSTR lpszSubKey)
Definition: reg.c:1533
DWORD minversion
Definition: assoc.c:317
#define ERROR_NO_ASSOCIATION
Definition: winerror.h:677
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
const WCHAR * action
Definition: action.c:7783
DWORD ASSOCF
Definition: shlwapi.h:599
PCSTR extension
Definition: assoc.c:313
#define ARRAY_SIZE(a)
Definition: main.h:24
#define ok(value,...)
Definition: atltest.h:57
#define E_NOTIMPL
Definition: ddrawi.h:99
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define ERROR_NOT_FOUND
Definition: winerror.h:690
static void test_getstring_basic(void)
Definition: assoc.c:126
static LPWSTR
Definition: assoc.c:30
#define E_UNEXPECTED
Definition: winerror.h:2456
static HRESULT(WINAPI *pAssocQueryStringA)(ASSOCF
#define skip(...)
Definition: atltest.h:64
static const WCHAR dotBad[]
Definition: assoc.c:37
char * cleanup(char *str)
Definition: wpickclick.c:99
#define GetProcAddress(x, y)
Definition: compat.h:418
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
const char * PCSTR
Definition: typedefs.h:51
static const WCHAR open[]
Definition: assoc.c:38
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define memset(x, y, z)
Definition: compat.h:39
static LPCWSTR
Definition: assoc.c:30
#define win_skip
Definition: test.h:150
#define HeapFree(x, y, z)
Definition: compat.h:402
static const WCHAR badBad[]
Definition: assoc.c:36
int WINAPI StrCmpIW(LPCWSTR lpszStr, LPCWSTR lpszComp)
Definition: string.c:353
#define IQueryAssociations_Release(p)
Definition: shlwapi.h:668
#define REG_SZ
Definition: layer.c:22