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