ReactOS  0.4.14-dev-358-gbef841c
assoc.c
Go to the documentation of this file.
1 /* Unit test suite for various shell Association objects
2  *
3  * Copyright 2012 Detlef Riekenberg
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 #define COBJMACROS
21 
22 #include <stdarg.h>
23 
24 #include "shlwapi.h"
25 #include "shlguid.h"
26 #include "shobjidl.h"
27 
28 #include "wine/heap.h"
29 #include "wine/test.h"
30 
31 
33 {
34  IQueryAssociations *qa;
35  IQueryAssociations *qa2;
36  IUnknown *unk;
37  HRESULT hr;
38 
39  hr = CoCreateInstance(&CLSID_QueryAssociations, NULL, CLSCTX_INPROC_SERVER, &IID_IQueryAssociations, (void*)&qa);
40  ok(hr == S_OK, "got 0x%08x\n", hr);
41 
42  hr = IQueryAssociations_QueryInterface(qa, &IID_IQueryAssociations, (void**)&qa2);
43  ok(hr == S_OK, "QueryInterface (IQueryAssociations) returned 0x%x\n", hr);
44  if (SUCCEEDED(hr)) {
46  }
47 
49  ok(hr == S_OK, "QueryInterface (IUnknown) returned 0x%x\n", hr);
50  if (SUCCEEDED(hr)) {
51  IUnknown_Release(unk);
52  }
53 
55  ok(hr == E_POINTER, "got 0x%x (expected E_POINTER)\n", hr);
56 
58 }
59 
60 
62 {
64  IUnknown *unk;
65  HRESULT hr;
66 
67  hr = IApplicationAssociationRegistration_QueryInterface(appreg, &IID_IApplicationAssociationRegistration,
68  (void**)&appreg2);
69  ok(hr == S_OK, "QueryInterface (IApplicationAssociationRegistration) returned 0x%x\n", hr);
70  if (SUCCEEDED(hr)) {
71  IApplicationAssociationRegistration_Release(appreg2);
72  }
73 
74  hr = IApplicationAssociationRegistration_QueryInterface(appreg, &IID_IUnknown, (void**)&unk);
75  ok(hr == S_OK, "QueryInterface (IUnknown) returned 0x%x\n", hr);
76  if (SUCCEEDED(hr)) {
77  IUnknown_Release(unk);
78  }
79 
80  hr = IApplicationAssociationRegistration_QueryInterface(appreg, &IID_IUnknown, NULL);
81  ok(hr == E_POINTER, "got 0x%x (expected E_POINTER)\n", hr);
82 }
83 
85 {
86  const WCHAR *key;
92 };
93 
94 static const WCHAR httpW[] = {'h','t','t','p',0};
95 static const WCHAR badW[] = {'b','a','d','b','a','d',0};
96 
98 {
99  { httpW, 0, ASSOCSTR_EXECUTABLE, 2, 0x8007007a /* E_NOT_SUFFICIENT_BUFFER */, S_OK },
101  { NULL }
102 };
103 
104 static void getstring_test(LPCWSTR assocName, HKEY progIdKey, ASSOCSTR str, LPCWSTR expected_string, int line)
105 {
106  IQueryAssociations *assoc;
107  HRESULT hr;
108  WCHAR *buffer = NULL;
109  DWORD len;
110 
111  hr = CoCreateInstance(&CLSID_QueryAssociations, NULL, CLSCTX_INPROC_SERVER, &IID_IQueryAssociations, (void*)&assoc);
112  ok_(__FILE__, line)(hr == S_OK, "failed to create IQueryAssociations, 0x%x\n", hr);
113  hr = IQueryAssociations_Init(assoc, ASSOCF_NONE, assocName, progIdKey, NULL);
114  ok_(__FILE__, line)(hr == S_OK, "IQueryAssociations::Init failed, 0x%x\n", hr);
115 
117  if (expected_string) {
118  ok_(__FILE__, line)(hr == S_FALSE, "GetString returned 0x%x, expected S_FALSE\n", hr);
119  if (hr != S_FALSE) {
120  /* don't try to allocate memory using uninitialized len */
122  return;
123  }
124 
125  buffer = heap_alloc(len * sizeof(WCHAR));
126  ok_(__FILE__, line)(buffer != NULL, "out of memory\n");
128  ok_(__FILE__, line)(hr == S_OK, "GetString returned 0x%x, expected S_OK\n", hr);
129 
130  ok_(__FILE__, line)(lstrcmpW(buffer, expected_string) == 0, "GetString returned %s, expected %s\n",
131  wine_dbgstr_w(buffer), wine_dbgstr_w(expected_string));
132  } else {
133  ok_(__FILE__, line)(FAILED(hr), "GetString returned 0x%x, expected failure\n", hr);
134  }
135 
137  heap_free(buffer);
138 }
139 
141 {
142  static WCHAR test_extensionW[] = {'.','t','e','s','t',0};
143  static WCHAR test_progidW[] = {'t','e','s','t','f','i','l','e',0};
144  static WCHAR DefaultIconW[] = {'D','e','f','a','u','l','t','I','c','o','n',0};
145  /* folder.ico, why not */
146  static WCHAR test_iconW[] = {'s','h','e','l','l','3','2','.','d','l','l',',','1',0};
147  HKEY test_extension_key;
148  HKEY test_progid_key;
149  HKEY test_defaulticon_key;
150  LRESULT r;
151 
153  IQueryAssociations *assoc;
154  HRESULT hr;
155  DWORD len;
156  int i = 0;
157 
158  r = RegCreateKeyExW(HKEY_CLASSES_ROOT, test_extensionW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &test_extension_key, NULL);
159  if (r == ERROR_ACCESS_DENIED)
160  {
161  win_skip("Not enough permissions to create a test key.\n");
162  return;
163  }
164 
165  ok(r == ERROR_SUCCESS, "RegCreateKeyExW(HKCR, \".test\") failed: 0x%lx\n", r);
166  r = RegSetValueExW(test_extension_key, NULL, 0, REG_SZ, (PBYTE)test_progidW, sizeof(test_progidW));
167  ok(r == ERROR_SUCCESS, "RegSetValueExW(HKCR\\.test, NULL, \"testfile\") failed: 0x%lx\n", r);
168 
169  /* adding progid key with no information should fail to return information */
170  r = RegCreateKeyExW(HKEY_CLASSES_ROOT, test_progidW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &test_progid_key, NULL);
171  ok(r == ERROR_SUCCESS, "RegCreateKeyExW(HKCR, \"testfile\") failed: 0x%lx\n", r);
172  getstring_test(test_extensionW, NULL, ASSOCSTR_DEFAULTICON, NULL, __LINE__);
173  getstring_test(test_progidW, NULL, ASSOCSTR_DEFAULTICON, NULL, __LINE__);
174  getstring_test(NULL, test_progid_key, ASSOCSTR_DEFAULTICON, NULL, __LINE__);
175 
176  /* adding information to the progid should return that information */
177  r = RegCreateKeyExW(test_progid_key, DefaultIconW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &test_defaulticon_key, NULL);
178  ok(r == ERROR_SUCCESS, "RegCreateKeyExW(HKCR\\testfile\\DefaultIcon) failed: 0x%lx\n", r);
179  r = RegSetValueExW(test_defaulticon_key, NULL, 0, REG_SZ, (PBYTE)test_iconW, sizeof(test_iconW));
180  ok(r == ERROR_SUCCESS, "RegSetValueExW(HKCR\\testfile\\DefaultIcon, NULL, \"folder.ico\") failed: 0x%lx\n", r);
181  getstring_test(test_extensionW, NULL, ASSOCSTR_DEFAULTICON, test_iconW, __LINE__);
182  getstring_test(test_progidW, NULL, ASSOCSTR_DEFAULTICON, test_iconW, __LINE__);
183  getstring_test(NULL, test_progid_key, ASSOCSTR_DEFAULTICON, test_iconW, __LINE__);
184 
185  RegDeleteKeyW(test_progid_key, DefaultIconW);
186  RegDeleteKeyW(HKEY_CLASSES_ROOT, test_progidW);
187  RegDeleteKeyW(HKEY_CLASSES_ROOT, test_extensionW);
188 
189  hr = CoCreateInstance(&CLSID_QueryAssociations, NULL, CLSCTX_INPROC_SERVER, &IID_IQueryAssociations, (void*)&assoc);
190  ok(hr == S_OK, "failed to create object, 0x%x\n", hr);
191 
193  ok(hr == S_OK, "Init failed, 0x%x\n", hr);
194 
195  len = 0;
197  ok(hr == S_FALSE, "got 0x%08x\n", hr);
198  ok(len > 0, "got wrong needed length, %d\n", len);
199 
200  while (ptr->key)
201  {
202  WCHAR buffW[MAX_PATH];
203  DWORD len;
204 
206  ok(hr == S_OK, "%d: Init failed, 0x%x\n", i, hr);
207 
208  len = ptr->len;
209  buffW[0] = ptr->flags & ASSOCF_NOTRUNCATE ? 0x1 : 0;
210  hr = IQueryAssociations_GetString(assoc, ptr->flags, ptr->str, NULL, buffW, &len);
211  if (hr != ptr->hr)
212  ok(broken(hr == ptr->brokenhr), "%d: GetString failed, 0x%08x\n", i, hr);
213  else
214  {
215  ok(hr == ptr->hr, "%d: GetString failed, 0x%08x\n", i, hr);
216  ok(len > ptr->len, "%d: got needed length %d\n", i, len);
217  }
218 
219  /* even with ASSOCF_NOTRUNCATE it's null terminated */
220  if ((ptr->flags & ASSOCF_NOTRUNCATE) && (ptr->len > 0))
221  ok(buffW[0] == 0 || broken(buffW[0] == 0x1) /* pre win7 */, "%d: got %x\n", i, buffW[0]);
222 
223  if (!(ptr->flags & ASSOCF_NOTRUNCATE) && ptr->len && FAILED(ptr->hr))
224  ok(buffW[0] != 0, "%d: got %x\n", i, buffW[0]);
225 
226  i++;
227  ptr++;
228  }
229 
231 }
232 
234 {
235  IQueryAssociations *assoc;
236  HRESULT hr;
237  DWORD len;
238 
239  hr = CoCreateInstance(&CLSID_QueryAssociations, NULL, CLSCTX_INPROC_SERVER, &IID_IQueryAssociations, (void*)&assoc);
240  ok(hr == S_OK, "failed to create object, 0x%x\n", hr);
241 
243  ok(hr == E_INVALIDARG, "Init failed, 0x%08x\n", hr);
244 
246  ok(hr == S_OK, "Init failed, 0x%08x\n", hr);
247 
249  ok(hr == S_OK || broken(hr == S_FALSE) /* pre-vista */, "Init failed, 0x%08x\n", hr);
250 
251  len = 0;
253  ok(hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) || broken(hr == E_FAIL) /* pre-vista */, "got 0x%08x\n", hr);
254 
256 }
257 
259 {
260  static const WCHAR emptyW[] = {0};
261  static const WCHAR txtW[] = {'.','t','x','t',0};
262  static const WCHAR spacetxtW[] = {' ','.','t','x','t',0};
263  HRESULT hr;
264  LPWSTR assocprog = NULL;
265 
266  hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, emptyW, AT_URLPROTOCOL, AL_EFFECTIVE, &assocprog);
267  ok(hr == E_INVALIDARG, "got 0x%x\n", hr);
268 
269  hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, emptyW, AT_FILEEXTENSION, AL_EFFECTIVE, &assocprog);
270  ok(hr == E_INVALIDARG, "got 0x%x\n", hr);
271 
272  hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, spacetxtW, AT_FILEEXTENSION, AL_EFFECTIVE, &assocprog);
273  ok(hr == E_INVALIDARG || hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) /*Win8*/, "got 0x%x\n", hr);
274 
275  hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, httpW, AT_URLPROTOCOL, AL_EFFECTIVE, NULL);
276  ok(hr == E_INVALIDARG, "got 0x%x\n", hr);
277 
278  /* AT_FILEEXTENSION must start with a period */
279  hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, txtW, AT_FILEEXTENSION, AL_EFFECTIVE, &assocprog);
280  ok(hr == S_OK, "got 0x%x\n", hr);
281  trace("%s\n", wine_dbgstr_w(assocprog));
282  CoTaskMemFree(assocprog);
283 
284  hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, emptyW, AT_STARTMENUCLIENT, AL_EFFECTIVE, &assocprog);
285  ok(hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION), "got 0x%x\n", hr);
286 
287  hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, emptyW, AT_MIMETYPE, AL_EFFECTIVE, &assocprog);
288  ok(hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION), "got 0x%x\n", hr);
289 
290  hr = IApplicationAssociationRegistration_QueryCurrentDefault(appreg, httpW, AT_URLPROTOCOL, AL_EFFECTIVE, &assocprog);
291  todo_wine ok(hr == S_OK, "got 0x%x\n", hr);
292  trace("%s\n", wine_dbgstr_w(assocprog));
293 
294  CoTaskMemFree(assocprog);
295 }
296 
298 {
299  IQueryAssociations *qa;
301  HRESULT hr;
302 
304 
305  /* this works since XP */
306  hr = CoCreateInstance(&CLSID_QueryAssociations, NULL, CLSCTX_INPROC_SERVER, &IID_IQueryAssociations, (void*)&qa);
307  if (hr == S_OK)
308  {
312 
314  }
315  else
316  win_skip("IQueryAssociations not supported, 0x%x\n", hr);
317 
318  /* this works since Vista */
319  hr = CoCreateInstance(&CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC_SERVER,
320  &IID_IApplicationAssociationRegistration, (LPVOID*)&appreg);
321  if (hr == S_OK)
322  {
325 
326  IApplicationAssociationRegistration_Release(appreg);
327  }
328  else
329  win_skip("IApplicationAssociationRegistration not supported: 0x%x\n", hr);
330 
331  CoUninitialize();
332 }
START_TEST(assoc)
Definition: assoc.c:297
static void test_IQueryAssociations_Init(void)
Definition: assoc.c:233
#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
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1237
GLuint buffer
Definition: glext.h:5915
static void test_IApplicationAssociationRegistration_QueryInterface(IApplicationAssociationRegistration *appreg)
Definition: assoc.c:61
#define E_FAIL
Definition: ddrawi.h:102
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
#define IQueryAssociations_QueryInterface(p, a, b)
Definition: shlwapi.h:666
static void test_IQueryAssociations_QueryInterface(void)
Definition: assoc.c:32
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
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
static PVOID ptr
Definition: dispmode.c:27
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
Definition: parser.c:48
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
#define trace
Definition: atltest.h:70
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
ASSOCSTR str
Definition: assoc.c:88
#define IQueryAssociations_Init(p, a, b, c, d)
Definition: shlwapi.h:669
#define todo_wine
Definition: test.h:154
GLenum GLsizei len
Definition: glext.h:6722
static void getstring_test(LPCWSTR assocName, HKEY progIdKey, ASSOCSTR str, LPCWSTR expected_string, int line)
Definition: assoc.c:104
#define broken(x)
Definition: _sntprintf.h:21
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
#define S_OK
Definition: intsafe.h:59
#define ERROR_NO_ASSOCIATION
Definition: winerror.h:677
ASSOCSTR
Definition: shlwapi.h:601
static const WCHAR emptyW[]
Definition: navigate.c:40
DWORD ASSOCF
Definition: shlwapi.h:599
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define ok(value,...)
Definition: atltest.h:57
const WCHAR * key
Definition: assoc.c:86
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
#define IQueryAssociations_GetString(p, a, b, c, d, e)
Definition: shlwapi.h:670
static struct assoc_getstring_test getstring_tests[]
Definition: assoc.c:97
static const WCHAR badW[]
Definition: assoc.c:95
static void test_IApplicationAssociationRegistration_QueryCurrentDefault(IApplicationAssociationRegistration *appreg)
Definition: assoc.c:258
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
static const WCHAR httpW[]
Definition: assoc.c:94
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LONG_PTR LRESULT
Definition: windef.h:209
#define E_POINTER
Definition: winerror.h:2365
HRESULT brokenhr
Definition: assoc.c:91
#define win_skip
Definition: test.h:141
BYTE * PBYTE
Definition: pedump.c:66
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static void test_IQueryAssociations_GetString(void)
Definition: assoc.c:140
#define IQueryAssociations_Release(p)
Definition: shlwapi.h:668
#define ok_(x1, x2)
Definition: atltest.h:61
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
#define REG_SZ
Definition: layer.c:22