ReactOS 0.4.16-dev-336-gb667d82
ordinal.c
Go to the documentation of this file.
1/* Unit test suite for SHLWAPI ordinal functions
2 *
3 * Copyright 2004 Jon Griffiths
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 <stdio.h>
21
22#define COBJMACROS
23#define CONST_VTABLE
24#include "wine/test.h"
25#include "winbase.h"
26#include "winerror.h"
27#include "winuser.h"
28#include "ole2.h"
29#include "oaidl.h"
30#include "ocidl.h"
31#include "mlang.h"
32#include "shlwapi.h"
33#include "docobj.h"
34#include "shobjidl.h"
35#include "shlobj.h"
36#ifdef __REACTOS__
37 #include <shlwapi_undoc.h>
38#endif
39
40/* Function ptrs for ordinal calls */
42
43static int (WINAPI *pSHSearchMapInt)(const int*,const int*,int,int);
44static HRESULT (WINAPI *pGetAcceptLanguagesA)(LPSTR,LPDWORD);
45
46static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
47static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
48static BOOL (WINAPI *pSHUnlockShared)(LPVOID);
49static BOOL (WINAPI *pSHFreeShared)(HANDLE,DWORD);
50static HANDLE (WINAPI *pSHMapHandle)(HANDLE,DWORD,DWORD,DWORD,DWORD);
51static HRESULT(WINAPIV *pSHPackDispParams)(DISPPARAMS*,VARIANTARG*,UINT,...);
52static HRESULT(WINAPI *pIConnectionPoint_SimpleInvoke)(IConnectionPoint*,DISPID,DISPPARAMS*);
53static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DISPID,DISPPARAMS*,DWORD,DWORD);
54static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **);
55static HRESULT(WINAPI *pSHPropertyBag_ReadLONG)(IPropertyBag *,LPCWSTR,LPLONG);
56static LONG (WINAPI *pSHSetWindowBits)(HWND, INT, UINT, UINT);
57static INT (WINAPI *pSHFormatDateTimeA)(const FILETIME UNALIGNED*, DWORD*, LPSTR, UINT);
58static INT (WINAPI *pSHFormatDateTimeW)(const FILETIME UNALIGNED*, DWORD*, LPWSTR, UINT);
59static DWORD (WINAPI *pSHGetObjectCompatFlags)(IUnknown*, const CLSID*);
60static BOOL (WINAPI *pGUIDFromStringA)(LPSTR, CLSID *);
61static HRESULT (WINAPI *pIUnknown_QueryServiceExec)(IUnknown*, REFIID, const GUID*, DWORD, DWORD, VARIANT*, VARIANT*);
62static HRESULT (WINAPI *pIUnknown_ProfferService)(IUnknown*, REFGUID, IServiceProvider*, DWORD*);
63static HWND (WINAPI *pSHCreateWorkerWindowA)(LONG, HWND, DWORD, DWORD, HMENU, LONG_PTR);
64static HRESULT (WINAPI *pSHIShellFolder_EnumObjects)(LPSHELLFOLDER, HWND, SHCONTF, IEnumIDList**);
65static DWORD (WINAPI *pSHGetIniStringW)(LPCWSTR, LPCWSTR, LPWSTR, DWORD, LPCWSTR);
66static BOOL (WINAPI *pSHSetIniStringW)(LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR);
67static HKEY (WINAPI *pSHGetShellKey)(DWORD, LPCWSTR, BOOL);
68static HRESULT (WINAPI *pSKGetValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD*, void*, DWORD*);
69static HRESULT (WINAPI *pSKSetValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD, void*, DWORD);
70static HRESULT (WINAPI *pSKDeleteValueW)(DWORD, LPCWSTR, LPCWSTR);
71static HRESULT (WINAPI *pSKAllocValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD*, void**, DWORD*);
72static HWND (WINAPI *pSHSetParentHwnd)(HWND, HWND);
73static HRESULT (WINAPI *pIUnknown_GetClassID)(IUnknown*, CLSID*);
74static HRESULT (WINAPI *pDllGetVersion)(DLLVERSIONINFO2*);
75
76typedef struct SHELL_USER_SID {
81typedef struct SHELL_USER_PERMISSION {
82
90
92
93static const CHAR ie_international[] = {
94 'S','o','f','t','w','a','r','e','\\',
95 'M','i','c','r','o','s','o','f','t','\\',
96 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
97 'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
98static const CHAR acceptlanguage[] = {
99 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
100
101static int strcmp_wa(LPCWSTR strw, const char *stra)
102{
103 CHAR buf[512];
104 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
105 return lstrcmpA(stra, buf);
106}
107
108typedef struct {
109 int id;
110 const void *args[5];
112
113typedef struct {
115 int count;
116 int alloc;
118
119static void init_call_trace(call_trace_t *ctrace)
120{
121 ctrace->alloc = 10;
122 ctrace->count = 0;
123 ctrace->calls = HeapAlloc(GetProcessHeap(), 0, sizeof(call_entry_t) * ctrace->alloc);
124}
125
126static void free_call_trace(const call_trace_t *ctrace)
127{
128 HeapFree(GetProcessHeap(), 0, ctrace->calls);
129}
130
131static void add_call(call_trace_t *ctrace, int id, const void *arg0,
132 const void *arg1, const void *arg2, const void *arg3, const void *arg4)
133{
134 call_entry_t call;
135
136 call.id = id;
137 call.args[0] = arg0;
138 call.args[1] = arg1;
139 call.args[2] = arg2;
140 call.args[3] = arg3;
141 call.args[4] = arg4;
142
143 if (ctrace->count == ctrace->alloc)
144 {
145 ctrace->alloc *= 2;
146 ctrace->calls = HeapReAlloc(GetProcessHeap(),0, ctrace->calls, ctrace->alloc*sizeof(call_entry_t));
147 }
148
149 ctrace->calls[ctrace->count++] = call;
150}
151
152static void ok_trace_(call_trace_t *texpected, call_trace_t *tgot, int line)
153{
154 if (texpected->count == tgot->count)
155 {
156 INT i;
157 /* compare */
158 for (i = 0; i < texpected->count; i++)
159 {
160 call_entry_t *expected = &texpected->calls[i];
161 call_entry_t *got = &tgot->calls[i];
162 INT j;
163
164 ok_(__FILE__, line)(expected->id == got->id, "got different ids %d: %d, %d\n", i+1, expected->id, got->id);
165
166 for (j = 0; j < 5; j++)
167 {
168 ok_(__FILE__, line)(expected->args[j] == got->args[j], "got different args[%d] for %d: %p, %p\n", j, i+1,
169 expected->args[j], got->args[j]);
170 }
171 }
172 }
173 else
174 ok_(__FILE__, line)(0, "traces length mismatch\n");
175}
176
177#define ok_trace(a, b) ok_trace_(a, b, __LINE__)
178
179/* trace of actually made calls */
181
183{
184 static LPCSTR table[] = {"de,en-gb;q=0.7,en;q=0.3",
185 "de,en;q=0.3,en-gb;q=0.7", /* sorting is ignored */
186 "winetest", /* content is ignored */
187 "de-de,de;q=0.5",
188 "de",
189 NULL};
190
191 DWORD exactsize;
192 char original[512];
193 char language[32];
194 char buffer[64];
195 HKEY hroot = NULL;
196 LONG res_query = ERROR_SUCCESS;
197 LONG lres;
198 HRESULT hr;
199 DWORD maxlen = sizeof(buffer) - 2;
200 DWORD len;
201 LCID lcid;
203 INT i = 0;
204
205 lcid = GetUserDefaultLCID();
206
207 /* Get the original Value */
209 if (lres) {
210 skip("RegOpenKey(%s) failed: %d\n", ie_international, lres);
211 return;
212 }
213 len = sizeof(original);
214 original[0] = 0;
215 res_query = RegQueryValueExA(hroot, acceptlanguage, 0, NULL, (PBYTE)original, &len);
216
218
219 /* Some windows versions use "lang-COUNTRY" as default */
220 memset(language, 0, sizeof(language));
221 len = GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, language, sizeof(language));
222
223 if (len) {
224 lstrcatA(language, "-");
225 memset(buffer, 0, sizeof(buffer));
227 lstrcatA(language, buffer);
228 }
229 else
230 {
231 /* LOCALE_SNAME has additional parts in some languages. Try only as last chance */
232 memset(language, 0, sizeof(language));
233 len = GetLocaleInfoA(lcid, LOCALE_SNAME, language, sizeof(language));
234 }
235
236 /* get the default value */
237 len = maxlen;
238 memset(buffer, '#', maxlen);
239 buffer[maxlen] = 0;
240 hr = pGetAcceptLanguagesA( buffer, &len);
241
242 if (hr != S_OK) {
243 win_skip("GetAcceptLanguagesA failed with 0x%x\n", hr);
244 goto restore_original;
245 }
246
247 if (lstrcmpA(buffer, language)) {
248 /* some windows versions use "lang" or "lang-country" as default */
249 language[0] = 0;
250 hr = LcidToRfc1766A(lcid, language, sizeof(language));
251 ok(hr == S_OK, "LcidToRfc1766A returned 0x%x and %s\n", hr, language);
252 }
253
254 ok(!lstrcmpA(buffer, language),
255 "have '%s' (searching for '%s')\n", language, buffer);
256
257 if (lstrcmpA(buffer, language)) {
258 win_skip("no more ideas, how to build the default language '%s'\n", buffer);
259 goto restore_original;
260 }
261
262 trace("detected default: %s\n", language);
263 while ((entry = table[i])) {
264
265 exactsize = lstrlenA(entry);
266
267 lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) entry, exactsize + 1);
268 ok(!lres, "got %d for RegSetValueExA: %s\n", lres, entry);
269
270 /* len includes space for the terminating 0 before vista/w2k8 */
271 len = exactsize + 2;
272 memset(buffer, '#', maxlen);
273 buffer[maxlen] = 0;
274 hr = pGetAcceptLanguagesA( buffer, &len);
275 ok(((hr == E_INVALIDARG) && (len == 0)) ||
276 (SUCCEEDED(hr) &&
277 ((len == exactsize) || (len == exactsize+1)) &&
279 "+2_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
280
281 len = exactsize + 1;
282 memset(buffer, '#', maxlen);
283 buffer[maxlen] = 0;
284 hr = pGetAcceptLanguagesA( buffer, &len);
285 ok(((hr == E_INVALIDARG) && (len == 0)) ||
286 (SUCCEEDED(hr) &&
287 ((len == exactsize) || (len == exactsize+1)) &&
289 "+1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
290
291 len = exactsize;
292 memset(buffer, '#', maxlen);
293 buffer[maxlen] = 0;
294 hr = pGetAcceptLanguagesA( buffer, &len);
295
296 /* There is no space for the string in the registry.
297 When the buffer is large enough, the default language is returned
298
299 When the buffer is too small for that fallback, win7_32 and w2k8_64
300 fail with E_NOT_SUFFICIENT_BUFFER, win8 fails with HRESULT_FROM_WIN32(ERROR_MORE_DATA),
301 other versions succeed and return a partial result while older os succeed
302 and overflow the buffer */
303
304 ok(((hr == E_INVALIDARG) && (len == 0)) ||
305 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
306 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
307 ((hr == E_NOT_SUFFICIENT_BUFFER) && !len) ||
308 ((hr == __HRESULT_FROM_WIN32(ERROR_MORE_DATA)) && len == exactsize)),
309 "==_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
310
311 if (exactsize > 1) {
312 len = exactsize - 1;
313 memset(buffer, '#', maxlen);
314 buffer[maxlen] = 0;
315 hr = pGetAcceptLanguagesA( buffer, &len);
316 ok(((hr == E_INVALIDARG) && (len == 0)) ||
317 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
318 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
319 ((hr == E_NOT_SUFFICIENT_BUFFER) && !len) ||
320 ((hr == __HRESULT_FROM_WIN32(ERROR_MORE_DATA)) && len == exactsize - 1)),
321 "-1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
322 }
323
324 len = 1;
325 memset(buffer, '#', maxlen);
326 buffer[maxlen] = 0;
327 hr = pGetAcceptLanguagesA( buffer, &len);
328 ok(((hr == E_INVALIDARG) && (len == 0)) ||
329 (((hr == S_OK) && !lstrcmpA(buffer, language) && (len == lstrlenA(language))) ||
330 ((hr == S_OK) && !memcmp(buffer, language, len)) ||
331 ((hr == E_NOT_SUFFICIENT_BUFFER) && !len) ||
333 "=1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
334
335 len = maxlen;
336 hr = pGetAcceptLanguagesA( NULL, &len);
337
338 /* w2k3 and below: E_FAIL and untouched len,
339 since w2k8: S_OK and needed size (excluding 0), win8 S_OK and size including 0. */
340 ok( ((hr == S_OK) && ((len == exactsize) || (len == exactsize + 1))) ||
341 ((hr == E_FAIL) && (len == maxlen)),
342 "NULL,max #%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
343
344 i++;
345 }
346
347 /* without a value in the registry, a default language is returned */
349
350 len = maxlen;
351 memset(buffer, '#', maxlen);
352 buffer[maxlen] = 0;
353 hr = pGetAcceptLanguagesA( buffer, &len);
354 ok( ((hr == S_OK) && (len == lstrlenA(language))),
355 "max: got 0x%x with %d and %s (expected S_OK with %d and '%s'\n",
356 hr, len, buffer, lstrlenA(language), language);
357
358 len = 2;
359 memset(buffer, '#', maxlen);
360 buffer[maxlen] = 0;
361 hr = pGetAcceptLanguagesA( buffer, &len);
362 ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
363 ((hr == E_NOT_SUFFICIENT_BUFFER) && !len) ||
365 "=2: got 0x%x with %d and %s\n", hr, len, buffer);
366
367 len = 1;
368 memset(buffer, '#', maxlen);
369 buffer[maxlen] = 0;
370 hr = pGetAcceptLanguagesA( buffer, &len);
371 /* When the buffer is too small, win7_32 and w2k8_64 and above fail with
372 E_NOT_SUFFICIENT_BUFFER, win8 ERROR_CANNOT_COPY,
373 other versions succeed and return a partial 0 terminated result while other versions
374 fail with E_INVALIDARG and return a partial unterminated result */
375 ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
376 ((hr == E_NOT_SUFFICIENT_BUFFER) && !len) ||
378 "=1: got 0x%x with %d and %s\n", hr, len, buffer);
379
380 len = 0;
381 memset(buffer, '#', maxlen);
382 buffer[maxlen] = 0;
383 hr = pGetAcceptLanguagesA( buffer, &len);
384 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG, win8 ERROR_CANNOT_COPY */
386 "got 0x%x\n", hr);
387
388 memset(buffer, '#', maxlen);
389 buffer[maxlen] = 0;
390 hr = pGetAcceptLanguagesA( buffer, NULL);
391 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
392 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
393 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
394
395
396 hr = pGetAcceptLanguagesA( NULL, NULL);
397 /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
398 ok((hr == E_FAIL) || (hr == E_INVALIDARG),
399 "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);
400
401restore_original:
402 if (!res_query) {
403 len = lstrlenA(original);
404 lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) original, len ? len + 1: 0);
405 ok(!lres, "RegSetValueEx(%s) failed: %d\n", original, lres);
406 }
407 else
408 {
410 }
411 RegCloseKey(hroot);
412}
413
414static void test_SHSearchMapInt(void)
415{
416 int keys[8], values[8];
417 int i = 0;
418
419 if (!pSHSearchMapInt)
420 return;
421
422 memset(keys, 0, sizeof(keys));
423 memset(values, 0, sizeof(values));
424 keys[0] = 99; values[0] = 101;
425
426 /* NULL key/value lists crash native, so skip testing them */
427
428 /* 1 element */
429 i = pSHSearchMapInt(keys, values, 1, keys[0]);
430 ok(i == values[0], "Len 1, expected %d, got %d\n", values[0], i);
431
432 /* Key doesn't exist */
433 i = pSHSearchMapInt(keys, values, 1, 100);
434 ok(i == -1, "Len 1 - bad key, expected -1, got %d\n", i);
435
436 /* Len = 0 => not found */
437 i = pSHSearchMapInt(keys, values, 0, keys[0]);
438 ok(i == -1, "Len 1 - passed len 0, expected -1, got %d\n", i);
439
440 /* 2 elements, len = 1 */
441 keys[1] = 98; values[1] = 102;
442 i = pSHSearchMapInt(keys, values, 1, keys[1]);
443 ok(i == -1, "Len 1 - array len 2, expected -1, got %d\n", i);
444
445 /* 2 elements, len = 2 */
446 i = pSHSearchMapInt(keys, values, 2, keys[1]);
447 ok(i == values[1], "Len 2, expected %d, got %d\n", values[1], i);
448
449 /* Searches forward */
450 keys[2] = 99; values[2] = 103;
451 i = pSHSearchMapInt(keys, values, 3, keys[0]);
452 ok(i == values[0], "Len 3, expected %d, got %d\n", values[0], i);
453}
454
456{
459};
460
461static void test_alloc_shared(int argc, char **argv)
462{
463 char cmdline[MAX_PATH];
465 STARTUPINFOA si = { 0 };
467 HANDLE hmem, hmem2 = 0;
468 struct shared_struct val, *p;
469 BOOL ret;
470
472 hmem=pSHAllocShared(NULL,10,procid);
473 ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
474 ret = pSHFreeShared(hmem, procid);
475 ok( ret, "SHFreeShared failed: %u\n", GetLastError());
476
477 val.value = 0x12345678;
478 val.handle = 0;
479 hmem = pSHAllocShared(&val, sizeof(val), procid);
480 ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
481
482 p=pSHLockShared(hmem,procid);
483 ok(p!=NULL,"SHLockShared failed: %u\n", GetLastError());
484 if (p!=NULL)
485 ok(p->value == 0x12345678, "Wrong value in shared memory: %d instead of %d\n", p->value, 0x12345678);
486 ret = pSHUnlockShared(p);
487 ok( ret, "SHUnlockShared failed: %u\n", GetLastError());
488
489 sprintf(cmdline, "%s %s %d %p", argv[0], argv[1], procid, hmem);
490 ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
491 ok(ret, "could not create child process error: %u\n", GetLastError());
492 if (ret)
493 {
495 CloseHandle(pi.hThread);
496 CloseHandle(pi.hProcess);
497
498 p = pSHLockShared(hmem, procid);
499 ok(p != NULL,"SHLockShared failed: %u\n", GetLastError());
500 if (p != NULL && p->value != 0x12345678)
501 {
502 ok(p->value == 0x12345679, "Wrong value in shared memory: %d instead of %d\n", p->value, 0x12345679);
503 hmem2 = p->handle;
504 ok(hmem2 != NULL, "Expected handle in shared memory\n");
505 }
506 ret = pSHUnlockShared(p);
507 ok(ret, "SHUnlockShared failed: %u\n", GetLastError());
508 }
509
510 ret = pSHFreeShared(hmem, procid);
511 ok( ret, "SHFreeShared failed: %u\n", GetLastError());
512
513 if (hmem2)
514 {
515 p = pSHLockShared(hmem2, procid);
516 ok(p != NULL,"SHLockShared failed: %u\n", GetLastError());
517 if (p != NULL)
518 ok(p->value == 0xDEADBEEF, "Wrong value in shared memory: %d instead of %d\n", p->value, 0xDEADBEEF);
519 ret = pSHUnlockShared(p);
520 ok(ret, "SHUnlockShared failed: %u\n", GetLastError());
521
522 ret = pSHFreeShared(hmem2, procid);
523 ok(ret, "SHFreeShared failed: %u\n", GetLastError());
524 }
525
526 SetLastError(0xdeadbeef);
527 ret = pSHFreeShared(NULL, procid);
528 ok(ret, "SHFreeShared failed: %u\n", GetLastError());
529 ok(GetLastError() == 0xdeadbeef, "last error should not have changed, got %u\n", GetLastError());
530}
531
533{
534 struct shared_struct val, *p;
535 HANDLE hmem2;
536 BOOL ret;
537
538 /* test directly accessing shared memory of a remote process */
539 p = pSHLockShared(hmem, procid);
540 ok(p != NULL || broken(p == NULL) /* Windows 7/8 */, "SHLockShared failed: %u\n", GetLastError());
541 if (p == NULL)
542 {
543 win_skip("Subprocess failed to modify shared memory, skipping test\n");
544 return;
545 }
546
547 ok(p->value == 0x12345678, "Wrong value in shared memory: %d instead of %d\n", p->value, 0x12345678);
548 p->value++;
549
550 val.value = 0xDEADBEEF;
551 val.handle = 0;
552 p->handle = pSHAllocShared(&val, sizeof(val), procid);
553 ok(p->handle != NULL, "SHAllocShared failed: %u\n", GetLastError());
554
555 ret = pSHUnlockShared(p);
556 ok(ret, "SHUnlockShared failed: %u\n", GetLastError());
557
558 /* test SHMapHandle */
559 SetLastError(0xdeadbeef);
560 hmem2 = pSHMapHandle(NULL, procid, GetCurrentProcessId(), 0, 0);
561 ok(hmem2 == NULL, "expected NULL, got new handle\n");
562 ok(GetLastError() == 0xdeadbeef, "last error should not have changed, got %u\n", GetLastError());
563
564 hmem2 = pSHMapHandle(hmem, procid, GetCurrentProcessId(), 0, 0);
565
566 /* It seems like Windows Vista/2008 uses a different internal implementation
567 * for shared memory, and calling SHMapHandle fails. */
568 ok(hmem2 != NULL || broken(hmem2 == NULL),
569 "SHMapHandle failed: %u\n", GetLastError());
570 if (hmem2 == NULL)
571 {
572 win_skip("Subprocess failed to map shared memory, skipping test\n");
573 return;
574 }
575
576 p = pSHLockShared(hmem2, GetCurrentProcessId());
577 ok(p != NULL, "SHLockShared failed: %u\n", GetLastError());
578
579 if (p != NULL)
580 ok(p->value == 0x12345679, "Wrong value in shared memory: %d instead of %d\n", p->value, 0x12345679);
581
582 ret = pSHUnlockShared(p);
583 ok(ret, "SHUnlockShared failed: %u\n", GetLastError());
584
585 ret = pSHFreeShared(hmem2, GetCurrentProcessId());
586 ok(ret, "SHFreeShared failed: %u\n", GetLastError());
587}
588
589static void test_fdsa(void)
590{
591 typedef struct
592 {
593 DWORD num_items; /* Number of elements inserted */
594 void *mem; /* Ptr to array */
595 DWORD blocks_alloced; /* Number of elements allocated */
596 BYTE inc; /* Number of elements to grow by when we need to expand */
597 BYTE block_size; /* Size in bytes of an element */
598 BYTE flags; /* Flags */
599 } FDSA_info;
600
601 BOOL (WINAPI *pFDSA_Initialize)(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
602 DWORD init_blocks);
603 BOOL (WINAPI *pFDSA_Destroy)(FDSA_info *info);
604 DWORD (WINAPI *pFDSA_InsertItem)(FDSA_info *info, DWORD where, const void *block);
605 BOOL (WINAPI *pFDSA_DeleteItem)(FDSA_info *info, DWORD where);
606
608 int block_size = 10, init_blocks = 4, inc = 2;
609 DWORD ret;
610 char *mem;
611
612 pFDSA_Initialize = (void *)GetProcAddress(hShlwapi, (LPSTR)208);
613 pFDSA_Destroy = (void *)GetProcAddress(hShlwapi, (LPSTR)209);
614 pFDSA_InsertItem = (void *)GetProcAddress(hShlwapi, (LPSTR)210);
615 pFDSA_DeleteItem = (void *)GetProcAddress(hShlwapi, (LPSTR)211);
616
617 mem = HeapAlloc(GetProcessHeap(), 0, block_size * init_blocks);
618 memset(&info, 0, sizeof(info));
619
620 ok(pFDSA_Initialize(block_size, inc, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
621 ok(info.num_items == 0, "num_items = %d\n", info.num_items);
622 ok(info.mem == mem, "mem = %p\n", info.mem);
623 ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
624 ok(info.inc == inc, "inc = %d\n", info.inc);
625 ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
626 ok(info.flags == 0, "flags = %d\n", info.flags);
627
628 ret = pFDSA_InsertItem(&info, 1234, "1234567890");
629 ok(ret == 0, "ret = %d\n", ret);
630 ok(info.num_items == 1, "num_items = %d\n", info.num_items);
631 ok(info.mem == mem, "mem = %p\n", info.mem);
632 ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
633 ok(info.inc == inc, "inc = %d\n", info.inc);
634 ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
635 ok(info.flags == 0, "flags = %d\n", info.flags);
636
637 ret = pFDSA_InsertItem(&info, 1234, "abcdefghij");
638 ok(ret == 1, "ret = %d\n", ret);
639
640 ret = pFDSA_InsertItem(&info, 1, "klmnopqrst");
641 ok(ret == 1, "ret = %d\n", ret);
642
643 ret = pFDSA_InsertItem(&info, 0, "uvwxyzABCD");
644 ok(ret == 0, "ret = %d\n", ret);
645 ok(info.mem == mem, "mem = %p\n", info.mem);
646 ok(info.flags == 0, "flags = %d\n", info.flags);
647
648 /* This next InsertItem will cause shlwapi to allocate its own mem buffer */
649 ret = pFDSA_InsertItem(&info, 0, "EFGHIJKLMN");
650 ok(ret == 0, "ret = %d\n", ret);
651 ok(info.mem != mem, "mem = %p\n", info.mem);
652 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
653 ok(info.flags == 0x1, "flags = %d\n", info.flags);
654
655 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info.mem);
656
657 ok(pFDSA_DeleteItem(&info, 2), "rets FALSE\n");
658 ok(info.mem != mem, "mem = %p\n", info.mem);
659 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
660 ok(info.flags == 0x1, "flags = %d\n", info.flags);
661
662 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info.mem);
663
664 ok(pFDSA_DeleteItem(&info, 3), "rets FALSE\n");
665 ok(info.mem != mem, "mem = %p\n", info.mem);
666 ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
667 ok(info.flags == 0x1, "flags = %d\n", info.flags);
668
669 ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info.mem);
670
671 ok(!pFDSA_DeleteItem(&info, 4), "does not ret FALSE\n");
672
673 /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
674 ok(!pFDSA_Destroy(&info), "FDSA_Destroy does not ret FALSE\n");
675
676
677 /* When Initialize is called with inc = 0, set it to 1 */
678 ok(pFDSA_Initialize(block_size, 0, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
679 ok(info.inc == 1, "inc = %d\n", info.inc);
680
681 /* This time, because shlwapi hasn't had to allocate memory
682 internally, Destroy rets non-zero */
683 ok(pFDSA_Destroy(&info), "FDSA_Destroy rets FALSE\n");
684
685
687}
688
690{
691 static const SHELL_USER_PERMISSION supCurrentUserFull = {
692 { {SECURITY_NULL_SID_AUTHORITY}, 0, 0 },
694 GENERIC_ALL, 0, 0 };
695#define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
696 static const SHELL_USER_PERMISSION supEveryoneDenied = {
700 const SHELL_USER_PERMISSION* rgsup[2] = {
701 &supCurrentUserFull, &supEveryoneDenied,
702 };
704
705 if(!pGetShellSecurityDescriptor) /* vista and later */
706 {
707 win_skip("GetShellSecurityDescriptor not available\n");
708 return;
709 }
710
712 ok(psd==NULL, "GetShellSecurityDescriptor should fail\n");
713 psd = pGetShellSecurityDescriptor(rgsup, 0);
714 ok(psd==NULL, "GetShellSecurityDescriptor should fail, got %p\n", psd);
715
716 SetLastError(0xdeadbeef);
717 psd = pGetShellSecurityDescriptor(rgsup, 2);
718 ok(psd!=NULL, "GetShellSecurityDescriptor failed\n");
719 if (psd!=NULL)
720 {
721 BOOL bHasDacl = FALSE, bDefaulted, ret;
722 PACL pAcl;
723 DWORD dwRev;
725
726 ok(IsValidSecurityDescriptor(psd), "returned value is not valid SD\n");
727
729 ok(ret, "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
730 ok(0 == (control & SE_SELF_RELATIVE), "SD should be absolute\n");
731
732 ret = GetSecurityDescriptorDacl(psd, &bHasDacl, &pAcl, &bDefaulted);
733 ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
734
735 ok(bHasDacl, "SD has no DACL\n");
736 if (bHasDacl)
737 {
738 ok(!bDefaulted, "DACL should not be defaulted\n");
739
740 ok(pAcl != NULL, "NULL DACL!\n");
741 if (pAcl != NULL)
742 {
743 ACL_SIZE_INFORMATION asiSize;
744
745 ok(IsValidAcl(pAcl), "DACL is not valid\n");
746
747 ret = GetAclInformation(pAcl, &asiSize, sizeof(asiSize), AclSizeInformation);
748 ok(ret, "GetAclInformation failed with error %u\n", GetLastError());
749
750 ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %d entries\n", asiSize.AceCount);
751 if (asiSize.AceCount == 3)
752 {
753 ACCESS_ALLOWED_ACE *paaa; /* will use for DENIED too */
754
755 ret = GetAce(pAcl, 0, (LPVOID*)&paaa);
756 ok(ret, "GetAce failed with error %u\n", GetLastError());
758 "Invalid ACE type %d\n", paaa->Header.AceType);
759 ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
760 ok(paaa->Mask == GENERIC_ALL, "Invalid ACE mask %x\n", paaa->Mask);
761
762 ret = GetAce(pAcl, 1, (LPVOID*)&paaa);
763 ok(ret, "GetAce failed with error %u\n", GetLastError());
765 "Invalid ACE type %d\n", paaa->Header.AceType);
766 /* first one of two ACEs generated from inheritable entry - without inheritance */
767 ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
768 ok(paaa->Mask == GENERIC_WRITE, "Invalid ACE mask %x\n", paaa->Mask);
769
770 ret = GetAce(pAcl, 2, (LPVOID*)&paaa);
771 ok(ret, "GetAce failed with error %u\n", GetLastError());
773 "Invalid ACE type %d\n", paaa->Header.AceType);
774 /* second ACE - with inheritance */
776 "Invalid ACE flags %x\n", paaa->Header.AceFlags);
777 ok(paaa->Mask == GENERIC_READ, "Invalid ACE mask %x\n", paaa->Mask);
778 }
779 }
780 }
781
782 LocalFree(psd);
783 }
784}
785
786static void test_SHPackDispParams(void)
787{
788 DISPPARAMS params;
789 VARIANT vars[10];
791
792 memset(&params, 0xc0, sizeof(params));
793 memset(vars, 0xc0, sizeof(vars));
794 hres = pSHPackDispParams(&params, vars, 1, VT_I4, 0xdeadbeef);
795 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
796 ok(params.cArgs == 1, "params.cArgs = %d\n", params.cArgs);
797 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
798 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
799 ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
800 ok(V_VT(vars) == VT_I4, "V_VT(var) = %d\n", V_VT(vars));
801 ok(V_I4(vars) == 0xdeadbeef, "failed %x\n", V_I4(vars));
802
803 memset(&params, 0xc0, sizeof(params));
804 hres = pSHPackDispParams(&params, NULL, 0, 0);
805 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
806 ok(params.cArgs == 0, "params.cArgs = %d\n", params.cArgs);
807 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
808 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
809 ok(params.rgvarg == NULL, "params.rgvarg = %p\n", params.rgvarg);
810
811 memset(vars, 0xc0, sizeof(vars));
812 memset(&params, 0xc0, sizeof(params));
813 hres = pSHPackDispParams(&params, vars, 4, VT_BSTR, (void*)0xdeadbeef, VT_EMPTY, 10,
814 VT_I4, 100, VT_DISPATCH, (void*)0xdeadbeef);
815 ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
816 ok(params.cArgs == 4, "params.cArgs = %d\n", params.cArgs);
817 ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
818 ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
819 ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
820 ok(V_VT(vars) == VT_DISPATCH, "V_VT(vars[0]) = %x\n", V_VT(vars));
821 ok(V_I4(vars) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars));
822 ok(V_VT(vars+1) == VT_I4, "V_VT(vars[1]) = %d\n", V_VT(vars+1));
823 ok(V_I4(vars+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars+1));
824 ok(V_VT(vars+2) == VT_I4, "V_VT(vars[2]) = %d\n", V_VT(vars+2));
825 ok(V_I4(vars+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars+2));
826 ok(V_VT(vars+3) == VT_BSTR, "V_VT(vars[3]) = %d\n", V_VT(vars+3));
827 ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3));
828}
829
830typedef struct _disp
831{
835
836static inline Disp *impl_from_IDispatch(IDispatch *iface)
837{
838 return CONTAINING_RECORD(iface, Disp, IDispatch_iface);
839}
840
841typedef struct _contain
842{
845
849
851{
852 return CONTAINING_RECORD(iface, Contain, IConnectionPointContainer_iface);
853}
854
855typedef struct _cntptn
856{
859
865
867{
868 return CONTAINING_RECORD(iface, ConPt, IConnectionPoint_iface);
869}
870
871typedef struct _enum
872{
875
879
881{
882 return CONTAINING_RECORD(iface, EnumCon, IEnumConnections_iface);
883}
884
885typedef struct _enumpt
886{
889
890 int idx;
893
895{
896 return CONTAINING_RECORD(iface, EnumPt, IEnumConnectionPoints_iface);
897}
898
899
902 REFIID riid,
903 void **ppvObject)
904{
905 *ppvObject = NULL;
906
908 {
909 *ppvObject = This;
910 }
911
912 if (*ppvObject)
913 {
914 IDispatch_AddRef(This);
915 return S_OK;
916 }
917
918 trace("no interface\n");
919 return E_NOINTERFACE;
920}
921
923{
924 Disp *iface = impl_from_IDispatch(This);
925 return InterlockedIncrement(&iface->refCount);
926}
927
929{
930 Disp *iface = impl_from_IDispatch(This);
931 ULONG ret;
932
934 if (ret == 0)
936 return ret;
937}
938
941 UINT *pctinfo)
942{
943 return ERROR_SUCCESS;
944}
945
948 UINT iTInfo,
949 LCID lcid,
950 ITypeInfo **ppTInfo)
951{
952 return ERROR_SUCCESS;
953}
954
957 REFIID riid,
958 LPOLESTR *rgszNames,
959 UINT cNames,
960 LCID lcid,
961 DISPID *rgDispId)
962{
963 return ERROR_SUCCESS;
964}
965
968 DISPID dispIdMember,
969 REFIID riid,
970 LCID lcid,
971 WORD wFlags,
972 DISPPARAMS *pDispParams,
973 VARIANT *pVarResult,
974 EXCEPINFO *pExcepInfo,
975 UINT *puArgErr)
976{
977 trace("%p %x %s %x %x %p %p %p %p\n", This, dispIdMember, wine_dbgstr_guid(riid), lcid, wFlags,
978 pDispParams, pVarResult, pExcepInfo, puArgErr);
979
980 ok(dispIdMember == 0xa0 || dispIdMember == 0xa1, "Unknown dispIdMember\n");
981 ok(pDispParams != NULL, "Invoked with NULL pDispParams\n");
982 ok(wFlags == DISPATCH_METHOD, "Wrong flags %x\n",wFlags);
983 ok(lcid == 0,"Wrong lcid %x\n",lcid);
984 if (dispIdMember == 0xa0)
985 {
986 ok(pDispParams->cArgs == 0, "params.cArgs = %d\n", pDispParams->cArgs);
987 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
988 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
989 ok(pDispParams->rgvarg == NULL, "params.rgvarg = %p\n", pDispParams->rgvarg);
990 }
991 else if (dispIdMember == 0xa1)
992 {
993 ok(pDispParams->cArgs == 2, "params.cArgs = %d\n", pDispParams->cArgs);
994 ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
995 ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
996 ok(V_VT(pDispParams->rgvarg) == VT_BSTR, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg));
997 ok(V_I4(pDispParams->rgvarg) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams->rgvarg));
998 ok(V_VT(pDispParams->rgvarg+1) == VT_I4, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg+1));
999 ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams->rgvarg+1));
1000 }
1001
1002 return ERROR_SUCCESS;
1003}
1004
1005static const IDispatchVtbl disp_vtbl = {
1009
1014};
1015
1018 REFIID riid,
1019 void **ppvObject)
1020{
1021 *ppvObject = NULL;
1022
1024 {
1025 *ppvObject = This;
1026 }
1027
1028 if (*ppvObject)
1029 {
1030 IEnumConnections_AddRef(This);
1031 return S_OK;
1032 }
1033
1034 trace("no interface\n");
1035 return E_NOINTERFACE;
1036}
1037
1039{
1041 return InterlockedIncrement(&iface->refCount);
1042}
1043
1045{
1047 ULONG ret;
1048
1050 if (ret == 0)
1052 return ret;
1053}
1054
1057 ULONG cConnections,
1058 LPCONNECTDATA rgcd,
1059 ULONG *pcFetched)
1060{
1062
1063 if (cConnections > 0 && iface->idx < iface->pt->sinkCount)
1064 {
1065 rgcd->pUnk = iface->pt->sink[iface->idx];
1066 IUnknown_AddRef(iface->pt->sink[iface->idx]);
1067 rgcd->dwCookie=0xff;
1068 if (pcFetched)
1069 *pcFetched = 1;
1070 iface->idx++;
1071 return S_OK;
1072 }
1073
1074 return E_FAIL;
1075}
1076
1079 ULONG cConnections)
1080{
1081 return E_FAIL;
1082}
1083
1086{
1087 return E_FAIL;
1088}
1089
1092 IEnumConnections **ppEnum)
1093{
1094 return E_FAIL;
1095}
1096
1097static const IEnumConnectionsVtbl enum_vtbl = {
1098
1102 Enum_Next,
1103 Enum_Skip,
1104 Enum_Reset,
1106};
1107
1110 REFIID riid,
1111 void **ppvObject)
1112{
1113 *ppvObject = NULL;
1114
1116 {
1117 *ppvObject = This;
1118 }
1119
1120 if (*ppvObject)
1121 {
1122 IConnectionPoint_AddRef(This);
1123 return S_OK;
1124 }
1125
1126 trace("no interface\n");
1127 return E_NOINTERFACE;
1128}
1129
1132{
1134 return InterlockedIncrement(&iface->refCount);
1135}
1136
1139{
1141 ULONG ret;
1142
1144 if (ret == 0)
1145 {
1146 if (iface->sinkCount > 0)
1147 {
1148 int i;
1149 for (i = 0; i < iface->sinkCount; i++)
1150 {
1151 if (iface->sink[i])
1152 IUnknown_Release(iface->sink[i]);
1153 }
1154 HeapFree(GetProcessHeap(),0,iface->sink);
1155 }
1157 }
1158 return ret;
1159}
1160
1163 IID *pIID)
1164{
1165 static int i = 0;
1167 if (i==0)
1168 {
1169 i++;
1170 return E_FAIL;
1171 }
1172 else
1173 memcpy(pIID,&iface->id,sizeof(GUID));
1174 return S_OK;
1175}
1176
1180{
1182
1184 return S_OK;
1185}
1186
1189 IUnknown *pUnkSink,
1190 DWORD *pdwCookie)
1191{
1193
1194 if (iface->sinkCount == 0)
1195 iface->sink = HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
1196 else
1197 iface->sink = HeapReAlloc(GetProcessHeap(),0,iface->sink,sizeof(IUnknown*)*(iface->sinkCount+1));
1198 iface->sink[iface->sinkCount] = pUnkSink;
1199 IUnknown_AddRef(pUnkSink);
1200 iface->sinkCount++;
1201 *pdwCookie = iface->sinkCount;
1202 return S_OK;
1203}
1204
1207 DWORD dwCookie)
1208{
1210
1211 if (dwCookie > iface->sinkCount)
1212 return E_FAIL;
1213 else
1214 {
1215 IUnknown_Release(iface->sink[dwCookie-1]);
1216 iface->sink[dwCookie-1] = NULL;
1217 }
1218 return S_OK;
1219}
1220
1223 IEnumConnections **ppEnum)
1224{
1225 EnumCon *ec;
1226
1227 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon));
1228 ec->IEnumConnections_iface.lpVtbl = &enum_vtbl;
1229 ec->refCount = 1;
1231 ec->idx = 0;
1232 *ppEnum = &ec->IEnumConnections_iface;
1233
1234 return S_OK;
1235}
1236
1237static const IConnectionPointVtbl point_vtbl = {
1241
1247};
1248
1251 REFIID riid,
1252 void **ppvObject)
1253{
1254 *ppvObject = NULL;
1255
1257 {
1258 *ppvObject = This;
1259 }
1260
1261 if (*ppvObject)
1262 {
1263 IEnumConnectionPoints_AddRef(This);
1264 return S_OK;
1265 }
1266
1267 trace("no interface\n");
1268 return E_NOINTERFACE;
1269}
1270
1272{
1274 return InterlockedIncrement(&iface->refCount);
1275}
1276
1278{
1280 ULONG ret;
1281
1283 if (ret == 0)
1285 return ret;
1286}
1287
1290 ULONG cConnections,
1291 IConnectionPoint **rgcd,
1292 ULONG *pcFetched)
1293{
1295
1296 if (cConnections > 0 && iface->idx < iface->container->ptCount)
1297 {
1298 *rgcd = iface->container->pt[iface->idx];
1299 IConnectionPoint_AddRef(iface->container->pt[iface->idx]);
1300 if (pcFetched)
1301 *pcFetched = 1;
1302 iface->idx++;
1303 return S_OK;
1304 }
1305
1306 return E_FAIL;
1307}
1308
1311 ULONG cConnections)
1312{
1313 return E_FAIL;
1314}
1315
1318{
1319 return E_FAIL;
1320}
1321
1324 IEnumConnectionPoints **ppEnumPt)
1325{
1326 return E_FAIL;
1327}
1328
1329static const IEnumConnectionPointsVtbl enumpt_vtbl = {
1330
1338};
1339
1342 REFIID riid,
1343 void **ppvObject)
1344{
1345 *ppvObject = NULL;
1346
1348 {
1349 *ppvObject = This;
1350 }
1351
1352 if (*ppvObject)
1353 {
1354 IConnectionPointContainer_AddRef(This);
1355 return S_OK;
1356 }
1357
1358 trace("no interface\n");
1359 return E_NOINTERFACE;
1360}
1361
1364{
1366 return InterlockedIncrement(&iface->refCount);
1367}
1368
1371{
1373 ULONG ret;
1374
1376 if (ret == 0)
1377 {
1378 if (iface->ptCount > 0)
1379 {
1380 int i;
1381 for (i = 0; i < iface->ptCount; i++)
1382 IConnectionPoint_Release(iface->pt[i]);
1383 HeapFree(GetProcessHeap(),0,iface->pt);
1384 }
1386 }
1387 return ret;
1388}
1389
1392 IEnumConnectionPoints **ppEnum)
1393{
1394 EnumPt *ec;
1395
1396 ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt));
1398 ec->refCount = 1;
1399 ec->idx= 0;
1401 *ppEnum = &ec->IEnumConnectionPoints_iface;
1402
1403 return S_OK;
1404}
1405
1408 REFIID riid,
1409 IConnectionPoint **ppCP)
1410{
1412 ConPt *pt;
1413
1414 if (!IsEqualIID(riid, &IID_NULL) || iface->ptCount ==0)
1415 {
1416 pt = HeapAlloc(GetProcessHeap(),0,sizeof(ConPt));
1417 pt->IConnectionPoint_iface.lpVtbl = &point_vtbl;
1418 pt->refCount = 1;
1419 pt->sinkCount = 0;
1420 pt->sink = NULL;
1421 pt->container = iface;
1422 pt->id = IID_IDispatch;
1423
1424 if (iface->ptCount == 0)
1425 iface->pt =HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
1426 else
1427 iface->pt = HeapReAlloc(GetProcessHeap(),0,iface->pt,sizeof(IUnknown*)*(iface->ptCount+1));
1428 iface->pt[iface->ptCount] = &pt->IConnectionPoint_iface;
1429 iface->ptCount++;
1430
1431 *ppCP = &pt->IConnectionPoint_iface;
1432 }
1433 else
1434 {
1435 *ppCP = iface->pt[0];
1436 IUnknown_AddRef((IUnknown*)*ppCP);
1437 }
1438
1439 return S_OK;
1440}
1441
1442static const IConnectionPointContainerVtbl contain_vtbl = {
1446
1449};
1450
1451static void test_IConnectionPoint(void)
1452{
1453 HRESULT rc;
1454 ULONG ref;
1457 Disp *dispatch;
1458 DWORD cookie = 0xffffffff;
1459 DISPPARAMS params;
1460 VARIANT vars[10];
1461
1463 container->IConnectionPointContainer_iface.lpVtbl = &contain_vtbl;
1464 container->refCount = 1;
1465 container->ptCount = 0;
1466 container->pt = NULL;
1467
1468 dispatch = HeapAlloc(GetProcessHeap(),0,sizeof(Disp));
1469 dispatch->IDispatch_iface.lpVtbl = &disp_vtbl;
1470 dispatch->refCount = 1;
1471
1472 rc = pConnectToConnectionPoint((IUnknown*)dispatch, &IID_NULL, TRUE, (IUnknown*)container, &cookie, &point);
1473 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1474 ok(point != NULL, "returned ConnectionPoint is NULL\n");
1475 ok(cookie != 0xffffffff, "invalid cookie returned\n");
1476
1477 rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL);
1478 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1479
1480 memset(&params, 0xc0, sizeof(params));
1481 memset(vars, 0xc0, sizeof(vars));
1482 rc = pSHPackDispParams(&params, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe);
1483 ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc);
1484
1485 rc = pIConnectionPoint_SimpleInvoke(point,0xa1,&params);
1486 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1487
1488 rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL);
1489 ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
1490
1491/* MSDN says this should be required but it crashs on XP
1492 IUnknown_Release(point);
1493*/
1494 ref = IUnknown_Release((IUnknown*)container);
1495 ok(ref == 0, "leftover IConnectionPointContainer reference %i\n",ref);
1496 ref = IUnknown_Release((IUnknown*)dispatch);
1497 ok(ref == 0, "leftover IDispatch reference %i\n",ref);
1498}
1499
1500typedef struct _propbag
1501{
1504
1506
1508{
1509 return CONTAINING_RECORD(iface, PropBag, IPropertyBag_iface);
1510}
1511
1512
1515 REFIID riid,
1516 void **ppvObject)
1517{
1518 *ppvObject = NULL;
1519
1521 {
1522 *ppvObject = This;
1523 }
1524
1525 if (*ppvObject)
1526 {
1527 IPropertyBag_AddRef(This);
1528 return S_OK;
1529 }
1530
1531 trace("no interface\n");
1532 return E_NOINTERFACE;
1533}
1534
1537{
1539 return InterlockedIncrement(&iface->refCount);
1540}
1541
1544{
1546 ULONG ret;
1547
1549 if (ret == 0)
1551 return ret;
1552}
1553
1556 LPCOLESTR pszPropName,
1557 VARIANT *pVar,
1558 IErrorLog *pErrorLog)
1559{
1560 V_VT(pVar) = VT_BLOB|VT_BYREF;
1561 V_BYREF(pVar) = (LPVOID)0xdeadcafe;
1562 return S_OK;
1563}
1564
1567 LPCOLESTR pszPropName,
1568 VARIANT *pVar)
1569{
1570 return S_OK;
1571}
1572
1573
1574static const IPropertyBagVtbl prop_vtbl = {
1578
1579 Prop_Read,
1581};
1582
1584{
1585 PropBag *pb;
1586 HRESULT rc;
1587 LONG out;
1588 static const WCHAR szName1[] = {'n','a','m','e','1',0};
1589
1590 pb = HeapAlloc(GetProcessHeap(),0,sizeof(PropBag));
1591 pb->refCount = 1;
1592 pb->IPropertyBag_iface.lpVtbl = &prop_vtbl;
1593
1594 out = 0xfeedface;
1595 rc = pSHPropertyBag_ReadLONG(NULL, szName1, &out);
1596 ok(rc == E_INVALIDARG || broken(rc == S_OK), "incorrect return %x\n",rc);
1597 ok(out == 0xfeedface, "value should not have changed\n");
1598 rc = pSHPropertyBag_ReadLONG(&pb->IPropertyBag_iface, NULL, &out);
1599 ok(rc == E_INVALIDARG || broken(rc == S_OK) || broken(rc == S_FALSE), "incorrect return %x\n",rc);
1600 ok(out == 0xfeedface, "value should not have changed\n");
1601 rc = pSHPropertyBag_ReadLONG(&pb->IPropertyBag_iface, szName1, NULL);
1602 ok(rc == E_INVALIDARG || broken(rc == S_OK) || broken(rc == S_FALSE), "incorrect return %x\n",rc);
1603 rc = pSHPropertyBag_ReadLONG(&pb->IPropertyBag_iface, szName1, &out);
1604 ok(rc == DISP_E_BADVARTYPE || broken(rc == S_OK) || broken(rc == S_FALSE), "incorrect return %x\n",rc);
1605 ok(out == 0xfeedface || broken(out == 0xfeedfa00), "value should not have changed %x\n",out);
1606 IUnknown_Release((IUnknown*)pb);
1607}
1608
1609static void test_SHSetWindowBits(void)
1610{
1611 HWND hwnd;
1612 DWORD style, styleold;
1613 WNDCLASSA clsA;
1614
1615 clsA.style = 0;
1617 clsA.cbClsExtra = 0;
1618 clsA.cbWndExtra = 0;
1620 clsA.hIcon = 0;
1621 clsA.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
1622 clsA.hbrBackground = NULL;
1623 clsA.lpszMenuName = NULL;
1624 clsA.lpszClassName = "Shlwapi test class";
1625 RegisterClassA(&clsA);
1626
1627 hwnd = CreateWindowA("Shlwapi test class", "Test", WS_VISIBLE, 0, 0, 100, 100,
1629 ok(IsWindow(hwnd), "failed to create window\n");
1630
1631 /* null window */
1632 SetLastError(0xdeadbeef);
1633 style = pSHSetWindowBits(NULL, GWL_STYLE, 0, 0);
1634 ok(style == 0, "expected 0 retval, got %d\n", style);
1636 "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError());
1637
1638 /* zero mask, zero flags */
1639 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1640 style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, 0);
1641 ok(styleold == style, "expected old style\n");
1642 ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n");
1643
1644 /* test mask */
1645 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1646 ok(styleold & WS_VISIBLE, "expected WS_VISIBLE\n");
1647 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1648
1649 ok(style == styleold, "expected previous style, got %x\n", style);
1650 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1651
1652 /* test mask, unset style bit used */
1653 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1654 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1655 ok(style == styleold, "expected previous style, got %x\n", style);
1656 ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n");
1657
1658 /* set back with flags */
1659 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1660 style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, WS_VISIBLE);
1661 ok(style == styleold, "expected previous style, got %x\n", style);
1662 ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "expected updated style\n");
1663
1664 /* reset and try to set without a mask */
1665 pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
1666 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1667 styleold = GetWindowLongA(hwnd, GWL_STYLE);
1668 style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, WS_VISIBLE);
1669 ok(style == styleold, "expected previous style, got %x\n", style);
1670 ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
1671
1673
1674 UnregisterClassA("Shlwapi test class", GetModuleHandleA(NULL));
1675}
1676
1677static void test_SHFormatDateTimeA(void)
1678{
1680 CHAR buff[100], buff2[100], buff3[100];
1681 SYSTEMTIME st;
1682 DWORD flags;
1683 INT ret;
1684
1685if (0)
1686{
1687 /* crashes on native */
1688 pSHFormatDateTimeA(NULL, NULL, NULL, 0);
1689}
1690
1691 GetLocalTime(&st);
1693 /* SHFormatDateTime expects input as utc */
1695
1696 /* no way to get required buffer length here */
1697 SetLastError(0xdeadbeef);
1698 ret = pSHFormatDateTimeA(&filetime, NULL, NULL, 0);
1699 ok(ret == 0, "got %d\n", ret);
1700 ok(GetLastError() == 0xdeadbeef || broken(GetLastError() == ERROR_SUCCESS /* Win7 */),
1701 "expected 0xdeadbeef, got %d\n", GetLastError());
1702
1703 SetLastError(0xdeadbeef);
1704 buff[0] = 'a'; buff[1] = 0;
1705 ret = pSHFormatDateTimeA(&filetime, NULL, buff, 0);
1706 ok(ret == 0, "got %d\n", ret);
1707 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1708 ok(buff[0] == 'a', "expected same string, got %s\n", buff);
1709
1710 /* flags needs to have FDTF_NOAUTOREADINGORDER for these tests to succeed on Vista+ */
1711
1712 /* all combinations documented as invalid succeeded */
1714 SetLastError(0xdeadbeef);
1715 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1716 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1717 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1718
1720 SetLastError(0xdeadbeef);
1721 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1722 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1723 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1724
1726 SetLastError(0xdeadbeef);
1727 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1728 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1729 ok(GetLastError() == 0xdeadbeef,
1730 "expected 0xdeadbeef, got %d\n", GetLastError());
1731
1732 /* now check returned strings */
1734 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1735 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1736 ret = GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2));
1737 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1738 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1739
1741 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1742 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1743 ret = GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2));
1744 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1745 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1746
1747 /* both time flags */
1749 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1750 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1751 ret = GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2));
1752 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1753 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1754
1756 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1757 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1758 ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1759 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1760 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1761
1763 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1764 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1765 ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1766 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1767 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1768
1769 /* both date flags */
1771 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1772 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1773 ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1774 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1775 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1776
1777 /* various combinations of date/time flags */
1779 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1780 ok(ret == lstrlenA(buff)+1, "got %d, length %d\n", ret, lstrlenA(buff)+1);
1781 ret = GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3));
1782 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1783 ok(lstrcmpA(buff3, buff + lstrlenA(buff) - lstrlenA(buff3)) == 0,
1784 "expected (%s), got (%s) for time part\n",
1785 buff3, buff + lstrlenA(buff) - lstrlenA(buff3));
1786 ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1787 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1788 buff[lstrlenA(buff2)] = '\0';
1789 ok(lstrcmpA(buff2, buff) == 0, "expected (%s) got (%s) for date part\n",
1790 buff2, buff);
1791
1793 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1794 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1795 ret = GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3));
1796 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1797 ok(lstrcmpA(buff3, buff + lstrlenA(buff) - lstrlenA(buff3)) == 0,
1798 "expected (%s), got (%s) for time part\n",
1799 buff3, buff + lstrlenA(buff) - lstrlenA(buff3));
1800 ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
1801 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1802 buff[lstrlenA(buff2)] = '\0';
1803 ok(lstrcmpA(buff2, buff) == 0, "expected (%s) got (%s) for date part\n",
1804 buff2, buff);
1805
1807 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1808 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1809 ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1810 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1811 strcat(buff2, " ");
1812 ret = GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3));
1813 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1814 strcat(buff2, buff3);
1815 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1816
1818 ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
1819 ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
1820 ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
1821 ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
1822 strcat(buff2, " ");
1823 ret = GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3));
1824 ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
1825 strcat(buff2, buff3);
1826 ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
1827}
1828
1829static void test_SHFormatDateTimeW(void)
1830{
1832 WCHAR buff[100], buff2[100], buff3[100], *p1, *p2;
1833 SYSTEMTIME st;
1834 DWORD flags;
1835 INT ret;
1836 static const WCHAR spaceW[] = {' ',0};
1837#define UNICODE_LTR_MARK 0x200e
1838#define UNICODE_RTL_MARK 0x200f
1839
1840if (0)
1841{
1842 /* crashes on native */
1843 pSHFormatDateTimeW(NULL, NULL, NULL, 0);
1844}
1845
1846 GetLocalTime(&st);
1848 /* SHFormatDateTime expects input as utc */
1850
1851 /* no way to get required buffer length here */
1852 SetLastError(0xdeadbeef);
1853 ret = pSHFormatDateTimeW(&filetime, NULL, NULL, 0);
1854 ok(ret == 0, "expected 0, got %d\n", ret);
1855 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1856
1857 SetLastError(0xdeadbeef);
1858 buff[0] = 'a'; buff[1] = 0;
1859 ret = pSHFormatDateTimeW(&filetime, NULL, buff, 0);
1860 ok(ret == 0, "expected 0, got %d\n", ret);
1861 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1862 ok(buff[0] == 'a', "expected same string\n");
1863
1864 /* all combinations documented as invalid succeeded */
1866 SetLastError(0xdeadbeef);
1867 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1868 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1869 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1870 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1871
1873 SetLastError(0xdeadbeef);
1874 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1875 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1876 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1877 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
1878
1880 SetLastError(0xdeadbeef);
1881 buff[0] = 0; /* NT4 doesn't clear the buffer on failure */
1882 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1883 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1884 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1885 ok(GetLastError() == 0xdeadbeef,
1886 "expected 0xdeadbeef, got %d\n", GetLastError());
1887
1888 /* now check returned strings */
1890 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1891 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1892 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1893 SetLastError(0xdeadbeef);
1895 ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
1896 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1897
1899 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1900 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1901 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1902 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, ARRAY_SIZE(buff2));
1903 ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
1904 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1905
1906 /* both time flags */
1908 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1909 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1910 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1911 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, ARRAY_SIZE(buff2));
1912 ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
1913 ok(lstrcmpW(buff, buff2) == 0, "expected equal string\n");
1914
1916 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1917 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1918 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1920 ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
1921 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1922
1924 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1925 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1926 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1928 ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
1929 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1930
1931 /* both date flags */
1933 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1934 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1935 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1937 ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
1938 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
1939
1940 /* various combinations of date/time flags */
1942 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1943 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1944 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1946 ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
1947 ok(lstrcmpW(buff3, buff + lstrlenW(buff) - lstrlenW(buff3)) == 0,
1948 "expected (%s), got (%s) for time part\n",
1949 wine_dbgstr_w(buff3), wine_dbgstr_w(buff + lstrlenW(buff) - lstrlenW(buff3)));
1951 ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
1952 p1 = buff;
1953 p2 = buff2;
1954 while (*p2 != '\0')
1955 {
1956 while (*p1 == UNICODE_LTR_MARK || *p1 == UNICODE_RTL_MARK)
1957 p1++;
1958 while (*p2 == UNICODE_LTR_MARK || *p2 == UNICODE_RTL_MARK)
1959 p2++;
1960 p1++;
1961 p2++;
1962 }
1963 *p1 = '\0';
1964 ok(lstrcmpW(buff2, buff) == 0, "expected (%s) got (%s) for date part\n",
1966
1968 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1969 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1970 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1971 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, ARRAY_SIZE(buff3));
1972 ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
1973 ok(lstrcmpW(buff3, buff + lstrlenW(buff) - lstrlenW(buff3)) == 0,
1974 "expected (%s), got (%s) for time part\n",
1975 wine_dbgstr_w(buff3), wine_dbgstr_w(buff + lstrlenW(buff) - lstrlenW(buff3)));
1977 ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
1978 p1 = buff;
1979 p2 = buff2;
1980 while (*p2 != '\0')
1981 {
1982 while (*p1 == UNICODE_LTR_MARK || *p1 == UNICODE_RTL_MARK)
1983 p1++;
1984 while (*p2 == UNICODE_LTR_MARK || *p2 == UNICODE_RTL_MARK)
1985 p2++;
1986 p1++;
1987 p2++;
1988 }
1989 *p1 = '\0';
1990 ok(lstrcmpW(buff2, buff) == 0, "expected (%s) got (%s) for date part\n",
1992
1994 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
1995 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
1996 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
1998 ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
1999 lstrcatW(buff2, spaceW);
2001 ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
2002 lstrcatW(buff2, buff3);
2003 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
2004
2006 ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
2007 ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
2008 "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
2010 ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
2011 lstrcatW(buff2, spaceW);
2012 ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, ARRAY_SIZE(buff3));
2013 ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
2014 lstrcatW(buff2, buff3);
2015 ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
2016}
2017
2019{
2020 struct compat_value {
2021 CHAR nameA[30];
2022 DWORD value;
2023 };
2024
2025 struct compat_value values[] = {
2026 { "OTNEEDSSFCACHE", 0x1 },
2027 { "NO_WEBVIEW", 0x2 },
2028 { "UNBINDABLE", 0x4 },
2029 { "PINDLL", 0x8 },
2030 { "NEEDSFILESYSANCESTOR", 0x10 },
2031 { "NOTAFILESYSTEM", 0x20 },
2032 { "CTXMENU_NOVERBS", 0x40 },
2033 { "CTXMENU_LIMITEDQI", 0x80 },
2034 { "COCREATESHELLFOLDERONLY", 0x100 },
2035 { "NEEDSSTORAGEANCESTOR", 0x200 },
2036 { "NOLEGACYWEBVIEW", 0x400 },
2037 { "CTXMENU_XPQCMFLAGS", 0x1000 },
2038 { "NOIPROPERTYSTORE", 0x2000 }
2039 };
2040
2041 static const char compat_path[] = "Software\\Microsoft\\Windows\\CurrentVersion\\ShellCompatibility\\Objects";
2042 CHAR keyA[39]; /* {CLSID} */
2043 HKEY root;
2044 DWORD ret;
2045 int i;
2046
2047 /* null args */
2048 ret = pSHGetObjectCompatFlags(NULL, NULL);
2049 ok(ret == 0, "got %d\n", ret);
2050
2051 ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, compat_path, &root);
2052 if (ret != ERROR_SUCCESS)
2053 {
2054 skip("No compatibility class data found\n");
2055 return;
2056 }
2057
2058 for (i = 0; RegEnumKeyA(root, i, keyA, sizeof(keyA)) == ERROR_SUCCESS; i++)
2059 {
2060 HKEY clsid_key;
2061
2062 if (RegOpenKeyA(root, keyA, &clsid_key) == ERROR_SUCCESS)
2063 {
2064 CHAR valueA[30];
2065 DWORD expected = 0, got, length = sizeof(valueA);
2066 CLSID clsid;
2067 int v;
2068
2069 for (v = 0; RegEnumValueA(clsid_key, v, valueA, &length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; v++)
2070 {
2071 int j;
2072
2073 for (j = 0; j < ARRAY_SIZE(values); j++)
2074 if (lstrcmpA(values[j].nameA, valueA) == 0)
2075 {
2076 expected |= values[j].value;
2077 break;
2078 }
2079
2080 length = sizeof(valueA);
2081 }
2082
2083 pGUIDFromStringA(keyA, &clsid);
2084 got = pSHGetObjectCompatFlags(NULL, &clsid);
2085 ok(got == expected, "got 0x%08x, expected 0x%08x. Key %s\n", got, expected, keyA);
2086
2087 RegCloseKey(clsid_key);
2088 }
2089 }
2090
2092}
2093
2094typedef struct {
2098
2100{
2101 return CONTAINING_RECORD(iface, IOleCommandTargetImpl, IOleCommandTarget_iface);
2102}
2103
2104static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl;
2105
2107{
2109
2110 obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
2111 obj->IOleCommandTarget_iface.lpVtbl = &IOleCommandTargetImpl_Vtbl;
2112 obj->ref = 1;
2113
2114 return &obj->IOleCommandTarget_iface;
2115}
2116
2118{
2120
2121 if (IsEqualIID(riid, &IID_IUnknown) ||
2122 IsEqualIID(riid, &IID_IOleCommandTarget))
2123 {
2124 *ppvObj = This;
2125 }
2126
2127 if(*ppvObj)
2128 {
2129 IOleCommandTarget_AddRef(iface);
2130 return S_OK;
2131 }
2132
2133 return E_NOINTERFACE;
2134}
2135
2137{
2139 return InterlockedIncrement(&This->ref);
2140}
2141
2143{
2146
2147 if (!ref)
2148 {
2150 return 0;
2151 }
2152 return ref;
2153}
2154
2156 IOleCommandTarget *iface, const GUID *group, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
2157{
2158 return E_NOTIMPL;
2159}
2160
2162 IOleCommandTarget *iface,
2163 const GUID *CmdGroup,
2164 DWORD nCmdID,
2165 DWORD nCmdexecopt,
2166 VARIANT *pvaIn,
2167 VARIANT *pvaOut)
2168{
2169 add_call(&trace_got, 3, CmdGroup, (void*)(DWORD_PTR)nCmdID, (void*)(DWORD_PTR)nCmdexecopt, pvaIn, pvaOut);
2170 return S_OK;
2171}
2172
2173static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl =
2174{
2180};
2181
2182typedef struct {
2183 IServiceProvider IServiceProvider_iface;
2184 LONG ref;
2186
2188{
2189 return CONTAINING_RECORD(iface, IServiceProviderImpl, IServiceProvider_iface);
2190}
2191
2192typedef struct {
2196
2198{
2199 return CONTAINING_RECORD(iface, IProfferServiceImpl, IProfferService_iface);
2200}
2201
2202
2203static const IServiceProviderVtbl IServiceProviderImpl_Vtbl;
2204static const IProfferServiceVtbl IProfferServiceImpl_Vtbl;
2205
2207{
2209
2210 obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
2211 obj->IServiceProvider_iface.lpVtbl = &IServiceProviderImpl_Vtbl;
2212 obj->ref = 1;
2213
2214 return &obj->IServiceProvider_iface;
2215}
2216
2218{
2220
2221 obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
2222 obj->IProfferService_iface.lpVtbl = &IProfferServiceImpl_Vtbl;
2223 obj->ref = 1;
2224
2225 return &obj->IProfferService_iface;
2226}
2227
2229{
2231
2232 if (IsEqualIID(riid, &IID_IUnknown) ||
2233 IsEqualIID(riid, &IID_IServiceProvider))
2234 {
2235 *ppvObj = This;
2236 }
2237
2238 if(*ppvObj)
2239 {
2240 IServiceProvider_AddRef(iface);
2241 /* native uses redefined IID_IServiceProvider symbol, so we can't compare pointers */
2242 if (IsEqualIID(riid, &IID_IServiceProvider))
2243 add_call(&trace_got, 1, iface, &IID_IServiceProvider, 0, 0, 0);
2244 return S_OK;
2245 }
2246
2247 return E_NOINTERFACE;
2248}
2249
2251{
2253 return InterlockedIncrement(&This->ref);
2254}
2255
2257{
2260
2261 if (!ref)
2262 {
2264 return 0;
2265 }
2266 return ref;
2267}
2268
2270 IServiceProvider *iface, REFGUID service, REFIID riid, void **ppv)
2271{
2272 /* native uses redefined pointer for IID_IOleCommandTarget, not one from uuid.lib */
2273 if (IsEqualIID(riid, &IID_IOleCommandTarget))
2274 {
2275 add_call(&trace_got, 2, iface, service, &IID_IOleCommandTarget, 0, 0);
2277 }
2278 if (IsEqualIID(riid, &IID_IProfferService))
2279 {
2280 if (IsEqualIID(service, &IID_IProfferService))
2281 add_call(&trace_got, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0);
2283 }
2284 return S_OK;
2285}
2286
2287static const IServiceProviderVtbl IServiceProviderImpl_Vtbl =
2288{
2293};
2294
2296{
2297 IServiceProvider *provider;
2298 static const GUID dummy_serviceid = { 0xdeadbeef };
2299 static const GUID dummy_groupid = { 0xbeefbeef };
2300 call_trace_t trace_expected;
2301 HRESULT hr;
2302
2303 provider = IServiceProviderImpl_Construct();
2304
2305 /* null source pointer */
2306 hr = pIUnknown_QueryServiceExec(NULL, &dummy_serviceid, &dummy_groupid, 0, 0, 0, 0);
2307 ok(hr == E_FAIL ||
2308 hr == E_NOTIMPL, /* win 8 */
2309 "got 0x%08x\n", hr);
2310
2311 /* expected trace:
2312 IUnknown_QueryServiceExec( ptr1, serviceid, groupid, arg1, arg2, arg3, arg4);
2313 -> IUnknown_QueryInterface( ptr1, &IID_IServiceProvider, &prov );
2314 -> IServiceProvider_QueryService( prov, serviceid, &IID_IOleCommandTarget, &obj );
2315 -> IOleCommandTarget_Exec( obj, groupid, arg1, arg2, arg3, arg4 );
2316 */
2317 init_call_trace(&trace_expected);
2318
2319 add_call(&trace_expected, 1, provider, &IID_IServiceProvider, 0, 0, 0);
2320 add_call(&trace_expected, 2, provider, &dummy_serviceid, &IID_IOleCommandTarget, 0, 0);
2321 add_call(&trace_expected, 3, &dummy_groupid, (void*)0x1, (void*)0x2, (void*)0x3, (void*)0x4);
2322
2324 hr = pIUnknown_QueryServiceExec((IUnknown*)provider, &dummy_serviceid, &dummy_groupid, 0x1, 0x2, (void*)0x3, (void*)0x4);
2325 ok(hr == S_OK, "got 0x%08x\n", hr);
2326
2327 ok_trace(&trace_expected, &trace_got);
2328
2329 free_call_trace(&trace_expected);
2331
2332 IServiceProvider_Release(provider);
2333}
2334
2335
2337{
2339
2340 if (IsEqualIID(riid, &IID_IUnknown) ||
2341 IsEqualIID(riid, &IID_IProfferService))
2342 {
2343 *ppvObj = This;
2344 }
2345 else if (IsEqualIID(riid, &IID_IServiceProvider))
2346 {
2348 add_call(&trace_got, 1, iface, &IID_IServiceProvider, 0, 0, 0);
2349 return S_OK;
2350 }
2351
2352 if(*ppvObj)
2353 {
2354 IProfferService_AddRef(iface);
2355 return S_OK;
2356 }
2357
2358 return E_NOINTERFACE;
2359}
2360
2362{
2364 return InterlockedIncrement(&This->ref);
2365}
2366
2368{
2371
2372 if (!ref)
2373 {
2375 return 0;
2376 }
2377 return ref;
2378}
2379
2381 REFGUID service, IServiceProvider *pService, DWORD *pCookie)
2382{
2383 *pCookie = 0xdeadbeef;
2384 add_call(&trace_got, 3, service, pService, pCookie, 0, 0);
2385 return S_OK;
2386}
2387
2389{
2390 add_call(&trace_got, 4, (void*)(DWORD_PTR)cookie, 0, 0, 0, 0);
2391 return S_OK;
2392}
2393
2394static const IProfferServiceVtbl IProfferServiceImpl_Vtbl =
2395{
2401};
2402
2404{
2405 IServiceProvider *provider;
2406 IProfferService *proff;
2407 static const GUID dummy_serviceid = { 0xdeadbeef };
2408 call_trace_t trace_expected;
2409 HRESULT hr;
2410 DWORD cookie;
2411
2412 provider = IServiceProviderImpl_Construct();
2414
2415 /* null source pointer */
2416 hr = pIUnknown_ProfferService(NULL, &dummy_serviceid, 0, 0);
2417 ok(hr == E_FAIL ||
2418 hr == E_NOTIMPL, /* win 8 */
2419 "got 0x%08x\n", hr);
2420
2421 /* expected trace:
2422 IUnknown_ProfferService( ptr1, serviceid, arg1, arg2);
2423 -> IUnknown_QueryInterface( ptr1, &IID_IServiceProvider, &provider );
2424 -> IServiceProvider_QueryService( provider, &IID_IProfferService, &IID_IProfferService, &proffer );
2425
2426 if (service pointer not null):
2427 -> IProfferService_ProfferService( proffer, serviceid, arg1, arg2 );
2428 else
2429 -> IProfferService_RevokeService( proffer, *arg2 );
2430 */
2431 init_call_trace(&trace_expected);
2432
2433 add_call(&trace_expected, 1, proff, &IID_IServiceProvider, 0, 0, 0);
2434 add_call(&trace_expected, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0);
2435 add_call(&trace_expected, 3, &dummy_serviceid, provider, &cookie, 0, 0);
2436
2438 cookie = 0;
2439 hr = pIUnknown_ProfferService((IUnknown*)proff, &dummy_serviceid, provider, &cookie);
2440 ok(hr == S_OK, "got 0x%08x\n", hr);
2441 ok(cookie == 0xdeadbeef, "got %x\n", cookie);
2442
2443 ok_trace(&trace_expected, &trace_got);
2445 free_call_trace(&trace_expected);
2446
2447 /* same with ::Revoke path */
2448 init_call_trace(&trace_expected);
2449
2450 add_call(&trace_expected, 1, proff, &IID_IServiceProvider, 0, 0, 0);
2451 add_call(&trace_expected, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0);
2452 add_call(&trace_expected, 4, (void*)(DWORD_PTR)cookie, 0, 0, 0, 0);
2453
2455 ok(cookie != 0, "got %x\n", cookie);
2456 hr = pIUnknown_ProfferService((IUnknown*)proff, &dummy_serviceid, 0, &cookie);
2457 ok(hr == S_OK, "got 0x%08x\n", hr);
2458 ok(cookie == 0, "got %x\n", cookie);
2459 ok_trace(&trace_expected, &trace_got);
2461 free_call_trace(&trace_expected);
2462
2463 IServiceProvider_Release(provider);
2464 IProfferService_Release(proff);
2465}
2466
2468{
2469 WNDCLASSA cliA;
2470 char classA[20];
2471 HWND hwnd;
2472 LONG_PTR ret;
2473 BOOL res;
2474
2475 hwnd = pSHCreateWorkerWindowA(0, NULL, 0, 0, 0, 0);
2476 ok(hwnd != 0, "expected window\n");
2477
2478 GetClassNameA(hwnd, classA, 20);
2479 ok(lstrcmpA(classA, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA);
2480
2482 ok(ret == 0, "got %ld\n", ret);
2483
2484 /* class info */
2485 memset(&cliA, 0, sizeof(cliA));
2486 res = GetClassInfoA(GetModuleHandleA("shlwapi.dll"), "WorkerA", &cliA);
2487 ok(res, "failed to get class info\n");
2488 ok(cliA.style == 0, "got 0x%08x\n", cliA.style);
2489 ok(cliA.cbClsExtra == 0, "got %d\n", cliA.cbClsExtra);
2490 ok(cliA.cbWndExtra == sizeof(LONG_PTR), "got %d\n", cliA.cbWndExtra);
2491 ok(cliA.lpszMenuName == 0, "got %s\n", cliA.lpszMenuName);
2492
2494
2495 /* set extra bytes */
2496 hwnd = pSHCreateWorkerWindowA(0, NULL, 0, 0, 0, 0xdeadbeef);
2497 ok(hwnd != 0, "expected window\n");
2498
2499 GetClassNameA(hwnd, classA, 20);
2500 ok(lstrcmpA(classA, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA);
2501
2503 ok(ret == 0xdeadbeef, "got %ld\n", ret);
2504
2505 /* test exstyle */
2507 ok(ret == WS_EX_WINDOWEDGE ||
2508 ret == (WS_EX_WINDOWEDGE|WS_EX_LAYOUTRTL) /* systems with RTL locale */, "0x%08lx\n", ret);
2509
2511
2512 hwnd = pSHCreateWorkerWindowA(0, NULL, WS_EX_TOOLWINDOW, 0, 0, 0);
2515 ret == (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW|WS_EX_LAYOUTRTL) /* systems with RTL locale */, "0x%08lx\n", ret);
2517}
2518
2520 REFIID riid, void **ppv)
2521{
2522 /* SHIShellFolder_EnumObjects doesn't QI the object for IShellFolder */
2523 ok(!IsEqualGUID(&IID_IShellFolder, riid),
2524 "Unexpected QI for IShellFolder\n");
2525 return E_NOINTERFACE;
2526}
2527
2529{
2530 return 2;
2531}
2532
2534{
2535 return 1;
2536}
2537
2539 HWND owner, LPBC reserved, LPOLESTR displayName, ULONG *eaten,
2540 LPITEMIDLIST *idl, ULONG *attr)
2541{
2542 ok(0, "Didn't expect ParseDisplayName\n");
2543 return E_NOTIMPL;
2544}
2545
2547 HWND owner, SHCONTF flags, IEnumIDList **enm)
2548{
2549 *enm = (IEnumIDList*)0xcafebabe;
2550 return S_OK;
2551}
2552
2554 LPCITEMIDLIST idl, LPBC reserved, REFIID riid, void **obj)
2555{
2556 ok(0, "Didn't expect BindToObject\n");
2557 return E_NOTIMPL;
2558}
2559
2561 LPCITEMIDLIST idl, LPBC reserved, REFIID riid, void **obj)
2562{
2563 ok(0, "Didn't expect BindToStorage\n");
2564 return E_NOTIMPL;
2565}
2566
2569{
2570 ok(0, "Didn't expect CompareIDs\n");
2571 return E_NOTIMPL;
2572}
2573
2575 HWND owner, REFIID riid, void **out)
2576{
2577 ok(0, "Didn't expect CreateViewObject\n");
2578 return E_NOTIMPL;
2579}
2580
2582#ifdef __REACTOS__
2583 UINT cidl, PCUITEMID_CHILD_ARRAY idl, SFGAOF *inOut)
2584#else
2585 UINT cidl, LPCITEMIDLIST *idl, SFGAOF *inOut)
2586#endif
2587{
2588 ok(0, "Didn't expect GetAttributesOf\n");
2589 return E_NOTIMPL;
2590}
2591
2593#ifdef __REACTOS__
2594 HWND owner, UINT cidl, PCUITEMID_CHILD_ARRAY idls, REFIID riid, UINT *inOut,
2595#else
2596 HWND owner, UINT cidl, LPCITEMIDLIST *idls, REFIID riid, UINT *inOut,
2597#endif
2598 void **out)
2599{
2600 ok(0, "Didn't expect GetUIObjectOf\n");
2601 return E_NOTIMPL;
2602}
2603
2605 LPCITEMIDLIST idl, SHGDNF flags, STRRET *name)
2606{
2607 ok(0, "Didn't expect GetDisplayNameOf\n");
2608 return E_NOTIMPL;
2609}
2610
2612 HWND hwnd, LPCITEMIDLIST idl, LPCOLESTR name, SHGDNF flags,
2613 LPITEMIDLIST *idlOut)
2614{
2615 ok(0, "Didn't expect SetNameOf\n");
2616 return E_NOTIMPL;
2617}
2618
2619static IShellFolderVtbl ShellFolderVtbl = {
2621 SF_AddRef,
2622 SF_Release,
2633};
2634
2636
2638{
2639 IEnumIDList *enm;
2640 HRESULT hres;
2642
2643 if(!pSHIShellFolder_EnumObjects){ /* win7 and later */
2644 win_skip("SHIShellFolder_EnumObjects not available\n");
2645 return;
2646 }
2647
2648 if(0){
2649 /* NULL object crashes on Windows */
2650 pSHIShellFolder_EnumObjects(NULL, NULL, 0, NULL);
2651 }
2652
2653 /* SHIShellFolder_EnumObjects doesn't QI the object for IShellFolder */
2654 enm = (IEnumIDList*)0xdeadbeef;
2655 hres = pSHIShellFolder_EnumObjects(&ShellFolder, NULL, 0, &enm);
2656 ok(hres == S_OK, "SHIShellFolder_EnumObjects failed: 0x%08x\n", hres);
2657 ok(enm == (IEnumIDList*)0xcafebabe, "Didn't get expected enumerator location, instead: %p\n", enm);
2658
2659 /* SHIShellFolder_EnumObjects isn't strict about the IShellFolder object */
2661 ok(hres == S_OK, "SHGetDesktopFolder failed: 0x%08x\n", hres);
2662
2663 enm = NULL;
2664 hres = pSHIShellFolder_EnumObjects(folder, NULL, 0, &enm);
2665 ok(hres == S_OK, "SHIShellFolder_EnumObjects failed: 0x%08x\n", hres);
2666 ok(enm != NULL, "Didn't get an enumerator\n");
2667 if(enm)
2668 IEnumIDList_Release(enm);
2669
2670 IShellFolder_Release(folder);
2671}
2672
2674{
2675 DWORD written;
2676 HANDLE file;
2677
2678 static const char data[] =
2679 "[TestApp]\r\n"
2680 "AKey=1\r\n"
2681 "AnotherKey=asdf\r\n";
2682
2684 if(file == INVALID_HANDLE_VALUE) {
2685 win_skip("failed to create ini file at %s\n", wine_dbgstr_w(filename));
2686 return FALSE;
2687 }
2688
2689 WriteFile(file, data, sizeof(data), &written, NULL);
2690
2692
2693 return TRUE;
2694}
2695
2696#define verify_inifile(f, e) r_verify_inifile(__LINE__, f, e)
2698{
2699 HANDLE file;
2700 CHAR buf[1024];
2701 DWORD read;
2702
2704
2706 return;
2707
2708 ReadFile(file, buf, sizeof(buf) * sizeof(CHAR), &read, NULL);
2709 buf[read] = '\0';
2710
2712
2713 ok_(__FILE__,l)(!strcmp(buf, exp), "Expected:\n%s\nGot:\n%s\n", exp,
2714 buf);
2715}
2716
2717static void test_SHGetIniString(void)
2718{
2719 DWORD ret;
2720 WCHAR out[64] = {0};
2721
2722 static const WCHAR TestAppW[] = {'T','e','s','t','A','p','p',0};
2723 static const WCHAR AKeyW[] = {'A','K','e','y',0};
2724 static const WCHAR AnotherKeyW[] = {'A','n','o','t','h','e','r','K','e','y',0};
2725 static const WCHAR JunkKeyW[] = {'J','u','n','k','K','e','y',0};
2726 static const WCHAR testpathW[] = {'C',':','\\','t','e','s','t','.','i','n','i',0};
2727 WCHAR pathW[MAX_PATH];
2728
2729 lstrcpyW(pathW, testpathW);
2730
2731 if (!write_inifile(pathW))
2732 return;
2733
2734 if(0){
2735 /* these crash on Windows */
2736 pSHGetIniStringW(NULL, NULL, NULL, 0, NULL);
2737 pSHGetIniStringW(NULL, AKeyW, out, ARRAY_SIZE(out), pathW);
2738 pSHGetIniStringW(TestAppW, AKeyW, NULL, ARRAY_SIZE(out), pathW);
2739 }
2740
2741 ret = pSHGetIniStringW(TestAppW, AKeyW, out, 0, pathW);
2742 ok(ret == 0, "SHGetIniStringW should have given 0, instead: %d\n", ret);
2743
2744 /* valid arguments */
2745 out[0] = 0;
2746 SetLastError(0xdeadbeef);
2747 ret = pSHGetIniStringW(TestAppW, NULL, out, ARRAY_SIZE(out), pathW);
2748 ok(ret == 4, "SHGetIniStringW should have given 4, instead: %d\n", ret);
2749 ok(!lstrcmpW(out, AKeyW), "Expected %s, got: %s, %d\n",
2751
2752 ret = pSHGetIniStringW(TestAppW, AKeyW, out, ARRAY_SIZE(out), pathW);
2753 ok(ret == 1, "SHGetIniStringW should have given 1, instead: %d\n", ret);
2754 ok(!strcmp_wa(out, "1"), "Expected L\"1\", got: %s\n", wine_dbgstr_w(out));
2755
2756 ret = pSHGetIniStringW(TestAppW, AnotherKeyW, out, ARRAY_SIZE(out), pathW);
2757 ok(ret == 4, "SHGetIniStringW should have given 4, instead: %d\n", ret);
2758 ok(!strcmp_wa(out, "asdf"), "Expected L\"asdf\", got: %s\n", wine_dbgstr_w(out));
2759
2760 out[0] = 1;
2761 ret = pSHGetIniStringW(TestAppW, JunkKeyW, out, ARRAY_SIZE(out), pathW);
2762 ok(ret == 0, "SHGetIniStringW should have given 0, instead: %d\n", ret);
2763 ok(*out == 0, "Expected L\"\", got: %s\n", wine_dbgstr_w(out));
2764
2765 DeleteFileW(pathW);
2766}
2767
2768static void test_SHSetIniString(void)
2769{
2770 BOOL ret;
2771
2772 static const WCHAR TestAppW[] = {'T','e','s','t','A','p','p',0};
2773 static const WCHAR AnotherAppW[] = {'A','n','o','t','h','e','r','A','p','p',0};
2774 static const WCHAR TestIniW[] = {'C',':','\\','t','e','s','t','.','i','n','i',0};
2775 static const WCHAR AKeyW[] = {'A','K','e','y',0};
2776 static const WCHAR NewKeyW[] = {'N','e','w','K','e','y',0};
2777 static const WCHAR AValueW[] = {'A','V','a','l','u','e',0};
2778
2779 if (!write_inifile(TestIniW))
2780 return;
2781
2782 ret = pSHSetIniStringW(TestAppW, AKeyW, AValueW, TestIniW);
2783 ok(ret == TRUE, "SHSetIniStringW should not have failed\n");
2784 todo_wine /* wine sticks an extra \r\n at the end of the file */
2785 verify_inifile(TestIniW, "[TestApp]\r\nAKey=AValue\r\nAnotherKey=asdf\r\n");
2786
2787 ret = pSHSetIniStringW(TestAppW, AKeyW, NULL, TestIniW);
2788 ok(ret == TRUE, "SHSetIniStringW should not have failed\n");
2789 verify_inifile(TestIniW, "[TestApp]\r\nAnotherKey=asdf\r\n");
2790
2791 ret = pSHSetIniStringW(AnotherAppW, NewKeyW, AValueW, TestIniW);
2792 ok(ret == TRUE, "SHSetIniStringW should not have failed\n");
2793 verify_inifile(TestIniW, "[TestApp]\r\nAnotherKey=asdf\r\n[AnotherApp]\r\nNewKey=AValue\r\n");
2794
2795 ret = pSHSetIniStringW(TestAppW, NULL, AValueW, TestIniW);
2796 ok(ret == TRUE, "SHSetIniStringW should not have failed\n");
2797 verify_inifile(TestIniW, "[AnotherApp]\r\nNewKey=AValue\r\n");
2798
2799 DeleteFileW(TestIniW);
2800}
2801
2802#ifndef __REACTOS__
2816 SHKEY_Subkey_FileExts = 0x6000
2818#endif
2819
2820static void test_SHGetShellKey(void)
2821{
2822 static const WCHAR ShellFoldersW[] = { 'S','h','e','l','l',' ','F','o','l','d','e','r','s',0 };
2823 static const WCHAR WineTestW[] = { 'W','i','n','e','T','e','s','t',0 };
2824
2825 DWORD *alloc_data, data, size;
2826 HKEY hkey;
2827 HRESULT hres;
2828
2829 /* Vista+ limits SHKEY enumeration values */
2830 SetLastError(0xdeadbeef);
2831 hkey = pSHGetShellKey(SHKEY_Key_Explorer, ShellFoldersW, FALSE);
2832 if (hkey)
2833 {
2834 /* Tests not working on Vista+ */
2835 RegCloseKey(hkey);
2836
2837 hkey = pSHGetShellKey(SHKEY_Root_HKLM|SHKEY_Key_Classes, NULL, FALSE);
2838 ok(hkey != NULL, "hkey = NULL\n");
2839 RegCloseKey(hkey);
2840 }
2841
2842 hkey = pSHGetShellKey(SHKEY_Root_HKCU|SHKEY_Key_Explorer, ShellFoldersW, FALSE);
2843 ok(hkey != NULL, "hkey = NULL\n");
2844 RegCloseKey(hkey);
2845
2846 hkey = pSHGetShellKey(SHKEY_Root_HKLM|SHKEY_Key_Explorer, ShellFoldersW, FALSE);
2847 ok(hkey != NULL, "hkey = NULL\n");
2848 RegCloseKey(hkey);
2849
2850 hkey = pSHGetShellKey(SHKEY_Root_HKLM, WineTestW, FALSE);
2851 ok(hkey == NULL, "hkey != NULL\n");
2852
2853 hkey = pSHGetShellKey(SHKEY_Root_HKLM, NULL, FALSE);
2854 ok(hkey != NULL, "Can't open key\n");
2855 ok(SUCCEEDED(RegDeleteKeyW(hkey, WineTestW)), "Can't delete key\n");
2856 RegCloseKey(hkey);
2857
2858 hkey = pSHGetShellKey(SHKEY_Root_HKLM, WineTestW, TRUE);
2859 if (!hkey && GetLastError() == ERROR_ACCESS_DENIED)
2860 {
2861 skip("Not authorized to create keys\n");
2862 return;
2863 }
2864 ok(hkey != NULL, "Can't create key\n");
2865 RegCloseKey(hkey);
2866
2867 size = sizeof(data);
2868 hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, &data, &size);
2869 ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %x\n", hres);
2870
2871 data = 1234;
2872 hres = pSKSetValueW(SHKEY_Root_HKLM, WineTestW, NULL, REG_DWORD, &data, sizeof(DWORD));
2873 ok(hres == S_OK, "hres = %x\n", hres);
2874
2875 size = 1;
2876 hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, NULL, &size);
2877 ok(hres == S_OK, "hres = %x\n", hres);
2878 ok(size == sizeof(DWORD), "size = %d\n", size);
2879
2880 data = 0xdeadbeef;
2881 hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, &data, &size);
2882 ok(hres == S_OK, "hres = %x\n", hres);
2883 ok(size == sizeof(DWORD), "size = %d\n", size);
2884 ok(data == 1234, "data = %d\n", data);
2885
2886 hres = pSKAllocValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, (void**)&alloc_data, &size);
2887 ok(hres == S_OK, "hres= %x\n", hres);
2888 ok(size == sizeof(DWORD), "size = %d\n", size);
2889 if (SUCCEEDED(hres))
2890 {
2891 ok(*alloc_data == 1234, "*alloc_data = %d\n", *alloc_data);
2892 LocalFree(alloc_data);
2893 }
2894
2895 hres = pSKDeleteValueW(SHKEY_Root_HKLM, WineTestW, NULL);
2896 ok(hres == S_OK, "hres = %x\n", hres);
2897
2898 hres = pSKDeleteValueW(SHKEY_Root_HKLM, WineTestW, NULL);
2899 ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %x\n", hres);
2900
2901 hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, &data, &size);
2902 ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %x\n", hres);
2903
2904 hkey = pSHGetShellKey(SHKEY_Root_HKLM, NULL, FALSE);
2905 ok(hkey != NULL, "Can't create key\n");
2906 ok(SUCCEEDED(RegDeleteKeyW(hkey, WineTestW)), "Can't delete key\n");
2907 RegCloseKey(hkey);
2908}
2909
2910static void init_pointers(void)
2911{
2912#define MAKEFUNC(f, ord) (p##f = (void*)GetProcAddress(hShlwapi, (LPSTR)(ord)))
2917 MAKEFUNC(SHMapHandle, 11);
2937 MAKEFUNC(SHGetShellKey, 491);
2940 MAKEFUNC(SKGetValueW, 516);
2941 MAKEFUNC(SKSetValueW, 517);
2943 MAKEFUNC(SKAllocValueW, 519);
2944#undef MAKEFUNC
2945
2946 pDllGetVersion = (void*)GetProcAddress(hShlwapi, "DllGetVersion");
2947}
2948
2949static void test_SHSetParentHwnd(void)
2950{
2951 HWND hwnd, hwnd2, ret;
2952 DWORD style;
2953
2954 hwnd = CreateWindowA("Button", "", WS_VISIBLE, 0, 0, 10, 10, NULL, NULL, NULL, NULL);
2955 ok(hwnd != NULL, "got %p\n", hwnd);
2956
2957 hwnd2 = CreateWindowA("Button", "", WS_VISIBLE | WS_CHILD, 0, 0, 10, 10, hwnd, NULL, NULL, NULL);
2958 ok(hwnd2 != NULL, "got %p\n", hwnd2);
2959
2960 /* null params */
2961 ret = pSHSetParentHwnd(NULL, NULL);
2962 ok(ret == NULL, "got %p\n", ret);
2963
2964 /* set to no parent while already no parent present */
2965 ret = GetParent(hwnd);
2966 ok(ret == NULL, "got %p\n", ret);
2968 ok((style & (WS_POPUP|WS_CHILD)) == 0, "got style 0x%08x\n", style);
2969 ret = pSHSetParentHwnd(hwnd, NULL);
2970 ok(ret == NULL, "got %p\n", ret);
2972 ok((style & (WS_POPUP|WS_CHILD)) == 0, "got style 0x%08x\n", style);
2973
2974 /* reset to null parent from not null */
2975 ret = GetParent(hwnd2);
2976 ok(ret == hwnd, "got %p\n", ret);
2977 style = GetWindowLongA(hwnd2, GWL_STYLE);
2978 ok((style & (WS_POPUP|WS_CHILD)) == WS_CHILD, "got style 0x%08x\n", style);
2979 ret = pSHSetParentHwnd(hwnd2, NULL);
2980 ok(ret == NULL, "got %p\n", ret);
2981 style = GetWindowLongA(hwnd2, GWL_STYLE);
2982 ok((style & (WS_POPUP|WS_CHILD)) == WS_POPUP, "got style 0x%08x\n", style);
2983 ret = GetParent(hwnd2);
2984 ok(ret == NULL, "got %p\n", ret);
2985
2986 /* set parent back */
2987 style = GetWindowLongA(hwnd2, GWL_STYLE);
2989 style = GetWindowLongA(hwnd2, GWL_STYLE);
2990 ok((style & (WS_CHILD|WS_POPUP)) == 0, "got 0x%08x\n", style);
2991
2992 ret = pSHSetParentHwnd(hwnd2, hwnd);
2993 todo_wine ok(ret == NULL, "got %p\n", ret);
2994
2995 style = GetWindowLongA(hwnd2, GWL_STYLE);
2996 ok((style & (WS_POPUP|WS_CHILD)) == WS_CHILD, "got style 0x%08x\n", style);
2997 ret = GetParent(hwnd2);
2998 ok(ret == hwnd, "got %p\n", ret);
2999
3000 /* try to set same parent again */
3001 /* with WS_POPUP */
3002 style = GetWindowLongA(hwnd2, GWL_STYLE);
3004 ret = pSHSetParentHwnd(hwnd2, hwnd);
3005 todo_wine ok(ret == NULL, "got %p\n", ret);
3006 style = GetWindowLongA(hwnd2, GWL_STYLE);
3007 ok((style & (WS_CHILD|WS_POPUP)) == WS_CHILD, "got 0x%08x\n", style);
3008 ret = GetParent(hwnd2);
3009 ok(ret == hwnd, "got %p\n", ret);
3010
3011 /* without WS_POPUP */
3012 style = GetWindowLongA(hwnd2, GWL_STYLE);
3014 ret = pSHSetParentHwnd(hwnd2, hwnd);
3015 todo_wine ok(ret == hwnd, "got %p\n", ret);
3016 style = GetWindowLongA(hwnd2, GWL_STYLE);
3017 ok((style & (WS_CHILD|WS_POPUP)) == WS_CHILD, "got 0x%08x\n", style);
3018 ret = GetParent(hwnd2);
3019 ok(ret == hwnd, "got %p\n", ret);
3020
3022 DestroyWindow(hwnd2);
3023}
3024
3026{
3028 *obj = iface;
3029 IPersist_AddRef(iface);
3030 return S_OK;
3031 }
3032
3033 *obj = NULL;
3034 return E_NOINTERFACE;
3035}
3036
3038{
3039 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPersistFolder)) {
3040 *obj = iface;
3041 IPersist_AddRef(iface);
3042 return S_OK;
3043 }
3044
3045 *obj = NULL;
3046 return E_NOINTERFACE;
3047}
3048
3050{
3051 return 2;
3052}
3053
3055{
3056 return 1;
3057}
3058
3060{
3061 memset(clsid, 0xab, sizeof(*clsid));
3062 return 0x8fff2222;
3063}
3064
3065static IPersistVtbl testpersistvtbl = {
3070};
3071
3072static IPersistVtbl testpersist2vtbl = {
3077};
3078
3081
3083{
3084 CLSID clsid, clsid2, clsid3;
3085 HRESULT hr;
3086
3087 if (0) /* crashes on native systems */
3088 hr = pIUnknown_GetClassID(NULL, NULL);
3089
3090 memset(&clsid, 0xcc, sizeof(clsid));
3091 memset(&clsid3, 0xcc, sizeof(clsid3));
3092 hr = pIUnknown_GetClassID(NULL, &clsid);
3093 ok(hr == E_FAIL, "got 0x%08x\n", hr);
3094 ok(IsEqualCLSID(&clsid, &CLSID_NULL) || broken(IsEqualCLSID(&clsid, &clsid3)) /* win2k, winxp, win2k3 */,
3095 "got wrong clsid %s\n", wine_dbgstr_guid(&clsid));
3096
3097 memset(&clsid, 0xcc, sizeof(clsid));
3098 memset(&clsid2, 0xab, sizeof(clsid2));
3099 hr = pIUnknown_GetClassID((IUnknown*)&testpersist, &clsid);
3100 ok(hr == 0x8fff2222, "got 0x%08x\n", hr);
3101 ok(IsEqualCLSID(&clsid, &clsid2) || broken(IsEqualCLSID(&clsid, &clsid3)) /* win2k3 */,
3102 "got wrong clsid %s\n", wine_dbgstr_guid(&clsid));
3103
3104 /* IPersistFolder is also supported */
3105 memset(&clsid, 0xcc, sizeof(clsid));
3106 memset(&clsid2, 0xab, sizeof(clsid2));
3107 memset(&clsid3, 0xcc, sizeof(clsid3));
3108 hr = pIUnknown_GetClassID((IUnknown*)&testpersist2, &clsid);
3109 ok(hr == 0x8fff2222, "got 0x%08x\n", hr);
3110 ok(IsEqualCLSID(&clsid, &clsid2) || broken(IsEqualCLSID(&clsid, &clsid3)) /* win2k3 */,
3111 "got wrong clsid %s\n", wine_dbgstr_guid(&clsid));
3112}
3113
3114static void test_DllGetVersion(void)
3115{
3116 HRESULT hr;
3117
3118 hr = pDllGetVersion(NULL);
3119 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
3120}
3121
3123{
3124 char **argv;
3125 int argc;
3126
3127 hShlwapi = GetModuleHandleA("shlwapi.dll");
3128
3129 init_pointers();
3130
3132 if (argc >= 4)
3133 {
3134 DWORD procid;
3135 HANDLE hmem;
3136 sscanf(argv[2], "%d", &procid);
3137 sscanf(argv[3], "%p", &hmem);
3139 return;
3140 }
3141
3145 test_fdsa();
3164}
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
static int argc
Definition: ServiceArgs.c:12
@ lparam
Definition: SystemMenu.c:31
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define read
Definition: acwin.h:96
Arabic default style
Definition: afstyles.h:94
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define ARRAY_SIZE(A)
Definition: main.h:20
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:70
const GUID IID_IUnknown
HANDLE HKEY
Definition: registry.h:26
#define RegCloseKey(hKey)
Definition: registry.h:49
struct _root root
r l[0]
Definition: byte_order.h:168
IProfferService IProfferService_iface
Definition: ordinal.c:2193
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3234
LONG WINAPI RegEnumValueA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpdwReserved, _Out_opt_ LPDWORD lpdwType, _Out_opt_ LPBYTE lpData, _Inout_opt_ LPDWORD lpcbData)
Definition: reg.c:2668
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2287
LONG WINAPI RegEnumKeyA(HKEY hKey, DWORD dwIndex, LPSTR lpName, DWORD cbName)
Definition: reg.c:2368
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
BOOL WINAPI GetAclInformation(PACL pAcl, LPVOID pAclInformation, DWORD nAclInformationLength, ACL_INFORMATION_CLASS dwAclInformationClass)
Definition: security.c:1194
BOOL WINAPI GetAce(PACL pAcl, DWORD dwAceIndex, LPVOID *pAce)
Definition: security.c:1186
BOOL WINAPI IsValidAcl(PACL pAcl)
Definition: security.c:1209
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
@ VT_BLOB
Definition: compat.h:2330
@ VT_BSTR
Definition: compat.h:2303