ReactOS 0.4.15-dev-8219-ge8b88cf
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
94static const WCHAR httpW[] = {'h','t','t','p',0};
95static 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
104static 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
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
332}
#define broken(x)
Definition: _sntprintf.h:21
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
const GUID IID_IUnknown
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
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:1096
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:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
#define MAX_PATH
Definition: compat.h:34
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4242
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint buffer
Definition: glext.h:5915
GLenum GLsizei len
Definition: glext.h:6722
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
static const WCHAR emptyW[]
Definition: navigate.c:40
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define wine_dbgstr_w
Definition: kernel32.h:34
#define REG_SZ
Definition: layer.c:22
static PVOID ptr
Definition: dispmode.c:27
#define todo_wine
Definition: custom.c:79
static const WCHAR badW[]
Definition: assoc.c:95
static void test_IApplicationAssociationRegistration_QueryCurrentDefault(IApplicationAssociationRegistration *appreg)
Definition: assoc.c:258
static void getstring_test(LPCWSTR assocName, HKEY progIdKey, ASSOCSTR str, LPCWSTR expected_string, int line)
Definition: assoc.c:104
static void test_IQueryAssociations_GetString(void)
Definition: assoc.c:140
static const WCHAR httpW[]
Definition: assoc.c:94
static void test_IQueryAssociations_QueryInterface(void)
Definition: assoc.c:32
static void test_IApplicationAssociationRegistration_QueryInterface(IApplicationAssociationRegistration *appreg)
Definition: assoc.c:61
static void test_IQueryAssociations_Init(void)
Definition: assoc.c:233
static struct assoc_getstring_test getstring_tests[]
Definition: assoc.c:97
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
BYTE * PBYTE
Definition: pedump.c:66
const WCHAR * str
#define win_skip
Definition: test.h:163
HRESULT hr
Definition: shlfolder.c:183
ASSOCSTR
Definition: shlwapi.h:602
@ ASSOCSTR_EXECUTABLE
Definition: shlwapi.h:604
@ ASSOCSTR_DEFAULTICON
Definition: shlwapi.h:617
#define IQueryAssociations_Release(p)
Definition: shlwapi.h:668
#define IQueryAssociations_Init(p, a, b, c, d)
Definition: shlwapi.h:669
#define IQueryAssociations_QueryInterface(p, a, b)
Definition: shlwapi.h:666
@ ASSOCF_NONE
Definition: shlwapi.h:581
@ ASSOCF_NOTRUNCATE
Definition: shlwapi.h:588
DWORD ASSOCF
Definition: shlwapi.h:599
#define IQueryAssociations_GetString(p, a, b, c, d, e)
Definition: shlwapi.h:670
@ AL_EFFECTIVE
Definition: shobjidl.idl:4125
@ AT_URLPROTOCOL
Definition: shobjidl.idl:4131
@ AT_MIMETYPE
Definition: shobjidl.idl:4133
@ AT_STARTMENUCLIENT
Definition: shobjidl.idl:4132
@ AT_FILEEXTENSION
Definition: shobjidl.idl:4130
const WCHAR * key
Definition: assoc.c:86
HRESULT brokenhr
Definition: assoc.c:91
ASSOCSTR str
Definition: assoc.c:88
Definition: parser.c:49
LONG_PTR LRESULT
Definition: windef.h:209
#define S_FALSE
Definition: winerror.h:2357
#define ERROR_NO_ASSOCIATION
Definition: winerror.h:677
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185