ReactOS 0.4.16-dev-197-g92996da
shellpath.c
Go to the documentation of this file.
1/*
2 * Unit tests for shell32 SHGet{Special}Folder{Path|Location} functions.
3 *
4 * Copyright 2004 Juan Lang
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 * This is a test program for the SHGet{Special}Folder{Path|Location} functions
20 * of shell32, that get either a filesystem path or a LPITEMIDLIST (shell
21 * namespace) path for a given folder (CSIDL value).
22 */
23
24#define COBJMACROS
25
26#include <stdarg.h>
27#include <stdio.h>
28#include "windef.h"
29#include "winbase.h"
30#include "shlguid.h"
31#include "shlobj.h"
32#include "shlwapi.h"
33#include "knownfolders.h"
34#include "shellapi.h"
35#include "wine/test.h"
36
37#include "initguid.h"
38
39/* CSIDL_MYDOCUMENTS is now the same as CSIDL_PERSONAL, but what we want
40 * here is its original value.
41 */
42#define OLD_CSIDL_MYDOCUMENTS 0x000c
43
44DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
45
46/* from pidl.h, not included here: */
47#ifndef PT_CPL /* Guess, Win7 uses this for CSIDL_CONTROLS */
48#define PT_CPL 0x01 /* no path */
49#endif
50#ifndef PT_GUID
51#define PT_GUID 0x1f /* no path */
52#endif
53#ifndef PT_DRIVE
54#define PT_DRIVE 0x23 /* has path */
55#endif
56#ifndef PT_DRIVE2
57#define PT_DRIVE2 0x25 /* has path */
58#endif
59#ifndef PT_SHELLEXT
60#define PT_SHELLEXT 0x2e /* no path */
61#endif
62#ifndef PT_FOLDER
63#define PT_FOLDER 0x31 /* has path */
64#endif
65#ifndef PT_FOLDERW
66#define PT_FOLDERW 0x35 /* has path */
67#endif
68#ifndef PT_WORKGRP
69#define PT_WORKGRP 0x41 /* no path */
70#endif
71#ifndef PT_YAGUID
72#define PT_YAGUID 0x70 /* no path */
73#endif
74/* FIXME: this is used for history/favorites folders; what's a better name? */
75#ifndef PT_IESPECIAL2
76#define PT_IESPECIAL2 0xb1 /* has path */
77#endif
78
79static GUID CLSID_CommonDocuments = { 0x0000000c, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x1a } };
80
82 int folder;
84 const BYTE *types;
85};
86
87static HRESULT (WINAPI *pDllGetVersion)(DLLVERSIONINFO *);
88static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
89static HRESULT (WINAPI *pSHGetFolderLocation)(HWND, int, HANDLE, DWORD,
90 LPITEMIDLIST *);
91static BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
92static HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *);
93static LPITEMIDLIST (WINAPI *pILFindLastID)(LPCITEMIDLIST);
94static int (WINAPI *pSHFileOperationA)(LPSHFILEOPSTRUCTA);
95static HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *);
96static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR,UINT);
97static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *);
98static HRESULT (WINAPI *pSHSetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR);
99static HRESULT (WINAPI *pSHGetFolderPathEx)(REFKNOWNFOLDERID, DWORD, HANDLE, LPWSTR, DWORD);
100static BOOL (WINAPI *pPathYetAnotherMakeUniqueName)(PWSTR, PCWSTR, PCWSTR, PCWSTR);
101static HRESULT (WINAPI *pSHGetKnownFolderIDList)(REFKNOWNFOLDERID, DWORD, HANDLE, PIDLIST_ABSOLUTE*);
102
105static const BYTE guidType[] = { PT_GUID };
107static const BYTE folderType[] = { PT_FOLDER, PT_FOLDERW };
108static const BYTE favoritesType[] = { PT_FOLDER, PT_FOLDERW, 0, PT_IESPECIAL2 /* Win98 */ };
110static const BYTE personalType[] = { PT_FOLDER, PT_GUID, PT_DRIVE, 0xff /* Win9x */,
111 PT_IESPECIAL2 /* Win98 */, 0 /* Vista */, PT_SHELLEXT /* win8 */ };
112/* FIXME: don't know the type of 0x71 returned by Vista/2008 for printers */
113static const BYTE printersType[] = { PT_YAGUID, PT_SHELLEXT, 0x71 };
114static const BYTE ieSpecialType[] = { PT_IESPECIAL2 };
115static const BYTE shellExtType[] = { PT_SHELLEXT };
116static const BYTE workgroupType[] = { PT_WORKGRP };
117#define DECLARE_TYPE(x, y) { x, ARRAY_SIZE(y), y }
126/* FIXME: the following fails in Wine, returns type PT_FOLDER
127 DECLARE_TYPE(CSIDL_HISTORY, ieSpecialType),
128 */
141};
143/* FIXME: the following only semi-succeed; they return NULL PIDLs on XP.. hmm.
144 DECLARE_TYPE(CSIDL_ALTSTARTUP, folderType),
145 DECLARE_TYPE(CSIDL_COMMON_ALTSTARTUP, folderType),
146 DECLARE_TYPE(CSIDL_COMMON_OEM_LINKS, folderType),
147 */
148/* Windows NT-only: */
156/* first appearing in shell32 version 4.71: */
158/* first appearing in shell32 version 4.72: */
160/* first appearing in shell32 version 5.0: */
175/* first appearing in shell32 6.0: */
183};
184#undef DECLARE_TYPE
185
186static void loadShell32(void)
187{
188 HMODULE hShell32 = GetModuleHandleA("shell32");
189
190#define GET_PROC(func) \
191 p ## func = (void*)GetProcAddress(hShell32, #func); \
192 if(!p ## func) \
193 trace("GetProcAddress(%s) failed\n", #func);
194
197 GET_PROC(SHGetFolderPathEx)
199 GET_PROC(SHGetKnownFolderPath)
200 GET_PROC(SHSetKnownFolderPath)
204 if (!pILFindLastID)
205 pILFindLastID = (void *)GetProcAddress(hShell32, (LPCSTR)16);
209 GET_PROC(SHGetKnownFolderIDList)
210
211 ok(pSHGetMalloc != NULL, "shell32 is missing SHGetMalloc\n");
212 if (pSHGetMalloc)
213 {
214 HRESULT hr = pSHGetMalloc(&pMalloc);
215
216 ok(hr == S_OK, "SHGetMalloc failed: 0x%08x\n", hr);
217 ok(pMalloc != NULL, "SHGetMalloc returned a NULL IMalloc\n");
218 }
219
220 if (pDllGetVersion)
221 {
222 shellVersion.cbSize = sizeof(shellVersion);
223 pDllGetVersion(&shellVersion);
224 trace("shell32 version is %d.%d\n",
225 shellVersion.dwMajorVersion, shellVersion.dwMinorVersion);
226 }
227#undef GET_PROC
228}
229
230#ifndef CSIDL_PROFILES
231#define CSIDL_PROFILES 0x003e
232#endif
233
234/* A couple utility printing functions */
235static const char *getFolderName(int folder)
236{
237 static char unknown[32];
238
239#define CSIDL_TO_STR(x) case x: return#x;
240 switch (folder)
241 {
300#undef CSIDL_TO_STR
301 default:
302 sprintf(unknown, "unknown (0x%04x)", folder);
303 return unknown;
304 }
305}
306
307/* Standard CSIDL values (and their flags) uses only two less-significant bytes */
308#define NO_CSIDL 0x10000
309#define WINE_ATTRIBUTES_OPTIONAL 0x20000
310#define KNOWN_FOLDER(id, csidl, name, category, parent1, parent2, relative_path, parsing_name, attributes, definitionFlags) \
311 { &id, # id, csidl, # csidl, name, category, {&parent1, &parent2}, relative_path, parsing_name, attributes, definitionFlags, __LINE__ }
312
313/* non-published known folders test */
314static const GUID _FOLDERID_CryptoKeys = {0xB88F4DAA, 0xE7BD, 0x49A9, {0xB7, 0x4D, 0x02, 0x88, 0x5A, 0x5D, 0xC7, 0x65} };
315static const GUID _FOLDERID_DpapiKeys = {0x10C07CD0, 0xEF91, 0x4567, {0xB8, 0x50, 0x44, 0x8B, 0x77, 0xCB, 0x37, 0xF9} };
316static const GUID _FOLDERID_SystemCertificates = {0x54EED2E0, 0xE7CA, 0x4FDB, {0x91, 0x48, 0x0F, 0x42, 0x47, 0x29, 0x1C, 0xFA} };
317static const GUID _FOLDERID_CredentialManager = {0x915221FB, 0x9EFE, 0x4BDA, {0x8F, 0xD7, 0xF7, 0x8D, 0xCA, 0x77, 0x4F, 0x87} };
318
321 const char *sFolderId;
322 const int csidl;
323 const char *sCsidl;
324 const char *sName;
325 const KF_CATEGORY category;
327 const char *sRelativePath;
328 const char *sParsingName;
331 const int line;
332};
333
334/* Note: content of parsing name may vary between Windows versions.
335 * As a base, values from 6.0 (Vista) were used. Some entries may contain
336 * alternative values. In that case, Windows version where the value was
337 * found is noted.
338 *
339 * The list of values for parsing name was encoded as a number of null-
340 * terminated strings placed one by one (separated by null byte only).
341 * End of list is marked by two consecutive null bytes.
342 */
343static const struct knownFolderDef known_folders[] = {
344 KNOWN_FOLDER(FOLDERID_AddNewPrograms,
345 NO_CSIDL,
346 "AddNewProgramsFolder",
347 KF_CATEGORY_VIRTUAL,
349 NULL,
350 "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{15eae92e-f17a-4431-9f28-805e482dafd4}\0"
351 "shell:::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{15eae92e-f17a-4431-9f28-805e482dafd4}\0\0" /* 6.1 */,
352 0,
353 0),
354 KNOWN_FOLDER(FOLDERID_AdminTools,
356 "Administrative Tools",
357 KF_CATEGORY_PERUSER,
358 FOLDERID_Programs, GUID_NULL,
359 "Administrative Tools",
360 NULL,
363 KNOWN_FOLDER(FOLDERID_AppUpdates,
364 NO_CSIDL,
365 "AppUpdatesFolder",
366 KF_CATEGORY_VIRTUAL,
368 NULL,
369 "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\\::{d450a8a1-9568-45c7-9c0e-b4f9fb4537bd}\0"
370 "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\\::{d450a8a1-9568-45c7-9c0e-b4f9fb4537bd}\0\0" /* 6.1 */,
371 0,
372 0),
373 KNOWN_FOLDER(FOLDERID_CDBurning,
375 "CD Burning",
376 KF_CATEGORY_PERUSER,
377 FOLDERID_LocalAppData, GUID_NULL,
378 "Microsoft\\Windows\\Burn\\Burn",
379 NULL,
382 KNOWN_FOLDER(FOLDERID_ChangeRemovePrograms,
383 NO_CSIDL,
384 "ChangeRemoveProgramsFolder",
385 KF_CATEGORY_VIRTUAL,
387 NULL,
388 "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\0"
389 "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\0\0" /* 6.1 */,
390 0,
391 0),
392 KNOWN_FOLDER(FOLDERID_CommonAdminTools,
394 "Common Administrative Tools",
395 KF_CATEGORY_COMMON,
396 FOLDERID_CommonPrograms, GUID_NULL,
397 "Administrative Tools",
398 NULL,
401 KNOWN_FOLDER(FOLDERID_CommonOEMLinks,
403 "OEM Links",
404 KF_CATEGORY_COMMON,
405 FOLDERID_ProgramData, GUID_NULL,
406 "OEM Links",
407 NULL,
408 0,
409 0),
410 KNOWN_FOLDER(FOLDERID_CommonPrograms,
412 "Common Programs",
413 KF_CATEGORY_COMMON,
414 FOLDERID_CommonStartMenu, GUID_NULL,
415 "Programs",
416 NULL,
419 KNOWN_FOLDER(FOLDERID_CommonStartMenu,
421 "Common Start Menu",
422 KF_CATEGORY_COMMON,
423 FOLDERID_ProgramData, GUID_NULL,
424 "Microsoft\\Windows\\Start Menu\0",
425 NULL,
428 KNOWN_FOLDER(FOLDERID_CommonStartup,
430 "Common Startup",
431 KF_CATEGORY_COMMON,
432 FOLDERID_CommonPrograms, GUID_NULL,
433 "StartUp",
434 NULL,
437 KNOWN_FOLDER(FOLDERID_CommonTemplates,
439 "Common Templates",
440 KF_CATEGORY_COMMON,
441 FOLDERID_ProgramData, GUID_NULL,
442 "Microsoft\\Windows\\Templates\0",
443 NULL,
444 0,
445 0),
446 KNOWN_FOLDER(FOLDERID_ComputerFolder,
448 "MyComputerFolder",
449 KF_CATEGORY_VIRTUAL,
451 NULL,
452 "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\0\0",
453 0,
454 0),
455 KNOWN_FOLDER(FOLDERID_ConflictFolder,
456 NO_CSIDL,
457 "ConflictFolder",
458 KF_CATEGORY_VIRTUAL,
460 NULL,
461 "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{E413D040-6788-4C22-957E-175D1C513A34},\0"
462 "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{E413D040-6788-4C22-957E-175D1C513A34},\0\0" /* 6.1 */,
463 0,
464 0),
465 KNOWN_FOLDER(FOLDERID_ConnectionsFolder,
467 "ConnectionsFolder",
468 KF_CATEGORY_VIRTUAL,
470 NULL,
471 "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}\0"
472 "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}\0\0" /* 6.1 */,
473 0,
474 0),
475 KNOWN_FOLDER(FOLDERID_Contacts,
476 NO_CSIDL,
477 "Contacts",
478 KF_CATEGORY_PERUSER,
479 FOLDERID_Profile, GUID_NULL,
480 "Contacts",
481 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{56784854-C6CB-462B-8169-88E350ACB882}\0\0",
484 KNOWN_FOLDER(FOLDERID_ControlPanelFolder,
486 "ControlPanelFolder",
487 KF_CATEGORY_VIRTUAL,
489 NULL,
490 "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\0"
491 "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\0\0" /* 6.1 */,
492 0,
493 0),
494 KNOWN_FOLDER(FOLDERID_Cookies,
496 "Cookies",
497 KF_CATEGORY_PERUSER,
498 FOLDERID_RoamingAppData, FOLDERID_LocalAppData,
499 "Microsoft\\Windows\\Cookies\0Microsoft\\Windows\\INetCookies\0" /* win8 */,
500 NULL,
501 0,
502 0),
503 KNOWN_FOLDER(FOLDERID_Desktop,
505 "Desktop",
506 KF_CATEGORY_PERUSER,
507 FOLDERID_Profile, GUID_NULL,
508 "Desktop",
509 NULL,
512 KNOWN_FOLDER(FOLDERID_DeviceMetadataStore,
513 NO_CSIDL,
514 "Device Metadata Store",
515 KF_CATEGORY_COMMON,
516 FOLDERID_ProgramData, GUID_NULL,
517 "Microsoft\\Windows\\DeviceMetadataStore\0",
518 NULL,
519 0,
520 0),
521 KNOWN_FOLDER(FOLDERID_Documents,
523 "Personal",
524 KF_CATEGORY_PERUSER,
525 FOLDERID_Profile, GUID_NULL,
526 "Documents\0",
527 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{FDD39AD0-238F-46AF-ADB4-6C85480369C7}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{A8CDFF1C-4878-43be-B5FD-F8091C1C60D0}\0\0", /* win8 */
530 KNOWN_FOLDER(FOLDERID_DocumentsLibrary,
531 NO_CSIDL,
532 "DocumentsLibrary",
533 KF_CATEGORY_PERUSER,
534 FOLDERID_Libraries, GUID_NULL,
535 "Documents.library-ms\0",
536 "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{7b0db17d-9cd2-4a93-9733-46cc89022e7c}\0\0",
537 0,
539 KNOWN_FOLDER(FOLDERID_Downloads,
540 NO_CSIDL,
541 "Downloads",
542 KF_CATEGORY_PERUSER,
543 FOLDERID_Profile, GUID_NULL,
544 "Downloads\0",
545 "(null)\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{374DE290-123F-4565-9164-39C4925E467B}\0\0", /* win8 */
548 KNOWN_FOLDER(FOLDERID_Favorites,
550 "Favorites",
551 KF_CATEGORY_PERUSER,
552 FOLDERID_Profile, GUID_NULL,
553 "Favorites\0",
554 NULL,
557 KNOWN_FOLDER(FOLDERID_Fonts,
559 "Fonts",
560 KF_CATEGORY_FIXED,
561 FOLDERID_Windows, GUID_NULL,
562 NULL,
563 NULL,
564 0,
565 0),
566 KNOWN_FOLDER(FOLDERID_Games,
567 NO_CSIDL,
568 "Games",
569 KF_CATEGORY_VIRTUAL,
571 NULL,
572 "::{ED228FDF-9EA8-4870-83b1-96b02CFE0D52}\0\0",
573 0,
574 0),
575 KNOWN_FOLDER(FOLDERID_GameTasks,
576 NO_CSIDL,
577 "GameTasks",
578 KF_CATEGORY_PERUSER,
579 FOLDERID_LocalAppData, GUID_NULL,
580 "Microsoft\\Windows\\GameExplorer\0",
581 NULL,
582 0,
584 KNOWN_FOLDER(FOLDERID_History,
586 "History",
587 KF_CATEGORY_PERUSER,
588 FOLDERID_LocalAppData, GUID_NULL,
589 "Microsoft\\Windows\\History\0",
590 NULL,
591 0,
593 KNOWN_FOLDER(FOLDERID_HomeGroup,
594 NO_CSIDL,
595 "HomeGroupFolder",
596 KF_CATEGORY_VIRTUAL,
598 NULL,
599 "::{B4FB3F98-C1EA-428d-A78A-D1F5659CBA93}\0\0",
600 0,
601 0),
602 KNOWN_FOLDER(FOLDERID_ImplicitAppShortcuts,
603 NO_CSIDL,
604 "ImplicitAppShortcuts",
605 KF_CATEGORY_PERUSER,
606 FOLDERID_UserPinned, GUID_NULL,
607 "ImplicitAppShortcuts\0",
608 NULL,
609 0,
611 KNOWN_FOLDER(FOLDERID_InternetCache,
613 "Cache",
614 KF_CATEGORY_PERUSER,
615 FOLDERID_LocalAppData, GUID_NULL,
616 "Microsoft\\Windows\\Temporary Internet Files\0Microsoft\\Windows\\INetCache\0\0", /* win8 */
617 NULL,
618 0,
620 KNOWN_FOLDER(FOLDERID_InternetFolder,
622 "InternetFolder",
623 KF_CATEGORY_VIRTUAL,
625 NULL,
626 "::{871C5380-42A0-1069-A2EA-08002B30309D}\0\0",
627 0,
628 0),
629 KNOWN_FOLDER(FOLDERID_Libraries,
630 NO_CSIDL,
631 "Libraries",
632 KF_CATEGORY_PERUSER,
633 FOLDERID_RoamingAppData, GUID_NULL,
634 "Microsoft\\Windows\\Libraries\0",
635 NULL,
636 0,
638 KNOWN_FOLDER(FOLDERID_Links,
639 NO_CSIDL,
640 "Links",
641 KF_CATEGORY_PERUSER,
642 FOLDERID_Profile, GUID_NULL,
643 "Links\0",
644 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{bfb9d5e0-c6a9-404c-b2b2-ae6db6af4968}\0\0",
647 KNOWN_FOLDER(FOLDERID_LocalAppData,
649 "Local AppData",
650 KF_CATEGORY_PERUSER,
651 FOLDERID_Profile, GUID_NULL,
652 "AppData\\Local\0",
653 NULL,
654 0,
656 KNOWN_FOLDER(FOLDERID_LocalAppDataLow,
657 NO_CSIDL,
658 "LocalAppDataLow",
659 KF_CATEGORY_PERUSER,
660 FOLDERID_Profile, GUID_NULL,
661 "AppData\\LocalLow\0",
662 NULL,
665 KNOWN_FOLDER(FOLDERID_LocalizedResourcesDir,
667 "LocalizedResourcesDir",
668 KF_CATEGORY_FIXED,
670 NULL,
671 NULL,
672 0,
673 0),
674 KNOWN_FOLDER(FOLDERID_Music,
676 "My Music",
677 KF_CATEGORY_PERUSER,
678 FOLDERID_Profile, GUID_NULL,
679 "Music\0",
680 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{4BD8D571-6D19-48D3-BE97-422220080E43}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{1CF1260C-4DD0-4EBB-811F-33C572699FDE}\0\0", /* win8 */
683 KNOWN_FOLDER(FOLDERID_MusicLibrary,
684 NO_CSIDL,
685 "MusicLibrary",
686 KF_CATEGORY_PERUSER,
687 FOLDERID_Libraries, GUID_NULL,
688 "Music.library-ms\0",
689 "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{2112AB0A-C86A-4ffe-A368-0DE96E47012E}\0\0",
690 0,
692 KNOWN_FOLDER(FOLDERID_NetHood,
694 "NetHood",
695 KF_CATEGORY_PERUSER,
696 FOLDERID_RoamingAppData, GUID_NULL,
697 "Microsoft\\Windows\\Network Shortcuts\0",
698 NULL,
699 0,
700 0),
701 KNOWN_FOLDER(FOLDERID_NetworkFolder,
703 "NetworkPlacesFolder",
704 KF_CATEGORY_VIRTUAL,
706 NULL,
707 "::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}\0\0",
708 0,
709 0),
710 KNOWN_FOLDER(FOLDERID_OriginalImages,
711 NO_CSIDL,
712 "Original Images",
713 KF_CATEGORY_PERUSER,
714 FOLDERID_LocalAppData, GUID_NULL,
715 "Microsoft\\Windows Photo Gallery\\Original Images\0",
716 NULL,
717 0,
718 0),
719 KNOWN_FOLDER(FOLDERID_PhotoAlbums,
720 NO_CSIDL,
721 "PhotoAlbums",
722 KF_CATEGORY_PERUSER,
723 FOLDERID_Pictures, GUID_NULL,
724 "Slide Shows\0",
725 NULL,
727 0),
728 KNOWN_FOLDER(FOLDERID_Pictures,
730 "My Pictures",
731 KF_CATEGORY_PERUSER,
732 FOLDERID_Profile, GUID_NULL,
733 "Pictures\0",
734 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{33E28130-4E1E-4676-835A-98395C3BC3BB}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{3ADD1653-EB32-4CB0-BBD7-DFA0ABB5ACCA}\0\0", /* win8 */
737 KNOWN_FOLDER(FOLDERID_PicturesLibrary,
738 NO_CSIDL,
739 "PicturesLibrary",
740 KF_CATEGORY_PERUSER,
741 FOLDERID_Libraries, GUID_NULL,
742 "Pictures.library-ms\0",
743 "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{A990AE9F-A03B-4e80-94BC-9912D7504104}\0\0",
744 0,
746 KNOWN_FOLDER(FOLDERID_Playlists,
747 NO_CSIDL,
748 "Playlists",
749 KF_CATEGORY_PERUSER,
750 FOLDERID_Music, GUID_NULL,
751 "Playlists\0",
752 NULL,
754 0),
755 KNOWN_FOLDER(FOLDERID_PrintersFolder,
757 "PrintersFolder",
758 KF_CATEGORY_VIRTUAL,
760 NULL,
761 "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}\0\0",
762 0,
763 0),
764 KNOWN_FOLDER(FOLDERID_PrintHood,
766 "PrintHood",
767 KF_CATEGORY_PERUSER,
768 FOLDERID_RoamingAppData, GUID_NULL,
769 "Microsoft\\Windows\\Printer Shortcuts\0",
770 NULL,
771 0,
772 0),
773 KNOWN_FOLDER(FOLDERID_Profile,
775 "Profile",
776 KF_CATEGORY_FIXED,
778 NULL,
779 NULL,
780 0,
781 0),
782 KNOWN_FOLDER(FOLDERID_ProgramData,
784 "Common AppData",
785 KF_CATEGORY_FIXED,
787 NULL,
788 NULL,
789 0,
790 0),
791 KNOWN_FOLDER(FOLDERID_ProgramFiles,
793 "ProgramFiles",
794 KF_CATEGORY_FIXED,
796 NULL,
797 NULL,
800 ),
801 KNOWN_FOLDER(FOLDERID_ProgramFilesCommon,
803 "ProgramFilesCommon",
804 KF_CATEGORY_FIXED,
806 NULL,
807 NULL,
808 0,
809 0),
810 KNOWN_FOLDER(FOLDERID_ProgramFilesCommonX64,
811 NO_CSIDL,
812 "ProgramFilesCommonX64",
813 KF_CATEGORY_FIXED,
815 NULL,
816 NULL,
817 0,
818 0),
819 KNOWN_FOLDER(FOLDERID_ProgramFilesCommonX86,
820 NO_CSIDL,
821 "ProgramFilesCommonX86",
822 KF_CATEGORY_FIXED,
824 NULL,
825 NULL,
826 0,
827 0),
828 KNOWN_FOLDER(FOLDERID_ProgramFilesX64,
829 NO_CSIDL,
830 "ProgramFilesX64",
831 KF_CATEGORY_FIXED,
833 NULL,
834 NULL,
835 0,
836 0),
837 KNOWN_FOLDER(FOLDERID_ProgramFilesX86,
839 "ProgramFilesX86",
840 KF_CATEGORY_FIXED,
842 NULL,
843 NULL,
846 KNOWN_FOLDER(FOLDERID_Programs,
848 "Programs",
849 KF_CATEGORY_PERUSER,
850 FOLDERID_StartMenu, GUID_NULL,
851 "Programs\0",
852 NULL,
855 KNOWN_FOLDER(FOLDERID_Public,
856 NO_CSIDL,
857 "Public",
858 KF_CATEGORY_FIXED,
860 NULL,
861 "::{4336a54d-038b-4685-ab02-99bb52d3fb8b}\0"
862 "(null)\0\0" /* 6.1 */,
865 KNOWN_FOLDER(FOLDERID_PublicDesktop,
867 "Common Desktop",
868 KF_CATEGORY_COMMON,
869 FOLDERID_Public, GUID_NULL,
870 "Desktop\0",
871 NULL,
874 KNOWN_FOLDER(FOLDERID_PublicDocuments,
876 "Common Documents",
877 KF_CATEGORY_COMMON,
878 FOLDERID_Public, GUID_NULL,
879 "Documents\0",
880 NULL,
883 KNOWN_FOLDER(FOLDERID_PublicDownloads,
884 NO_CSIDL,
885 "CommonDownloads",
886 KF_CATEGORY_COMMON,
887 FOLDERID_Public, GUID_NULL,
888 "Downloads\0",
889 NULL,
892 KNOWN_FOLDER(FOLDERID_PublicGameTasks,
893 NO_CSIDL,
894 "PublicGameTasks",
895 KF_CATEGORY_COMMON,
896 FOLDERID_ProgramData, GUID_NULL,
897 "Microsoft\\Windows\\GameExplorer\0",
898 NULL,
899 0,
901 KNOWN_FOLDER(FOLDERID_PublicLibraries,
902 NO_CSIDL,
903 "PublicLibraries",
904 KF_CATEGORY_COMMON,
905 FOLDERID_Public, GUID_NULL,
906 "Libraries\0",
907 NULL,
910 KNOWN_FOLDER(FOLDERID_PublicMusic,
912 "CommonMusic",
913 KF_CATEGORY_COMMON,
914 FOLDERID_Public, GUID_NULL,
915 "Music\0",
916 NULL,
919 KNOWN_FOLDER(FOLDERID_PublicPictures,
921 "CommonPictures",
922 KF_CATEGORY_COMMON,
923 FOLDERID_Public, GUID_NULL,
924 "Pictures\0",
925 NULL,
928 KNOWN_FOLDER(FOLDERID_PublicRingtones,
929 NO_CSIDL,
930 "CommonRingtones",
931 KF_CATEGORY_COMMON,
932 FOLDERID_ProgramData, GUID_NULL,
933 "Microsoft\\Windows\\Ringtones\0",
934 NULL,
935 0,
937 KNOWN_FOLDER(FOLDERID_PublicVideos,
939 "CommonVideo",
940 KF_CATEGORY_COMMON,
941 FOLDERID_Public, GUID_NULL,
942 "Videos\0",
943 NULL,
946 KNOWN_FOLDER(FOLDERID_QuickLaunch,
947 NO_CSIDL,
948 "Quick Launch",
949 KF_CATEGORY_PERUSER,
950 FOLDERID_RoamingAppData, GUID_NULL,
951 "Microsoft\\Internet Explorer\\Quick Launch\0",
952 NULL,
953 0,
954 0),
955 KNOWN_FOLDER(FOLDERID_Recent,
957 "Recent",
958 KF_CATEGORY_PERUSER,
959 FOLDERID_RoamingAppData, GUID_NULL,
960 "Microsoft\\Windows\\Recent\0",
961 NULL,
964 KNOWN_FOLDER(FOLDERID_RecordedTVLibrary,
965 NO_CSIDL,
966 "RecordedTVLibrary",
967 KF_CATEGORY_COMMON,
968 FOLDERID_PublicLibraries, GUID_NULL,
969 "RecordedTV.library-ms\0",
970 NULL,
971 0,
973 KNOWN_FOLDER(FOLDERID_RecycleBinFolder,
975 "RecycleBinFolder",
976 KF_CATEGORY_VIRTUAL,
978 NULL,
979 "::{645FF040-5081-101B-9F08-00AA002F954E}\0\0",
980 0,
981 0),
982 KNOWN_FOLDER(FOLDERID_ResourceDir,
984 "ResourceDir",
985 KF_CATEGORY_FIXED,
987 NULL,
988 NULL,
989 0,
990 0),
991 KNOWN_FOLDER(FOLDERID_Ringtones,
992 NO_CSIDL,
993 "Ringtones",
994 KF_CATEGORY_PERUSER,
995 FOLDERID_LocalAppData, GUID_NULL,
996 "Microsoft\\Windows\\Ringtones\0",
997 NULL,
998 0,
1000 KNOWN_FOLDER(FOLDERID_RoamingAppData,
1002 "AppData",
1003 KF_CATEGORY_PERUSER,
1004 FOLDERID_Profile, GUID_NULL,
1005 "AppData\\Roaming\0",
1006 NULL,
1007 0,
1008 0),
1009 KNOWN_FOLDER(FOLDERID_SampleMusic,
1011 "SampleMusic",
1012 KF_CATEGORY_COMMON,
1013 FOLDERID_PublicMusic, GUID_NULL,
1014 "Sample Music\0",
1015 NULL,
1018 KNOWN_FOLDER(FOLDERID_SamplePictures,
1020 "SamplePictures",
1021 KF_CATEGORY_COMMON,
1022 FOLDERID_PublicPictures, GUID_NULL,
1023 "Sample Pictures\0",
1024 NULL,
1027 KNOWN_FOLDER(FOLDERID_SamplePlaylists,
1028 NO_CSIDL,
1029 "SamplePlaylists",
1030 KF_CATEGORY_COMMON,
1031 FOLDERID_PublicMusic, GUID_NULL,
1032 "Sample Playlists\0",
1033 NULL,
1035 0),
1036 KNOWN_FOLDER(FOLDERID_SampleVideos,
1038 "SampleVideos",
1039 KF_CATEGORY_COMMON,
1040 FOLDERID_PublicVideos, GUID_NULL,
1041 "Sample Videos\0",
1042 NULL,
1045 KNOWN_FOLDER(FOLDERID_SavedGames,
1046 NO_CSIDL,
1047 "SavedGames",
1048 KF_CATEGORY_PERUSER,
1049 FOLDERID_Profile, GUID_NULL,
1050 "Saved Games\0",
1051 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}\0\0",
1054 KNOWN_FOLDER(FOLDERID_SavedSearches,
1055 NO_CSIDL,
1056 "Searches",
1057 KF_CATEGORY_PERUSER,
1058 FOLDERID_Profile, GUID_NULL,
1059 "Searches\0",
1060 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{7d1d3a04-debb-4115-95cf-2f29da2920da}\0\0",
1063 KNOWN_FOLDER(FOLDERID_SEARCH_CSC,
1064 NO_CSIDL,
1065 "CSCFolder",
1066 KF_CATEGORY_VIRTUAL,
1068 NULL,
1069 "shell:::{BD7A2E7B-21CB-41b2-A086-B309680C6B7E}\\*\0\0",
1070 0,
1071 0),
1072 KNOWN_FOLDER(FOLDERID_SearchHome,
1073 NO_CSIDL,
1074 "SearchHomeFolder",
1075 KF_CATEGORY_VIRTUAL,
1077 NULL,
1078 "::{9343812e-1c37-4a49-a12e-4b2d810d956b}\0\0",
1079 0,
1080 0),
1081 KNOWN_FOLDER(FOLDERID_SEARCH_MAPI,
1082 NO_CSIDL,
1083 "MAPIFolder",
1084 KF_CATEGORY_VIRTUAL,
1086 NULL,
1087 "shell:::{89D83576-6BD1-4C86-9454-BEB04E94C819}\\*\0\0",
1088 0,
1089 0),
1090 KNOWN_FOLDER(FOLDERID_SendTo,
1092 "SendTo",
1093 KF_CATEGORY_PERUSER,
1094 FOLDERID_RoamingAppData, GUID_NULL,
1095 "Microsoft\\Windows\\SendTo\0",
1096 NULL,
1097 0,
1098 0),
1099 KNOWN_FOLDER(FOLDERID_SidebarDefaultParts,
1100 NO_CSIDL,
1101 "Default Gadgets",
1102 KF_CATEGORY_COMMON,
1103 FOLDERID_ProgramFiles, GUID_NULL,
1104 "Windows Sidebar\\Gadgets\0",
1105 NULL,
1106 0,
1107 0),
1108 KNOWN_FOLDER(FOLDERID_SidebarParts,
1109 NO_CSIDL,
1110 "Gadgets",
1111 KF_CATEGORY_PERUSER,
1112 FOLDERID_LocalAppData, GUID_NULL,
1113 "Microsoft\\Windows Sidebar\\Gadgets\0",
1114 NULL,
1115 0,
1116 0),
1117 KNOWN_FOLDER(FOLDERID_StartMenu,
1119 "Start Menu",
1120 KF_CATEGORY_PERUSER,
1121 FOLDERID_RoamingAppData, GUID_NULL,
1122 "Microsoft\\Windows\\Start Menu\0",
1123 NULL,
1126 KNOWN_FOLDER(FOLDERID_Startup,
1128 "Startup",
1129 KF_CATEGORY_PERUSER,
1130 FOLDERID_Programs, GUID_NULL,
1131 "StartUp\0",
1132 NULL,
1135 KNOWN_FOLDER(FOLDERID_SyncManagerFolder,
1136 NO_CSIDL,
1137 "SyncCenterFolder",
1138 KF_CATEGORY_VIRTUAL,
1140 NULL,
1141 "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\0"
1142 "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\0\0" /* 6.1 */,
1143 0,
1144 0),
1145 KNOWN_FOLDER(FOLDERID_SyncResultsFolder,
1146 NO_CSIDL,
1147 "SyncResultsFolder",
1148 KF_CATEGORY_VIRTUAL,
1150 NULL,
1151 "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{BC48B32F-5910-47F5-8570-5074A8A5636A},\0"
1152 "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{BC48B32F-5910-47F5-8570-5074A8A5636A},\0\0",
1153 0,
1154 0),
1155 KNOWN_FOLDER(FOLDERID_SyncSetupFolder,
1156 NO_CSIDL,
1157 "SyncSetupFolder",
1158 KF_CATEGORY_VIRTUAL,
1160 NULL,
1161 "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{F1390A9A-A3F4-4E5D-9C5F-98F3BD8D935C},\0"
1162 "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{F1390A9A-A3F4-4E5D-9C5F-98F3BD8D935C},\0\0" /* 6.1 */,
1163 0,
1164 0),
1165 KNOWN_FOLDER(FOLDERID_System,
1167 "System",
1168 KF_CATEGORY_FIXED,
1170 NULL,
1171 NULL,
1172 0,
1173 0),
1174 KNOWN_FOLDER(FOLDERID_SystemX86,
1176 "SystemX86",
1177 KF_CATEGORY_FIXED,
1179 NULL,
1180 NULL,
1181 0,
1182 0),
1183 KNOWN_FOLDER(FOLDERID_Templates,
1185 "Templates",
1186 KF_CATEGORY_PERUSER,
1187 FOLDERID_RoamingAppData, GUID_NULL,
1188 "Microsoft\\Windows\\Templates\0",
1189 NULL,
1190 0,
1191 0),
1192 KNOWN_FOLDER(FOLDERID_UserPinned,
1193 NO_CSIDL,
1194 "User Pinned",
1195 KF_CATEGORY_PERUSER,
1196 FOLDERID_QuickLaunch, GUID_NULL,
1197 "User Pinned\0",
1198 NULL,
1201 KNOWN_FOLDER(FOLDERID_UserProfiles,
1202 NO_CSIDL,
1203 "UserProfiles",
1204 KF_CATEGORY_FIXED,
1206 NULL,
1207 NULL,
1210 KNOWN_FOLDER(FOLDERID_UserProgramFiles,
1211 NO_CSIDL,
1212 "UserProgramFiles",
1213 KF_CATEGORY_PERUSER,
1214 FOLDERID_LocalAppData, GUID_NULL,
1215 "Programs\0",
1216 NULL,
1217 0,
1218 0),
1219 KNOWN_FOLDER(FOLDERID_UserProgramFilesCommon,
1220 NO_CSIDL,
1221 "UserProgramFilesCommon",
1222 KF_CATEGORY_PERUSER,
1223 FOLDERID_UserProgramFiles, GUID_NULL,
1224 "Common\0",
1225 NULL,
1226 0,
1227 0),
1228 KNOWN_FOLDER(FOLDERID_UsersFiles,
1229 NO_CSIDL,
1230 "UsersFilesFolder",
1231 KF_CATEGORY_VIRTUAL,
1233 NULL,
1234 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\0\0",
1235 0,
1236 0),
1237 KNOWN_FOLDER(FOLDERID_UsersLibraries,
1238 NO_CSIDL,
1239 "UsersLibrariesFolder",
1240 KF_CATEGORY_VIRTUAL,
1242 NULL,
1243 "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\0\0",
1244 0,
1245 0),
1246 KNOWN_FOLDER(FOLDERID_Videos,
1248 "My Video",
1249 KF_CATEGORY_PERUSER,
1250 FOLDERID_Profile, GUID_NULL,
1251 "Videos\0",
1252 "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{18989B1D-99B5-455B-841C-AB7C74E4DDFC}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{A0953C92-50DC-43BF-BE83-3742FED03C9C}\0\0", /* win8 */
1255 KNOWN_FOLDER(FOLDERID_VideosLibrary,
1256 NO_CSIDL,
1257 "VideosLibrary",
1258 KF_CATEGORY_PERUSER,
1259 FOLDERID_Libraries, GUID_NULL,
1260 "Videos.library-ms\0",
1261 "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{491E922F-5643-4af4-A7EB-4E7A138D8174}\0\0",
1262 0,
1264 KNOWN_FOLDER(FOLDERID_Windows,
1266 "Windows",
1267 KF_CATEGORY_FIXED,
1269 NULL,
1270 NULL,
1271 0,
1272 0),
1274 NO_CSIDL,
1275 "CredentialManager",
1276 KF_CATEGORY_FIXED,
1278 NULL,
1279 NULL,
1280 0,
1281 0),
1283 NO_CSIDL,
1284 "CryptoKeys",
1285 KF_CATEGORY_FIXED,
1287 NULL,
1288 NULL,
1289 0,
1290 0),
1292 NO_CSIDL,
1293 "DpapiKeys",
1294 KF_CATEGORY_FIXED,
1296 NULL,
1297 NULL,
1298 0,
1299 0),
1301 NO_CSIDL,
1302 "SystemCertificates",
1303 KF_CATEGORY_FIXED,
1305 NULL,
1306 NULL,
1307 0,
1308 0),
1309};
1310#undef KNOWN_FOLDER
1312
1313static void test_parameters(void)
1314{
1315 LPITEMIDLIST pidl = NULL;
1316 char path[MAX_PATH];
1317 HRESULT hr;
1318
1319 if (pSHGetFolderLocation)
1320 {
1321 /* check a bogus CSIDL: */
1322 pidl = NULL;
1323 hr = pSHGetFolderLocation(NULL, 0xeeee, NULL, 0, &pidl);
1324 ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
1325 if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
1326
1327 /* check a bogus user token: */
1328 pidl = NULL;
1329 hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, (HANDLE)2, 0, &pidl);
1330 ok(hr == E_FAIL || hr == E_HANDLE, "got 0x%08x, expected E_FAIL or E_HANDLE\n", hr);
1331 if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
1332
1333 /* a NULL pidl pointer crashes, so don't test it */
1334 }
1335
1336 if (pSHGetSpecialFolderLocation)
1337 {
1338 if (0)
1339 /* crashes */
1341
1342 hr = pSHGetSpecialFolderLocation(NULL, 0xeeee, &pidl);
1343 ok(hr == E_INVALIDARG, "got returned 0x%08x\n", hr);
1344 }
1345
1346 if (pSHGetFolderPathA)
1347 {
1348 /* expect 2's a bogus handle, especially since we didn't open it */
1349 hr = pSHGetFolderPathA(NULL, CSIDL_DESKTOP, (HANDLE)2, SHGFP_TYPE_DEFAULT, path);
1350 ok(hr == E_FAIL || hr == E_HANDLE || /* Vista and 2k8 */
1351 broken(hr == S_OK), /* W2k and Me */ "got 0x%08x, expected E_FAIL\n", hr);
1352
1353 hr = pSHGetFolderPathA(NULL, 0xeeee, NULL, SHGFP_TYPE_DEFAULT, path);
1354 ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
1355 }
1356
1357 if (pSHGetSpecialFolderPathA)
1358 {
1359 BOOL ret;
1360
1361 if (0)
1362 pSHGetSpecialFolderPathA(NULL, NULL, CSIDL_BITBUCKET, FALSE);
1363
1364 /* odd but true: calling with a NULL path still succeeds if it's a real
1365 * dir (on some windows platform). on winME it generates exception.
1366 */
1367 ret = pSHGetSpecialFolderPathA(NULL, path, CSIDL_PROGRAMS, FALSE);
1368 ok(ret, "got %d\n", ret);
1369
1370 ret = pSHGetSpecialFolderPathA(NULL, path, 0xeeee, FALSE);
1371 ok(!ret, "got %d\n", ret);
1372 }
1373}
1374
1375/* Returns the folder's PIDL type, or 0xff if one can't be found. */
1377{
1378 LPITEMIDLIST pidl;
1379 HRESULT hr;
1380 BYTE ret = 0xff;
1381
1382 /* treat absence of function as success */
1383 if (!pSHGetFolderLocation) return TRUE;
1384
1385 pidl = NULL;
1386 hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
1387 if (hr == S_OK)
1388 {
1389 if (pidl)
1390 {
1391 LPITEMIDLIST pidlLast = pILFindLastID(pidl);
1392
1393 ok(pidlLast != NULL, "%s: ILFindLastID failed\n",
1395 if (pidlLast)
1396 ret = pidlLast->mkid.abID[0];
1397 IMalloc_Free(pMalloc, pidl);
1398 }
1399 }
1400 return ret;
1401}
1402
1403/* Returns the folder's PIDL type, or 0xff if one can't be found. */
1405{
1406 LPITEMIDLIST pidl;
1407 HRESULT hr;
1408 BYTE ret = 0xff;
1409
1410 /* treat absence of function as success */
1411 if (!pSHGetSpecialFolderLocation) return TRUE;
1412
1413 pidl = NULL;
1414 hr = pSHGetSpecialFolderLocation(NULL, folder, &pidl);
1415 if (hr == S_OK)
1416 {
1417 if (pidl)
1418 {
1419 LPITEMIDLIST pidlLast = pILFindLastID(pidl);
1420
1421 ok(pidlLast != NULL,
1422 "%s: ILFindLastID failed\n", getFolderName(folder));
1423 if (pidlLast)
1424 ret = pidlLast->mkid.abID[0];
1425 IMalloc_Free(pMalloc, pidl);
1426 }
1427 }
1428 return ret;
1429}
1430
1432{
1433 char path[MAX_PATH];
1434 HRESULT hr;
1435
1436 if (!pSHGetFolderPathA) return;
1437
1438 hr = pSHGetFolderPathA(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path);
1439 ok(hr == S_OK || optional,
1440 "SHGetFolderPathA(NULL, %s, NULL, SHGFP_TYPE_CURRENT, path) failed: 0x%08x\n", getFolderName(folder), hr);
1441}
1442
1444{
1445 char path[MAX_PATH];
1446 BOOL ret;
1447
1448 if (!pSHGetSpecialFolderPathA) return;
1449
1450 ret = pSHGetSpecialFolderPathA(NULL, path, folder, FALSE);
1452 printf("%s: %s\n", getFolderName(folder), path);
1453 ok(ret || optional,
1454 "SHGetSpecialFolderPathA(NULL, path, %s, FALSE) failed\n",
1456}
1457
1458static void test_ShellValues(const struct shellExpectedValues testEntries[],
1459 int numEntries, BOOL optional)
1460{
1461 int i;
1462
1463 for (i = 0; i < numEntries; i++)
1464 {
1465 BYTE type;
1466 int j;
1467 BOOL foundTypeMatch = FALSE;
1468
1469 if (pSHGetFolderLocation)
1470 {
1471 type = testSHGetFolderLocation(testEntries[i].folder);
1472 for (j = 0; !foundTypeMatch && j < testEntries[i].numTypes; j++)
1473 if (testEntries[i].types[j] == type)
1474 foundTypeMatch = TRUE;
1475 ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
1476 "%s has unexpected type %d (0x%02x)\n",
1477 getFolderName(testEntries[i].folder), type, type);
1478 }
1480 for (j = 0, foundTypeMatch = FALSE; !foundTypeMatch &&
1481 j < testEntries[i].numTypes; j++)
1482 if (testEntries[i].types[j] == type)
1483 foundTypeMatch = TRUE;
1484 ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
1485 "%s has unexpected type %d (0x%02x)\n",
1486 getFolderName(testEntries[i].folder), type, type);
1487 switch (type)
1488 {
1489 case PT_FOLDER:
1490 case PT_DRIVE:
1491 case PT_DRIVE2:
1492 case PT_IESPECIAL2:
1493 test_SHGetFolderPath(optional, testEntries[i].folder);
1495 break;
1496 }
1497 }
1498}
1499
1500/* Attempts to verify that the folder path corresponding to the folder CSIDL
1501 * value has the same value as the environment variable with name envVar.
1502 * Doesn't mind if SHGetSpecialFolderPath fails for folder or if envVar isn't
1503 * set in this environment; different OS and shell version behave differently.
1504 * However, if both are present, fails if envVar's value is not the same
1505 * (byte-for-byte) as what SHGetSpecialFolderPath returns.
1506 */
1507static void matchSpecialFolderPathToEnv(int folder, const char *envVar)
1508{
1509 char path[MAX_PATH];
1510
1511 if (!pSHGetSpecialFolderPathA) return;
1512
1513 if (pSHGetSpecialFolderPathA(NULL, path, folder, FALSE))
1514 {
1515 char *envVal = getenv(envVar);
1516
1517 ok(!envVal || !lstrcmpiA(envVal, path),
1518 "%%%s%% does not match SHGetSpecialFolderPath:\n"
1519 "%%%s%% is %s\nSHGetSpecialFolderPath returns %s\n",
1520 envVar, envVar, envVal, path);
1521 }
1522}
1523
1524/* Attempts to match the GUID returned by SHGetFolderLocation for folder with
1525 * GUID. Assumes the type of the returned PIDL is in fact a GUID, but doesn't
1526 * fail if it isn't--that check should already have been done.
1527 * Fails if the returned PIDL is a GUID whose value does not match guid.
1528 */
1529static void matchGUID(int folder, const GUID *guid, const GUID *guid_alt)
1530{
1531 LPITEMIDLIST pidl;
1532 HRESULT hr;
1533
1534 if (!pSHGetFolderLocation) return;
1535 if (!guid) return;
1536
1537 pidl = NULL;
1538 hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
1539 if (hr == S_OK)
1540 {
1541 LPITEMIDLIST pidlLast = pILFindLastID(pidl);
1542
1543 if (pidlLast && (pidlLast->mkid.abID[0] == PT_SHELLEXT ||
1544 pidlLast->mkid.abID[0] == PT_GUID))
1545 {
1546 GUID *shellGuid = (GUID *)(pidlLast->mkid.abID + 2);
1547
1548 if (!guid_alt)
1549 ok(IsEqualIID(shellGuid, guid),
1550 "%s: got GUID %s, expected %s\n", getFolderName(folder),
1552 else
1553 ok(IsEqualIID(shellGuid, guid) ||
1554 IsEqualIID(shellGuid, guid_alt),
1555 "%s: got GUID %s, expected %s or %s\n", getFolderName(folder),
1556 wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid), wine_dbgstr_guid(guid_alt));
1557 }
1558 IMalloc_Free(pMalloc, pidl);
1559 }
1560}
1561
1562/* Checks the PIDL type of all the known values. */
1563static void test_PidlTypes(void)
1564{
1565 /* Desktop */
1568
1571}
1572
1573/* FIXME: Should be in shobjidl.idl */
1574DEFINE_GUID(CLSID_NetworkExplorerFolder, 0xF02C1A0D, 0xBE21, 0x4350, 0x88, 0xB0, 0x73, 0x67, 0xFC, 0x96, 0xEF, 0x3C);
1575DEFINE_GUID(_CLSID_Documents, 0xA8CDFF1C, 0x4878, 0x43be, 0xB5, 0xFD, 0xF8, 0x09, 0x1C, 0x1C, 0x60, 0xD0);
1576
1577/* Verifies various shell virtual folders have the correct well-known GUIDs. */
1578static void test_GUIDs(void)
1579{
1580 matchGUID(CSIDL_BITBUCKET, &CLSID_RecycleBin, NULL);
1581 matchGUID(CSIDL_CONTROLS, &CLSID_ControlPanel, NULL);
1582 matchGUID(CSIDL_DRIVES, &CLSID_MyComputer, NULL);
1583 matchGUID(CSIDL_INTERNET, &CLSID_Internet, NULL);
1584 matchGUID(CSIDL_NETWORK, &CLSID_NetworkPlaces, &CLSID_NetworkExplorerFolder); /* Vista and higher */
1585 matchGUID(CSIDL_PERSONAL, &CLSID_MyDocuments, &_CLSID_Documents /* win8 */);
1587 matchGUID(CSIDL_PRINTERS, &CLSID_Printers, NULL);
1588}
1589
1590/* Verifies various shell paths match the environment variables to which they
1591 * correspond.
1592 */
1593static void test_EnvVars(void)
1594{
1601 /* this is only set on Wine, but can't hurt to verify it: */
1603}
1604
1605/* Loosely based on PathRemoveBackslashA from dlls/shlwapi/path.c */
1606static BOOL myPathIsRootA(LPCSTR lpszPath)
1607{
1608 if (lpszPath && *lpszPath &&
1609 lpszPath[1] == ':' && lpszPath[2] == '\\' && lpszPath[3] == '\0')
1610 return TRUE; /* X:\ */
1611 return FALSE;
1612}
1614{
1615 LPSTR szTemp = NULL;
1616
1617 if(lpszPath)
1618 {
1619 szTemp = CharPrevA(lpszPath, lpszPath + strlen(lpszPath));
1620 if (!myPathIsRootA(lpszPath) && *szTemp == '\\')
1621 *szTemp = '\0';
1622 }
1623 return szTemp;
1624}
1625
1626/* Verifies the shell path for CSIDL_WINDOWS matches the return from
1627 * GetWindowsDirectory. If SHGetSpecialFolderPath fails, no harm, no foul--not
1628 * every shell32 version supports CSIDL_WINDOWS.
1629 */
1630static void testWinDir(void)
1631{
1632 char windowsShellPath[MAX_PATH], windowsDir[MAX_PATH] = { 0 };
1633
1634 if (!pSHGetSpecialFolderPathA) return;
1635
1636 if (pSHGetSpecialFolderPathA(NULL, windowsShellPath, CSIDL_WINDOWS, FALSE))
1637 {
1638 myPathRemoveBackslashA(windowsShellPath);
1639 GetWindowsDirectoryA(windowsDir, sizeof(windowsDir));
1640 myPathRemoveBackslashA(windowsDir);
1641 ok(!lstrcmpiA(windowsDir, windowsShellPath),
1642 "GetWindowsDirectory returns %s SHGetSpecialFolderPath returns %s\n",
1643 windowsDir, windowsShellPath);
1644 }
1645}
1646
1647/* Verifies the shell path for CSIDL_SYSTEM matches the return from
1648 * GetSystemDirectory. If SHGetSpecialFolderPath fails, no harm,
1649 * no foul--not every shell32 version supports CSIDL_SYSTEM.
1650 */
1651static void testSystemDir(void)
1652{
1653 char systemShellPath[MAX_PATH], systemDir[MAX_PATH], systemDirx86[MAX_PATH];
1654
1655 if (!pSHGetSpecialFolderPathA) return;
1656
1657 GetSystemDirectoryA(systemDir, sizeof(systemDir));
1658 myPathRemoveBackslashA(systemDir);
1659 if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEM, FALSE))
1660 {
1661 myPathRemoveBackslashA(systemShellPath);
1662 ok(!lstrcmpiA(systemDir, systemShellPath),
1663 "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
1664 systemDir, systemShellPath);
1665 }
1666
1667 if (!pGetSystemWow64DirectoryA || !pGetSystemWow64DirectoryA(systemDirx86, sizeof(systemDirx86)))
1668 GetSystemDirectoryA(systemDirx86, sizeof(systemDirx86));
1669 myPathRemoveBackslashA(systemDirx86);
1670 if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEMX86, FALSE))
1671 {
1672 myPathRemoveBackslashA(systemShellPath);
1673 ok(!lstrcmpiA(systemDirx86, systemShellPath) || broken(!lstrcmpiA(systemDir, systemShellPath)),
1674 "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
1675 systemDir, systemShellPath);
1676 }
1677}
1678
1679/* Globals used by subprocesses */
1680static int myARGC;
1681static char **myARGV;
1682static char base[MAX_PATH];
1683static char selfname[MAX_PATH];
1684
1685static BOOL init(void)
1686{
1688 if (!GetCurrentDirectoryA(sizeof(base), base)) return FALSE;
1689 strcpy(selfname, myARGV[0]);
1690 return TRUE;
1691}
1692
1693static void doChild(const char *arg)
1694{
1695 char path[MAX_PATH];
1696 HRESULT hr;
1697
1698 if (arg[0] == '1')
1699 {
1700 LPITEMIDLIST pidl;
1701 char *p;
1702
1703 /* test what happens when CSIDL_FAVORITES is set to a nonexistent directory */
1704
1705 /* test some failure cases first: */
1706 hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path);
1708 "SHGetFolderPath returned 0x%08x, expected 0x80070002\n", hr);
1709
1710 pidl = NULL;
1711 hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, NULL, 0, &pidl);
1713 "SHGetFolderLocation returned 0x%08x\n", hr);
1714 if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
1715
1716 ok(!pSHGetSpecialFolderPathA(NULL, path, CSIDL_FAVORITES, FALSE),
1717 "SHGetSpecialFolderPath succeeded, expected failure\n");
1718
1719 pidl = NULL;
1720 hr = pSHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
1722 "SHGetFolderLocation returned 0x%08x\n", hr);
1723
1724 if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
1725
1726 /* now test success: */
1727 hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
1729 ok (hr == S_OK, "got 0x%08x\n", hr);
1730 if (hr == S_OK)
1731 {
1732 BOOL ret;
1733
1734 trace("CSIDL_FAVORITES was changed to %s\n", path);
1736 ok(!ret, "expected failure with ERROR_ALREADY_EXISTS\n");
1737 if (!ret)
1739 "got %d, expected ERROR_ALREADY_EXISTS\n", GetLastError());
1740
1741 p = path + strlen(path);
1742 strcpy(p, "\\desktop.ini");
1744 *p = 0;
1747 ok( ret, "failed to remove %s error %u\n", path, GetLastError() );
1748 }
1749 }
1750 else if (arg[0] == '2')
1751 {
1752 /* make sure SHGetFolderPath still succeeds when the
1753 original value of CSIDL_FAVORITES is restored. */
1754 hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
1756 ok(hr == S_OK, "SHGetFolderPath failed: 0x%08x\n", hr);
1757 }
1758}
1759
1760/* Tests the return values from the various shell functions both with and
1761 * without the use of the CSIDL_FLAG_CREATE flag. This flag only appeared in
1762 * version 5 of the shell, so don't test unless it's at least version 5.
1763 * The test reads a value from the registry, modifies it, calls
1764 * SHGetFolderPath once with the CSIDL_FLAG_CREATE flag, and immediately
1765 * afterward without it. Then it restores the registry and deletes the folder
1766 * that was created.
1767 * One oddity with respect to restoration: shell32 caches somehow, so it needs
1768 * to be reloaded in order to see the correct (restored) value.
1769 * Some APIs unrelated to the ones under test may fail, but I expect they're
1770 * covered by other unit tests; I just print out something about failure to
1771 * help trace what's going on.
1772 */
1773static void test_NonExistentPath(void)
1774{
1775 static const char userShellFolders[] =
1776 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
1777 char originalPath[MAX_PATH], modifiedPath[MAX_PATH];
1778 HKEY key;
1779
1780 if (!pSHGetFolderPathA) return;
1781 if (!pSHGetFolderLocation) return;
1782 if (!pSHGetSpecialFolderPathA) return;
1783 if (!pSHGetSpecialFolderLocation) return;
1784 if (!pSHFileOperationA) return;
1785 if (shellVersion.dwMajorVersion < 5) return;
1786
1787 if (!RegOpenKeyExA(HKEY_CURRENT_USER, userShellFolders, 0, KEY_ALL_ACCESS,
1788 &key))
1789 {
1790 DWORD len, type;
1791
1792 len = sizeof(originalPath);
1793 if (!RegQueryValueExA(key, "Favorites", NULL, &type,
1794 (LPBYTE)&originalPath, &len))
1795 {
1796 size_t len = strlen(originalPath);
1797
1798 memcpy(modifiedPath, originalPath, len);
1799 modifiedPath[len++] = '2';
1800 modifiedPath[len++] = '\0';
1801 trace("Changing CSIDL_FAVORITES to %s\n", modifiedPath);
1802 if (!RegSetValueExA(key, "Favorites", 0, type,
1803 (LPBYTE)modifiedPath, len))
1804 {
1805 char buffer[MAX_PATH+20];
1808
1809 sprintf(buffer, "%s tests/shellpath.c 1", selfname);
1810 memset(&startup, 0, sizeof(startup));
1811 startup.cb = sizeof(startup);
1812 startup.dwFlags = STARTF_USESHOWWINDOW;
1813 startup.wShowWindow = SW_SHOWNORMAL;
1815 &startup, &info);
1817
1818 /* restore original values: */
1819 trace("Restoring CSIDL_FAVORITES to %s\n", originalPath);
1820 RegSetValueExA(key, "Favorites", 0, type, (LPBYTE) originalPath,
1821 strlen(originalPath) + 1);
1823
1824 sprintf(buffer, "%s tests/shellpath.c 2", selfname);
1825 memset(&startup, 0, sizeof(startup));
1826 startup.cb = sizeof(startup);
1827 startup.dwFlags = STARTF_USESHOWWINDOW;
1828 startup.wShowWindow = SW_SHOWNORMAL;
1830 &startup, &info);
1831 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0,
1832 "child process termination\n");
1833 }
1834 }
1835 else skip("RegQueryValueExA(key, Favorites, ...) failed\n");
1836 if (key)
1838 }
1839 else skip("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n", userShellFolders);
1840}
1841
1842static void test_SHGetFolderPathEx(void)
1843{
1845 unsigned int i;
1846 HRESULT hr;
1847 DWORD len;
1848
1849 if (!pSHGetKnownFolderPath || !pSHGetFolderPathEx)
1850 {
1851 win_skip("SHGetKnownFolderPath or SHGetFolderPathEx not available\n");
1852 return;
1853 }
1854
1855if (0) { /* crashes */
1856 hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, NULL);
1857 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
1858}
1859 /* non-existent folder id */
1860 path = (void *)0xdeadbeef;
1861 hr = pSHGetKnownFolderPath(&IID_IOleObject, 0, NULL, &path);
1862 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
1863 ok(path == NULL, "got %p\n", path);
1864
1865 path = NULL;
1866 hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, KF_FLAG_DEFAULT_PATH, NULL, &path);
1867 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1868 ok(path != NULL, "expected path != NULL\n");
1870
1871 for (i = 0; i < ARRAY_SIZE(known_folders); ++i)
1872 {
1873 const KNOWNFOLDERID *folder_id = known_folders[i].folderId;
1874
1875 path = NULL;
1876 hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_DEFAULT, NULL, &path);
1877 if (FAILED(hr))
1878 {
1879 ok(path == NULL, "expected path == NULL\n");
1880 continue;
1881 }
1882 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1883 ok(path != NULL, "expected path != NULL\n");
1884
1885 path2 = NULL;
1886 hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_SIMPLE_IDLIST, NULL, &path2);
1887 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1888 ok(path2 != NULL, "expected path != NULL\n");
1889 ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n", wine_dbgstr_w(path), wine_dbgstr_w(path2));
1891
1892 path2 = NULL;
1893 hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_DONT_UNEXPAND, NULL, &path2);
1894 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1895 ok(path2 != NULL, "expected path != NULL\n");
1896 ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n", wine_dbgstr_w(path), wine_dbgstr_w(path2));
1898
1899 path2 = NULL;
1900 hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_UNEXPAND, NULL, &path2);
1901 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1902 ok(path2 != NULL, "expected path != NULL\n");
1903 ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n", wine_dbgstr_w(path), wine_dbgstr_w(path2));
1905
1907 }
1908
1909 path = NULL;
1910 hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path);
1911 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1912 ok(path != NULL, "expected path != NULL\n");
1913
1914 hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, MAX_PATH);
1915 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1916 ok(!lstrcmpiW(path, buffer), "expected equal paths\n");
1917 len = lstrlenW(buffer);
1919
1920 hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, 0);
1921 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
1922
1923if (0) { /* crashes */
1924 hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, NULL, len + 1);
1925 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
1926
1927 hr = pSHGetFolderPathEx(NULL, 0, NULL, buffer, MAX_PATH);
1928 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
1929}
1930 hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len);
1931 ok(hr == E_NOT_SUFFICIENT_BUFFER, "expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hr);
1932
1933 hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len + 1);
1934 ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1935}
1936
1937static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
1938{
1939 WCHAR wstr[MAX_PATH];
1940
1941 if(!needle && !hay)
1942 return TRUE;
1943
1944 while(hay && *hay)
1945 {
1946 DWORD ret;
1947
1948 if(strcmp(hay, "(null)") == 0 && !needle)
1949 return TRUE;
1950
1951 ret = MultiByteToWideChar(CP_ACP, 0, hay, -1, wstr, ARRAY_SIZE(wstr));
1952 if(ret == 0)
1953 {
1954 ok(0, "Failed to convert string\n");
1955 return FALSE;
1956 }
1957
1958 if(lstrcmpW(wstr, needle) == 0)
1959 return TRUE;
1960
1961 hay += strlen(hay) + 1;
1962 }
1963
1964 return FALSE;
1965}
1966
1968{
1969 HRESULT hr;
1970 int csidl, expectedCsidl, ret;
1972 IKnownFolder *folder;
1973 WCHAR sName[1024];
1974 BOOL found = FALSE;
1975 unsigned int i;
1976
1977 for (i = 0; i < ARRAY_SIZE(known_folders); ++i)
1978 {
1979 const struct knownFolderDef *known_folder = &known_folders[i];
1980
1981 if(IsEqualGUID(known_folder->folderId, folderId))
1982 {
1984 found = TRUE;
1985 /* verify CSIDL */
1986 if(!(known_folder->csidl & NO_CSIDL))
1987 {
1988 /* mask off winetest flags */
1989 expectedCsidl = known_folder->csidl & 0xFFFF;
1990
1991 hr = IKnownFolderManager_FolderIdToCsidl(mgr, folderId, &csidl);
1992 ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot retrieve CSIDL for folder %s\n", known_folder->sFolderId);
1993
1994 ok_(__FILE__, known_folder->line)(csidl == expectedCsidl, "invalid CSIDL retrieved for folder %s. %d (%s) expected, but %d found\n", known_folder->sFolderId, expectedCsidl, known_folder->sCsidl, csidl);
1995 }
1996
1997 hr = IKnownFolderManager_GetFolder(mgr, folderId, &folder);
1998 ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot get known folder for %s\n", known_folder->sFolderId);
1999 if(SUCCEEDED(hr))
2000 {
2001 hr = IKnownFolder_GetFolderDefinition(folder, &kfd);
2002 ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot get known folder definition for %s\n", known_folder->sFolderId);
2003 if(SUCCEEDED(hr))
2004 {
2005 ret = MultiByteToWideChar(CP_ACP, 0, known_folder->sName, -1, sName, ARRAY_SIZE(sName));
2006 ok_(__FILE__, known_folder->line)(ret != 0, "cannot convert known folder name \"%s\" to wide characters\n", known_folder->sName);
2007
2008 ok_(__FILE__, known_folder->line)(lstrcmpW(kfd.pszName, sName)==0, "invalid known folder name returned for %s: %s expected, but %s retrieved\n", known_folder->sFolderId, wine_dbgstr_w(sName), wine_dbgstr_w(kfd.pszName));
2009
2010 ok_(__FILE__, known_folder->line)(kfd.category == known_folder->category, "invalid known folder category for %s: %d expected, but %d retrieved\n", known_folder->sFolderId, known_folder->category, kfd.category);
2011
2012 ok_(__FILE__, known_folder->line)(IsEqualGUID(known_folder->fidParents[0], &kfd.fidParent) ||
2013 IsEqualGUID(known_folder->fidParents[1], &kfd.fidParent),
2014 "invalid known folder parent for %s: %s retrieved\n",
2015 known_folder->sFolderId, wine_dbgstr_guid(&kfd.fidParent));
2016
2017 ok_(__FILE__, known_folder->line)(is_in_strarray(kfd.pszRelativePath, known_folder->sRelativePath), "invalid known folder relative path returned for %s: %s expected, but %s retrieved\n", known_folder->sFolderId, known_folder->sRelativePath, wine_dbgstr_w(kfd.pszRelativePath));
2018
2019 ok_(__FILE__, known_folder->line)(is_in_strarray(kfd.pszParsingName, known_folder->sParsingName), "invalid known folder parsing name returned for %s: %s retrieved\n", known_folder->sFolderId, wine_dbgstr_w(kfd.pszParsingName));
2020
2021 ok_(__FILE__, known_folder->line)(known_folder->attributes == kfd.dwAttributes ||
2022 (known_folder->csidl & WINE_ATTRIBUTES_OPTIONAL && kfd.dwAttributes == 0),
2023 "invalid known folder attributes for %s: 0x%08x expected, but 0x%08x retrieved\n", known_folder->sFolderId, known_folder->attributes, kfd.dwAttributes);
2024
2025 ok_(__FILE__, known_folder->line)(!(kfd.kfdFlags & (~known_folder->definitionFlags)), "invalid known folder flags for %s: 0x%08x expected, but 0x%08x retrieved\n", known_folder->sFolderId, known_folder->definitionFlags, kfd.kfdFlags);
2026
2028 }
2029
2030 IKnownFolder_Release(folder);
2031 }
2032
2033 break;
2034 }
2035 }
2036
2037 if(!found)
2038 {
2039 trace("unknown known folder found: %s\n", wine_dbgstr_guid(folderId));
2040
2041 hr = IKnownFolderManager_GetFolder(mgr, folderId, &folder);
2042 ok(hr == S_OK, "cannot get known folder for %s\n", wine_dbgstr_guid(folderId));
2043 if(SUCCEEDED(hr))
2044 {
2045 hr = IKnownFolder_GetFolderDefinition(folder, &kfd);
2046 todo_wine
2047 ok(hr == S_OK, "cannot get known folder definition for %s\n", wine_dbgstr_guid(folderId));
2048 if(SUCCEEDED(hr))
2049 {
2050 trace(" category: %d\n", kfd.category);
2051 trace(" name: %s\n", wine_dbgstr_w(kfd.pszName));
2052 trace(" description: %s\n", wine_dbgstr_w(kfd.pszDescription));
2053 trace(" parent: %s\n", wine_dbgstr_guid(&kfd.fidParent));
2054 trace(" relative path: %s\n", wine_dbgstr_w(kfd.pszRelativePath));
2055 trace(" parsing name: %s\n", wine_dbgstr_w(kfd.pszParsingName));
2056 trace(" tooltip: %s\n", wine_dbgstr_w(kfd.pszTooltip));
2057 trace(" localized name: %s\n", wine_dbgstr_w(kfd.pszLocalizedName));
2058 trace(" icon: %s\n", wine_dbgstr_w(kfd.pszIcon));
2059 trace(" security: %s\n", wine_dbgstr_w(kfd.pszSecurity));
2060 trace(" attributes: 0x%08x\n", kfd.dwAttributes);
2061 trace(" flags: 0x%08x\n", kfd.kfdFlags);
2062 trace(" type: %s\n", wine_dbgstr_guid(&kfd.ftidType));
2064 }
2065
2066 IKnownFolder_Release(folder);
2067 }
2068 }
2069}
2070#undef NO_CSIDL
2071
2072static void test_knownFolders(void)
2073{
2074 static const WCHAR sWindows[] = {'W','i','n','d','o','w','s',0};
2075 static const WCHAR sWindows2[] = {'w','i','n','d','o','w','s',0};
2076 static const WCHAR sExample[] = {'E','x','a','m','p','l','e',0};
2077 static const WCHAR sExample2[] = {'E','x','a','m','p','l','e','2',0};
2078 static const WCHAR sSubFolder[] = {'S','u','b','F','o','l','d','e','r',0};
2079 static const WCHAR sNoSuch[] = {'N','o','S','u','c','h',0};
2080 static const WCHAR sBackslash[] = {'\\',0};
2081 static const KNOWNFOLDERID newFolderId = {0x01234567, 0x89AB, 0xCDEF, {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x01} };
2082 static const KNOWNFOLDERID subFolderId = {0xFEDCBA98, 0x7654, 0x3210, {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF} };
2083 HRESULT hr;
2085 IKnownFolder *folder = NULL, *subFolder = NULL;
2086 KNOWNFOLDERID folderId, *folders;
2087 KF_CATEGORY cat = 0;
2088 KNOWNFOLDER_DEFINITION kfDefinition, kfSubDefinition;
2089 int csidl, i;
2090 UINT nCount = 0;
2091 LPWSTR folderPath, errorMsg;
2092 KF_REDIRECTION_CAPABILITIES redirectionCapabilities = 1;
2093 WCHAR sWinDir[MAX_PATH], sExamplePath[MAX_PATH], sExample2Path[MAX_PATH], sSubFolderPath[MAX_PATH], sSubFolder2Path[MAX_PATH];
2094 BOOL bRes;
2096
2097 GetWindowsDirectoryW( sWinDir, MAX_PATH );
2098
2099 GetTempPathW(ARRAY_SIZE(sExamplePath), sExamplePath);
2100 lstrcatW(sExamplePath, sExample);
2101
2102 GetTempPathW(ARRAY_SIZE(sExample2Path), sExample2Path);
2103 lstrcatW(sExample2Path, sExample2);
2104
2105 lstrcpyW(sSubFolderPath, sExamplePath);
2106 lstrcatW(sSubFolderPath, sBackslash);
2107 lstrcatW(sSubFolderPath, sSubFolder);
2108
2109 lstrcpyW(sSubFolder2Path, sExample2Path);
2110 lstrcatW(sSubFolder2Path, sBackslash);
2111 lstrcatW(sSubFolder2Path, sSubFolder);
2112
2114
2115 hr = CoCreateInstance(&CLSID_KnownFolderManager, NULL, CLSCTX_INPROC_SERVER,
2116 &IID_IKnownFolderManager, (LPVOID*)&mgr);
2117 if(hr == REGDB_E_CLASSNOTREG)
2118 win_skip("IKnownFolderManager unavailable\n");
2119 else
2120 {
2121 IUnknown *unk;
2122
2123 ok(hr == S_OK, "failed to create KnownFolderManager instance: 0x%08x\n", hr);
2124
2125 hr = IKnownFolderManager_QueryInterface(mgr, &IID_IMarshal, (void**)&unk);
2126 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2127
2128 hr = IKnownFolderManager_FolderIdFromCsidl(mgr, CSIDL_WINDOWS, &folderId);
2129 ok(hr == S_OK, "failed to convert CSIDL to KNOWNFOLDERID: 0x%08x\n", hr);
2130 ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2131
2132 hr = IKnownFolderManager_FolderIdToCsidl(mgr, &FOLDERID_Windows, &csidl);
2133 ok(hr == S_OK, "failed to convert CSIDL to KNOWNFOLDERID: 0x%08x\n", hr);
2134 ok(csidl == CSIDL_WINDOWS, "invalid CSIDL returned\n");
2135
2136 hr = IKnownFolderManager_GetFolder(mgr, &FOLDERID_Windows, &folder);
2137 ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2138 if(SUCCEEDED(hr))
2139 {
2140 hr = IKnownFolder_QueryInterface(folder, &IID_IMarshal, (void**)&unk);
2141 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2142
2143 hr = IKnownFolder_GetCategory(folder, &cat);
2144 ok(hr == S_OK, "failed to get folder category: 0x%08x\n", hr);
2145 ok(cat==KF_CATEGORY_FIXED, "invalid folder category: %d\n", cat);
2146
2147 hr = IKnownFolder_GetId(folder, &folderId);
2148 ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2149 ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2150
2151 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2152 ok(hr == S_OK, "failed to get path from known folder: 0x%08x\n", hr);
2153 ok(lstrcmpiW(sWinDir, folderPath)==0, "invalid path returned: \"%s\", expected: \"%s\"\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sWinDir));
2154 CoTaskMemFree(folderPath);
2155
2156 hr = IKnownFolder_GetRedirectionCapabilities(folder, &redirectionCapabilities);
2157 ok(hr == S_OK, "failed to get redirection capabilities: 0x%08x\n", hr);
2158 todo_wine
2159 ok(redirectionCapabilities==0, "invalid redirection capabilities returned: %d\n", redirectionCapabilities);
2160
2161 hr = IKnownFolder_SetPath(folder, 0, sWinDir);
2162 todo_wine
2163 ok(hr == E_INVALIDARG, "unexpected value from SetPath: 0x%08x\n", hr);
2164
2165 hr = IKnownFolder_GetFolderDefinition(folder, &kfDefinition);
2166 ok(hr == S_OK, "failed to get folder definition: 0x%08x\n", hr);
2167 if(SUCCEEDED(hr))
2168 {
2169 ok(kfDefinition.category==KF_CATEGORY_FIXED, "invalid folder category: 0x%08x\n", kfDefinition.category);
2170 ok(lstrcmpW(kfDefinition.pszName, sWindows)==0, "invalid folder name: %s\n", wine_dbgstr_w(kfDefinition.pszName));
2171 ok(kfDefinition.dwAttributes==0, "invalid folder attributes: %d\n", kfDefinition.dwAttributes);
2172 FreeKnownFolderDefinitionFields(&kfDefinition);
2173 }
2174
2175 hr = IKnownFolder_Release(folder);
2176 ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2177 }
2178
2179 hr = IKnownFolderManager_GetFolderByName(mgr, sWindows, &folder);
2180 ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2181 if(SUCCEEDED(hr))
2182 {
2183 hr = IKnownFolder_GetId(folder, &folderId);
2184 ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2185 ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2186
2187 hr = IKnownFolder_Release(folder);
2188 ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2189 }
2190
2191 hr = IKnownFolderManager_GetFolderByName(mgr, sWindows2, &folder);
2192 ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2193 if(SUCCEEDED(hr))
2194 {
2195 hr = IKnownFolder_GetId(folder, &folderId);
2196 ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2197 ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2198
2199 hr = IKnownFolder_Release(folder);
2200 ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2201 }
2202
2203 folder = (IKnownFolder *)0xdeadbeef;
2204 hr = IKnownFolderManager_GetFolderByName(mgr, sNoSuch, &folder);
2205 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
2206 ok(folder == NULL, "got %p\n", folder);
2207
2208 for(i=0; i < ARRAY_SIZE(known_folder_found); ++i)
2210
2211 hr = IKnownFolderManager_GetFolderIds(mgr, &folders, &nCount);
2212 ok(hr == S_OK, "failed to get known folders: 0x%08x\n", hr);
2213 for(i=0;i<nCount;++i)
2214 check_known_folder(mgr, &folders[i]);
2215
2216 for(i=0; i < ARRAY_SIZE(known_folder_found); ++i)
2217 if(!known_folder_found[i])
2218 trace("Known folder %s not found on current platform\n", known_folders[i].sFolderId);
2219
2220 CoTaskMemFree(folders);
2221
2222 /* test of registering new known folders */
2223 bRes = CreateDirectoryW(sExamplePath, NULL);
2224 ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sExamplePath));
2225 bRes = CreateDirectoryW(sExample2Path, NULL);
2226 ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sExample2Path));
2227 bRes = CreateDirectoryW(sSubFolderPath, NULL);
2228 ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sSubFolderPath));
2229
2230 ZeroMemory(&kfDefinition, sizeof(kfDefinition));
2231 kfDefinition.category = KF_CATEGORY_PERUSER;
2232 kfDefinition.pszName = CoTaskMemAlloc(sizeof(sExample));
2233 lstrcpyW(kfDefinition.pszName, sExample);
2234 kfDefinition.pszDescription = CoTaskMemAlloc(sizeof(sExample));
2235 lstrcpyW(kfDefinition.pszDescription, sExample);
2236 kfDefinition.pszRelativePath = CoTaskMemAlloc(sizeof(sExamplePath));
2237 lstrcpyW(kfDefinition.pszRelativePath, sExamplePath);
2238
2239 hr = IKnownFolderManager_RegisterFolder(mgr, &newFolderId, &kfDefinition);
2241 win_skip("No permissions required to register custom known folder\n");
2242 else
2243 {
2244 ok(hr == S_OK, "failed to register known folder: 0x%08x\n", hr);
2245 if(SUCCEEDED(hr))
2246 {
2247 hr = IKnownFolderManager_GetFolder(mgr, &newFolderId, &folder);
2248 ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2249 if(SUCCEEDED(hr))
2250 {
2251 hr = IKnownFolder_GetCategory(folder, &cat);
2252 ok(hr == S_OK, "failed to get folder category: hr=0x%0x\n", hr);
2253 ok(cat == KF_CATEGORY_PERUSER, "invalid category returned: %d, while %d (KF_CATEGORY_PERUSER) expected\n", cat, KF_CATEGORY_PERUSER);
2254
2255 hr = IKnownFolder_GetId(folder, &folderId);
2256 ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2257 ok(IsEqualGUID(&folderId, &newFolderId)==TRUE, "invalid KNOWNFOLDERID returned\n");
2258
2259 /* current path should be Temp\Example */
2260 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2261 ok(hr == S_OK, "failed to get path from known folder: 0x%08x\n", hr);
2262 ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2263 CoTaskMemFree(folderPath);
2264
2265 /* register sub-folder and mark it as child of Example folder */
2266 ZeroMemory(&kfSubDefinition, sizeof(kfSubDefinition));
2267 kfSubDefinition.category = KF_CATEGORY_PERUSER;
2268 kfSubDefinition.pszName = CoTaskMemAlloc(sizeof(sSubFolder));
2269 lstrcpyW(kfSubDefinition.pszName, sSubFolder);
2270 kfSubDefinition.pszDescription = CoTaskMemAlloc(sizeof(sSubFolder));
2271 lstrcpyW(kfSubDefinition.pszDescription, sSubFolder);
2272 kfSubDefinition.pszRelativePath = CoTaskMemAlloc(sizeof(sSubFolder));
2273 lstrcpyW(kfSubDefinition.pszRelativePath, sSubFolder);
2274 kfSubDefinition.fidParent = newFolderId;
2275
2276 hr = IKnownFolderManager_RegisterFolder(mgr, &subFolderId, &kfSubDefinition);
2277 ok(hr == S_OK, "failed to register known folder: 0x%08x\n", hr);
2278 if(SUCCEEDED(hr))
2279 {
2280
2281 hr = IKnownFolderManager_GetFolder(mgr, &subFolderId, &subFolder);
2282 ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2283 if(SUCCEEDED(hr))
2284 {
2285 /* check sub folder path */
2286 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2287 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2288 ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2289 CoTaskMemFree(folderPath);
2290
2291
2292 /* try to redirect Example to Temp\Example2 */
2293 hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 0, NULL, &errorMsg);
2294 ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2295
2296 /* verify */
2297 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2298 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2299 ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2300 CoTaskMemFree(folderPath);
2301
2302 /* verify sub folder - it should fail now, as we redirected its parent folder, but we have no sub folder in new location */
2303 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2304 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "unexpected value from GetPath(): 0x%08x\n", hr);
2305 ok(folderPath==NULL, "invalid known folder path retrieved: \"%s\" when NULL pointer was expected\n", wine_dbgstr_w(folderPath));
2306 CoTaskMemFree(folderPath);
2307
2308
2309 /* set Example path to original. Using SetPath() is valid here, as it also uses redirection internally */
2310 hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2311 ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2312
2313 /* verify */
2314 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2315 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2316 ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2317 CoTaskMemFree(folderPath);
2318
2319
2320 /* create sub folder in Temp\Example2 */
2321 bRes = CreateDirectoryW(sSubFolder2Path, NULL);
2322 ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sSubFolder2Path));
2323
2324 /* again perform that same redirection */
2325 hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 0, NULL, &errorMsg);
2326 ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2327
2328 /* verify sub folder. It should succeed now, as the required sub folder exists */
2329 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2330 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2331 ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2332 CoTaskMemFree(folderPath);
2333
2334 /* remove newly created directory */
2335 RemoveDirectoryW(sSubFolder2Path);
2336
2337 /* verify subfolder. It still succeeds, so Windows does not check folder presence each time */
2338 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2339 todo_wine
2340 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2341 todo_wine
2342 ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2343 CoTaskMemFree(folderPath);
2344
2345
2346 /* set Example path to original */
2347 hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2348 ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2349
2350 /* verify */
2351 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2352 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2353 ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2354 CoTaskMemFree(folderPath);
2355
2356 /* verify sub folder */
2357 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2358 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2359 ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2360 CoTaskMemFree(folderPath);
2361
2362
2363 /* create sub folder in Temp\Example2 */
2364 bRes = CreateDirectoryW(sSubFolder2Path, NULL);
2365 ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sSubFolder2Path));
2366
2367 /* do that same redirection, but try to exclude sub-folder */
2368 hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 1, &subFolderId, &errorMsg);
2369 ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2370
2371 /* verify */
2372 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2373 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2374 ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2375 CoTaskMemFree(folderPath);
2376
2377 /* verify sub folder. Unexpectedly, this path was also changed. So, exclusion seems to be ignored (Windows bug)? This test however will let us know, if this behavior is changed */
2378 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2379 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2380 ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2381 CoTaskMemFree(folderPath);
2382
2383 /* remove newly created directory */
2384 RemoveDirectoryW(sSubFolder2Path);
2385
2386
2387 /* set Example path to original */
2388 hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2389 ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2390
2391 /* verify */
2392 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2393 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2394 ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2395 CoTaskMemFree(folderPath);
2396
2397 /* verify sub folder */
2398 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2399 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2400 ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2401 CoTaskMemFree(folderPath);
2402
2403
2404 /* do that same redirection again, but set it to copy content. It should also copy the sub folder, so checking it would succeed now */
2405 hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS, sExample2Path, 0, NULL, &errorMsg);
2406 ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2407
2408 /* verify */
2409 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2410 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2411 ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2412 CoTaskMemFree(folderPath);
2413
2414 /* verify sub folder */
2415 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2416 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2417 ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2418 CoTaskMemFree(folderPath);
2419
2420 /* remove copied directory */
2421 RemoveDirectoryW(sSubFolder2Path);
2422
2423
2424 /* set Example path to original */
2425 hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2426 ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2427
2428 /* verify */
2429 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2430 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2431 ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2432 CoTaskMemFree(folderPath);
2433
2434 /* verify sub folder */
2435 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2436 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2437 ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2438 CoTaskMemFree(folderPath);
2439
2440
2441 /* redirect again, set it to copy content and remove originals */
2442 hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS | KF_REDIRECT_DEL_SOURCE_CONTENTS, sExample2Path, 0, NULL, &errorMsg);
2443 ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2444
2445 /* verify */
2446 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2447 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2448 ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2449 CoTaskMemFree(folderPath);
2450
2451 /* verify sub folder */
2452 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2453 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2454 ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2455 CoTaskMemFree(folderPath);
2456
2457 /* check if original directory was really removed */
2458 dwAttributes = GetFileAttributesW(sExamplePath);
2459 ok(dwAttributes==INVALID_FILE_ATTRIBUTES, "directory should not exist, but has attributes: 0x%08x\n", dwAttributes );
2460
2461
2462 /* redirect (with copy) to original path */
2463 hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS, sExamplePath, 0, NULL, &errorMsg);
2464 ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2465
2466 /* verify */
2467 hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2468 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2469 ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2470 CoTaskMemFree(folderPath);
2471
2472 /* verify sub folder */
2473 hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2474 ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2475 ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2476 CoTaskMemFree(folderPath);
2477
2478 /* check shell utility functions */
2479 if(!pSHGetKnownFolderPath || !pSHSetKnownFolderPath)
2480 todo_wine
2481 win_skip("cannot get SHGet/SetKnownFolderPath routines\n");
2482 else
2483 {
2484 /* try to get current known folder path */
2485 hr = pSHGetKnownFolderPath(&newFolderId, 0, NULL, &folderPath);
2486 todo_wine
2487 ok(hr==S_OK, "cannot get known folder path: hr=0x%0x\n", hr);
2488 todo_wine
2489 ok(lstrcmpW(folderPath, sExamplePath)==0, "invalid path returned: %s\n", wine_dbgstr_w(folderPath));
2490
2491 /* set it to new value */
2492 hr = pSHSetKnownFolderPath(&newFolderId, 0, NULL, sExample2Path);
2493 todo_wine
2494 ok(hr==S_OK, "cannot set known folder path: hr=0x%0x\n", hr);
2495
2496 /* check if it changed */
2497 hr = pSHGetKnownFolderPath(&newFolderId, 0, NULL, &folderPath);
2498 todo_wine
2499 ok(hr==S_OK, "cannot get known folder path: hr=0x%0x\n", hr);
2500 todo_wine
2501 ok(lstrcmpW(folderPath, sExample2Path)==0, "invalid path returned: %s\n", wine_dbgstr_w(folderPath));
2502
2503 /* set it back */
2504 hr = pSHSetKnownFolderPath(&newFolderId, 0, NULL, sExamplePath);
2505 todo_wine
2506 ok(hr==S_OK, "cannot set known folder path: hr=0x%0x\n", hr);
2507 }
2508
2509 IKnownFolder_Release(subFolder);
2510 }
2511
2512 hr = IKnownFolderManager_UnregisterFolder(mgr, &subFolderId);
2513 ok(hr == S_OK, "failed to unregister folder: 0x%08x\n", hr);
2514 }
2515
2516 FreeKnownFolderDefinitionFields(&kfSubDefinition);
2517
2518 hr = IKnownFolder_Release(folder);
2519 ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2520
2521 /* update the folder */
2522 CoTaskMemFree(kfDefinition.pszName);
2523 kfDefinition.pszName = CoTaskMemAlloc(sizeof(sExample2));
2524 lstrcpyW(kfDefinition.pszName, sExample2);
2525 hr = IKnownFolderManager_RegisterFolder(mgr, &newFolderId, &kfDefinition);
2526 ok(hr == S_OK, "failed to re-register known folder: 0x%08x\n", hr);
2527
2528 hr = IKnownFolderManager_GetFolder(mgr, &newFolderId, &folder);
2529 ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2530
2531 hr = IKnownFolder_GetFolderDefinition(folder, &kfSubDefinition);
2532 ok(hr == S_OK, "failed to get folder definition: 0x%08x\n", hr);
2533 ok(!memcmp(kfDefinition.pszName, kfSubDefinition.pszName, sizeof(sExample2)),
2534 "Got wrong updated name: %s\n", wine_dbgstr_w(kfSubDefinition.pszName));
2535
2536 FreeKnownFolderDefinitionFields(&kfSubDefinition);
2537
2538 hr = IKnownFolder_Release(folder);
2539 ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2540 }
2541
2542 hr = IKnownFolderManager_UnregisterFolder(mgr, &newFolderId);
2543 ok(hr == S_OK, "failed to unregister folder: 0x%08x\n", hr);
2544 }
2545 }
2546 FreeKnownFolderDefinitionFields(&kfDefinition);
2547
2548 RemoveDirectoryW(sSubFolder2Path);
2549 RemoveDirectoryW(sSubFolderPath);
2550 RemoveDirectoryW(sExamplePath);
2551 RemoveDirectoryW(sExample2Path);
2552
2553 hr = IKnownFolderManager_Release(mgr);
2554 ok(hr == S_OK, "failed to release KnownFolderManager instance: 0x%08x\n", hr);
2555 }
2557}
2558
2559
2561{
2562 WCHAR expectedW[MAX_PATH];
2563 WCHAR bufferW[MAX_PATH];
2564 CHAR expectedA[MAX_PATH];
2565 CHAR bufferA[MAX_PATH];
2566 DWORD res;
2567 DWORD res2;
2568 DWORD len;
2569 INT i;
2570 static const WCHAR does_not_existW[] = {'%','D','O','E','S','_','N','O','T','_','E','X','I','S','T','%',0};
2571 static const CHAR does_not_existA[] = "%DOES_NOT_EXIST%";
2572 static const CHAR *names[] = {
2573 /* interactive apps and services (works on all windows versions) */
2574 "%ALLUSERSPROFILE%", "%APPDATA%", "%LOCALAPPDATA%",
2575 "%NUMBER_OF_PROCESSORS%", "%OS%", "%PROCESSOR_ARCHITECTURE%",
2576 "%PROCESSOR_IDENTIFIER%", "%PROCESSOR_LEVEL%", "%PROCESSOR_REVISION%",
2577 "%ProgramFiles%", "%SystemDrive%",
2578 "%SystemRoot%", "%USERPROFILE%", "%windir%",
2579 /* todo_wine: "%COMPUTERNAME%", "%ProgramData%", "%PUBLIC%", */
2580
2581 /* replace more than one var is allowed */
2582 "%HOMEDRIVE%%HOMEPATH%",
2583 "%OS% %windir%"}; /* always the last entry in the table */
2584
2585 for (i = 0; i < (ARRAY_SIZE(names)); i++)
2586 {
2587 memset(bufferA, '#', MAX_PATH - 1);
2588 bufferA[MAX_PATH - 1] = 0;
2589 lstrcpyA(bufferA, names[i]);
2590 MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2591
2592 res2 = ExpandEnvironmentStringsA(names[i], expectedA, MAX_PATH);
2593 res = DoEnvironmentSubstA(bufferA, MAX_PATH);
2594
2595 /* is the space for the terminating 0 included? */
2596 if (!i && HIWORD(res) && (LOWORD(res) == (lstrlenA(bufferA))))
2597 {
2598 win_skip("DoEnvironmentSubstA/W are broken on NT 4\n");
2599 return;
2600 }
2601 ok(HIWORD(res) && (LOWORD(res) == res2),
2602 "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2603 ok(!lstrcmpA(bufferA, expectedA),
2604 "%d: got %s (expected %s)\n", i, bufferA, expectedA);
2605
2606 res2 = ExpandEnvironmentStringsW(bufferW, expectedW, MAX_PATH);
2607 res = DoEnvironmentSubstW(bufferW, MAX_PATH);
2608 ok(HIWORD(res) && (LOWORD(res) == res2),
2609 "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2610 ok(!lstrcmpW(bufferW, expectedW),
2611 "%d: got %s (expected %s)\n", i, wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2612 }
2613
2614 i--; /* reuse data in the last table entry */
2615 len = LOWORD(res); /* needed length */
2616
2617 /* one character extra is fine */
2618 memset(bufferA, '#', MAX_PATH - 1);
2619 bufferA[len + 2] = 0;
2620 lstrcpyA(bufferA, names[i]);
2621 MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2622
2623 res2 = ExpandEnvironmentStringsA(bufferA, expectedA, MAX_PATH);
2624 res = DoEnvironmentSubstA(bufferA, len + 1);
2625 ok(HIWORD(res) && (LOWORD(res) == res2),
2626 "+1: got %d/%d (expected TRUE/%d)\n", HIWORD(res), LOWORD(res), res2);
2627 ok(!lstrcmpA(bufferA, expectedA),
2628 "+1: got %s (expected %s)\n", bufferA, expectedA);
2629
2630 res2 = ExpandEnvironmentStringsW(bufferW, expectedW, MAX_PATH);
2631 res = DoEnvironmentSubstW(bufferW, len + 1);
2632 ok(HIWORD(res) && (LOWORD(res) == res2),
2633 "+1: got %d/%d (expected TRUE/%d)\n", HIWORD(res), LOWORD(res), res2);
2634 ok(!lstrcmpW(bufferW, expectedW),
2635 "+1: got %s (expected %s)\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2636
2637
2638 /* minimal buffer length (result string and terminating 0) */
2639 memset(bufferA, '#', MAX_PATH - 1);
2640 bufferA[len + 2] = 0;
2641 lstrcpyA(bufferA, names[i]);
2642 MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2643
2644 /* ANSI version failed without an extra byte, as documented on msdn */
2645 res = DoEnvironmentSubstA(bufferA, len);
2646 ok(!HIWORD(res) && (LOWORD(res) == len),
2647 " 0: got %d/%d (expected FALSE/%d)\n", HIWORD(res), LOWORD(res), len);
2648 ok(!lstrcmpA(bufferA, names[i]),
2649 " 0: got %s (expected %s)\n", bufferA, names[i]);
2650
2651 /* DoEnvironmentSubstW works as expected */
2652 res2 = ExpandEnvironmentStringsW(bufferW, expectedW, MAX_PATH);
2653 res = DoEnvironmentSubstW(bufferW, len);
2654 ok(HIWORD(res) && (LOWORD(res) == res2),
2655 " 0: got %d/%d (expected TRUE/%d)\n", HIWORD(res), LOWORD(res), res2);
2656 ok(!lstrcmpW(bufferW, expectedW),
2657 " 0: got %s (expected %s)\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2658
2659
2660 /* Buffer too small */
2661 /* result: FALSE / provided buffer length / the buffer is untouched */
2662 memset(bufferA, '#', MAX_PATH - 1);
2663 bufferA[len + 2] = 0;
2664 lstrcpyA(bufferA, names[i]);
2665 MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2666
2667 res = DoEnvironmentSubstA(bufferA, len - 1);
2668 ok(!HIWORD(res) && (LOWORD(res) == (len - 1)),
2669 "-1: got %d/%d (expected FALSE/%d)\n", HIWORD(res), LOWORD(res), len - 1);
2670 ok(!lstrcmpA(bufferA, names[i]),
2671 "-1: got %s (expected %s)\n", bufferA, names[i]);
2672
2673 lstrcpyW(expectedW, bufferW);
2674 res = DoEnvironmentSubstW(bufferW, len - 1);
2675 ok(!HIWORD(res) && (LOWORD(res) == (len - 1)),
2676 "-1: got %d/%d (expected FALSE/%d)\n", HIWORD(res), LOWORD(res), len - 1);
2677 ok(!lstrcmpW(bufferW, expectedW),
2678 "-1: got %s (expected %s)\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2679
2680
2681 /* unknown variable */
2682 /* result: TRUE / string length including terminating 0 / the buffer is untouched */
2683 memset(bufferA, '#', MAX_PATH - 1);
2684 bufferA[MAX_PATH - 1] = 0;
2685 lstrcpyA(bufferA, does_not_existA);
2686 MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2687
2688 res2 = lstrlenA(does_not_existA) + 1;
2689 res = DoEnvironmentSubstA(bufferA, MAX_PATH);
2690 ok(HIWORD(res) && (LOWORD(res) == res2),
2691 "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2692 ok(!lstrcmpA(bufferA, does_not_existA),
2693 "%d: got %s (expected %s)\n", i, bufferA, does_not_existA);
2694
2695 res = DoEnvironmentSubstW(bufferW, MAX_PATH);
2696 ok(HIWORD(res) && (LOWORD(res) == res2),
2697 "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2698 ok(!lstrcmpW(bufferW, does_not_existW),
2699 "%d: got %s (expected %s)\n", i, wine_dbgstr_w(bufferW), wine_dbgstr_w(does_not_existW));
2700
2701
2702 if (0)
2703 {
2704 /* NULL crashes on windows */
2707 }
2708}
2709
2711{
2712 static const WCHAR shortW[] = {'f','i','l','e','.','t','s','t',0};
2713 static const WCHAR short2W[] = {'f','i','l','e',' ','(','2',')','.','t','s','t',0};
2714 static const WCHAR tmpW[] = {'t','m','p',0};
2715 static const WCHAR longW[] = {'n','a','m','e',0};
2716 static const WCHAR long2W[] = {'n','a','m','e',' ','(','2',')',0};
2717 WCHAR nameW[MAX_PATH], buffW[MAX_PATH], pathW[MAX_PATH];
2718 HANDLE file;
2719 BOOL ret;
2720
2721 if (!pPathYetAnotherMakeUniqueName)
2722 {
2723 win_skip("PathYetAnotherMakeUniqueName() is not available.\n");
2724 return;
2725 }
2726
2727if (0)
2728{
2729 /* crashes on Windows */
2730 ret = pPathYetAnotherMakeUniqueName(NULL, NULL, NULL, NULL);
2731 ok(!ret, "got %d\n", ret);
2732
2733 ret = pPathYetAnotherMakeUniqueName(nameW, NULL, NULL, NULL);
2734 ok(!ret, "got %d\n", ret);
2735}
2736
2737 GetTempPathW(ARRAY_SIZE(pathW), pathW);
2738
2739 /* Using short name only first */
2740 nameW[0] = 0;
2741 ret = pPathYetAnotherMakeUniqueName(nameW, pathW, shortW, NULL);
2742 ok(ret, "got %d\n", ret);
2743 lstrcpyW(buffW, pathW);
2744 lstrcatW(buffW, shortW);
2745 ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2746
2747 /* now create a file with this name and get next name */
2749 ok(file != NULL, "got %p\n", file);
2750
2751 nameW[0] = 0;
2752 ret = pPathYetAnotherMakeUniqueName(nameW, pathW, shortW, NULL);
2753 ok(ret, "got %d\n", ret);
2754 lstrcpyW(buffW, pathW);
2755 lstrcatW(buffW, short2W);
2756 ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2757
2759
2760 /* Using short and long */
2761 nameW[0] = 0;
2762 ret = pPathYetAnotherMakeUniqueName(nameW, pathW, tmpW, longW);
2763 ok(ret, "got %d\n", ret);
2764 lstrcpyW(buffW, pathW);
2765 lstrcatW(buffW, longW);
2766 ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2767
2769 ok(file != NULL, "got %p\n", file);
2770
2771 nameW[0] = 0;
2772 ret = pPathYetAnotherMakeUniqueName(nameW, pathW, tmpW, longW);
2773 ok(ret, "got %d\n", ret);
2774 lstrcpyW(buffW, pathW);
2775 lstrcatW(buffW, long2W);
2776 ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2777
2779
2780 /* Using long only */
2781 nameW[0] = 0;
2782 ret = pPathYetAnotherMakeUniqueName(nameW, pathW, NULL, longW);
2783 ok(ret, "got %d\n", ret);
2784 lstrcpyW(buffW, pathW);
2785 lstrcatW(buffW, longW);
2786 ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2787}
2788
2790{
2791 PIDLIST_ABSOLUTE pidl;
2792 HRESULT hr;
2793
2794 if (!pSHGetKnownFolderIDList)
2795 {
2796 win_skip("SHGetKnownFolderIDList is not available.\n");
2797 return;
2798 }
2799
2800 hr = pSHGetKnownFolderIDList(NULL, 0, NULL, NULL);
2801 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2802
2803if (0) { /* crashes on native */
2804 pidl = (void*)0xdeadbeef;
2805 hr = pSHGetKnownFolderIDList(NULL, 0, NULL, &pidl);
2806}
2807 /* not a known folder */
2808 pidl = (void*)0xdeadbeef;
2809 hr = pSHGetKnownFolderIDList(&IID_IUnknown, 0, NULL, &pidl);
2810 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
2811 ok(pidl == NULL, "got %p\n", pidl);
2812
2813 hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, 0, NULL, NULL);
2814 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2815
2816 pidl = (void*)0xdeadbeef;
2817 hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, 0, NULL, &pidl);
2818 ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2819 ok(ILIsEmpty(pidl), "pidl should be empty.\n");
2820 ok(pidl->mkid.cb == 0, "get wrong value: %d\n", pidl->mkid.cb);
2821 ILFree(pidl);
2822
2823 pidl = (void*)0xdeadbeef;
2824 hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, KF_FLAG_NO_ALIAS, NULL, &pidl);
2825 ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2826 todo_wine ok(!ILIsEmpty(pidl), "pidl should not be empty.\n");
2827 todo_wine ok(pidl->mkid.cb == 20, "get wrong value: %d\n", pidl->mkid.cb);
2828 ILFree(pidl);
2829
2830 pidl = (void*)0xdeadbeef;
2831 hr = pSHGetKnownFolderIDList(&FOLDERID_Documents, 0, NULL, &pidl);
2832 ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2833 ok(!ILIsEmpty(pidl), "pidl should not be empty.\n");
2834 ok(pidl->mkid.cb == 20, "get wrong value: %d\n", pidl->mkid.cb);
2835 ILFree(pidl);
2836
2837 pidl = (void*)0xdeadbeef;
2838 hr = pSHGetKnownFolderIDList(&FOLDERID_Documents, KF_FLAG_NO_ALIAS, NULL, &pidl);
2839 ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2840 ok(!ILIsEmpty(pidl), "pidl should not be empty.\n");
2841 ok(pidl->mkid.cb == 20, "get wrong value: %d\n", pidl->mkid.cb);
2842 ILFree(pidl);
2843}
2844
2845START_TEST(shellpath)
2846{
2847 if (!init()) return;
2848
2849 loadShell32();
2850 pGetSystemWow64DirectoryA = (void *)GetProcAddress( GetModuleHandleA("kernel32.dll"),
2851 "GetSystemWow64DirectoryA" );
2852 if (myARGC >= 3)
2853 doChild(myARGV[2]);
2854 else
2855 {
2856 /* Report missing functions once */
2857 if (!pSHGetFolderLocation)
2858 win_skip("SHGetFolderLocation is not available\n");
2859
2860 /* first test various combinations of parameters: */
2862
2863 /* check known values: */
2865 test_GUIDs();
2866 test_EnvVars();
2867 testWinDir();
2868 testSystemDir();
2875 }
2876}
@ optional
Definition: SystemMenu.c:34
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
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static void startup(void)
#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
static const WCHAR nameW[]
Definition: main.c:49
#define ARRAY_SIZE(A)
Definition: main.h:20
const GUID IID_IUnknown
#define RegCloseKey(hKey)
Definition: registry.h:49
STDAPI DllGetVersion(DLLVERSIONINFO *info)
Definition: browseui.cpp:221
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#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 RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LONG WINAPI RegFlushKey(HKEY hKey)
Definition: reg.c:2951
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
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
#define CloseHandle
Definition: compat.h:739
#define CP_ACP
Definition: compat.h:109
HANDLE HWND
Definition: compat.h:19
#define GetProcAddress(x, y)
Definition: compat.h:753
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:399
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:776
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2337
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2283
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4747
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4195
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4224
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI SHGetMalloc(LPMALLOC *lpmal)
Definition: shellole.c:285
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3257
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3150
BOOL WINAPI SHGetSpecialFolderPathA(HWND hwndOwner, LPSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:3079
HRESULT WINAPI SHGetFolderPathA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath)
Definition: shellpath.c:2836
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:699
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define printf
Definition: freeldr.h:97
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLuint GLuint * names
Definition: glext.h:11545
GLuint buffer
Definition: glext.h:5915
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define wine_dbgstr_w
Definition: kernel32.h:34
#define GUID_NULL
Definition: ks.h:106
static WCHAR does_not_existW[]
Definition: localmon.c:90
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
const GUID * guid
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define CREATE_ALWAYS
Definition: disk.h:72
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define FILE_FLAG_DELETE_ON_CLOSE
Definition: disk.h:42
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define todo_wine
Definition: custom.c:89
static LPSTR myPathRemoveBackslashA(LPSTR lpszPath)
Definition: shellpath.c:1613
static PCWSTR
Definition: shellpath.c:100
static const BYTE folderOrSpecialType[]
Definition: shellpath.c:109
static void test_SHGetKnownFolderIDList(void)
Definition: shellpath.c:2789
static void testSystemDir(void)
Definition: shellpath.c:1651
static const BYTE workgroupType[]
Definition: shellpath.c:116
static void matchGUID(int folder, const GUID *guid, const GUID *guid_alt)
Definition: shellpath.c:1529
#define PT_CPL
Definition: shellpath.c:48
#define PT_WORKGRP
Definition: shellpath.c:69
static void test_SHGetSpecialFolderPath(BOOL optional, int folder)
Definition: shellpath.c:1443
#define PT_FOLDER
Definition: shellpath.c:63
static void test_PidlTypes(void)
Definition: shellpath.c:1563
static const BYTE folderType[]
Definition: shellpath.c:107
static const BYTE guidType[]
Definition: shellpath.c:105
static void test_DoEnvironmentSubst(void)
Definition: shellpath.c:2560
static PWSTR *static PWSTR
Definition: shellpath.c:98
static const BYTE favoritesType[]
Definition: shellpath.c:108
static const BYTE printersType[]
Definition: shellpath.c:113
static void test_NonExistentPath(void)
Definition: shellpath.c:1773
static void test_SHGetFolderPathEx(void)
Definition: shellpath.c:1842
static void test_EnvVars(void)
Definition: shellpath.c:1593
static void test_SHGetFolderPath(BOOL optional, int folder)
Definition: shellpath.c:1431
static BYTE testSHGetFolderLocation(int folder)
Definition: shellpath.c:1376
#define NO_CSIDL
Definition: shellpath.c:308
static BOOL init(void)
Definition: shellpath.c:1685
static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
Definition: shellpath.c:1937
static const char * getFolderName(int folder)
Definition: shellpath.c:235
#define PT_DRIVE
Definition: shellpath.c:54
static void test_PathYetAnotherMakeUniqueName(void)
Definition: shellpath.c:2710
static const struct shellExpectedValues optionalShellValues[]
Definition: shellpath.c:142
static int myARGC
Definition: shellpath.c:1680
static int
Definition: shellpath.c:88
static const GUID _FOLDERID_SystemCertificates
Definition: shellpath.c:316
#define OLD_CSIDL_MYDOCUMENTS
Definition: shellpath.c:42
static const BYTE personalType[]
Definition: shellpath.c:110
static void test_parameters(void)
Definition: shellpath.c:1313
#define CSIDL_PROFILES
Definition: shellpath.c:231
#define PT_DRIVE2
Definition: shellpath.c:57
static PIDLIST_ABSOLUTE *static DLLVERSIONINFO shellVersion
Definition: shellpath.c:103
static void loadShell32(void)
Definition: shellpath.c:186
#define CSIDL_TO_STR(x)
static const BYTE ieSpecialType[]
Definition: shellpath.c:114
static DWORD
Definition: shellpath.c:88
static const BYTE shellExtType[]
Definition: shellpath.c:115
static void test_knownFolders(void)
Definition: shellpath.c:2072
static void doChild(const char *arg)
Definition: shellpath.c:1693
static void test_GUIDs(void)
Definition: shellpath.c:1578
#define PT_GUID
Definition: shellpath.c:51
static LPMALLOC pMalloc
Definition: shellpath.c:104
static char ** myARGV
Definition: shellpath.c:1681
static GUID CLSID_CommonDocuments
Definition: shellpath.c:79
#define GET_PROC(func)
static const GUID _FOLDERID_DpapiKeys
Definition: shellpath.c:315
static void matchSpecialFolderPathToEnv(int folder, const char *envVar)
Definition: shellpath.c:1507
static void test_ShellValues(const struct shellExpectedValues testEntries[], int numEntries, BOOL optional)
Definition: shellpath.c:1458
BOOL known_folder_found[ARRAY_SIZE(known_folders)]
Definition: shellpath.c:1311
static const BYTE controlPanelType[]
Definition: shellpath.c:106
static const struct shellExpectedValues requiredShellValues[]
Definition: shellpath.c:118
static const GUID _FOLDERID_CryptoKeys
Definition: shellpath.c:314
static BOOL myPathIsRootA(LPCSTR lpszPath)
Definition: shellpath.c:1606
#define WINE_ATTRIBUTES_OPTIONAL
Definition: shellpath.c:309
static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId)
Definition: shellpath.c:1967
static void testWinDir(void)
Definition: shellpath.c:1630
static BYTE testSHGetSpecialFolderLocation(int folder)
Definition: shellpath.c:1404
#define DECLARE_TYPE(x, y)
Definition: shellpath.c:117
static const GUID _FOLDERID_CredentialManager
Definition: shellpath.c:317
#define KNOWN_FOLDER(id, csidl, name, category, parent1, parent2, relative_path, parsing_name, attributes, definitionFlags)
Definition: shellpath.c:310
static LPITEMIDLIST *static BOOL
Definition: shellpath.c:91
static char selfname[MAX_PATH]
Definition: shellpath.c:1683
static const struct knownFolderDef known_folders[]
Definition: shellpath.c:343
#define PT_YAGUID
Definition: shellpath.c:72
#define PT_FOLDERW
Definition: shellpath.c:66
#define PT_SHELLEXT
Definition: shellpath.c:60
#define PT_IESPECIAL2
Definition: shellpath.c:76
static UINT
Definition: shellpath.c:96
static HMODULE hShell32
Definition: string.c:34
static const WCHAR path2[]
Definition: path.c:29
unsigned int UINT
Definition: ndis.h:50
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define GENERIC_WRITE
Definition: nt_native.h:90
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
Definition: ntifs_ex.h:384
#define L(x)
Definition: ntvdm.h:50
interface IMalloc * LPMALLOC
Definition: objfwd.h:12
const GUID IID_IOleObject
#define LOWORD(l)
Definition: pedump.c:82
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:946
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:198
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define win_skip
Definition: test.h:163
int winetest_interactive
int winetest_get_mainargs(char ***pargv)
void winetest_wait_child_process(HANDLE process)
#define memset(x, y, z)
Definition: compat.h:39
struct _SHFILEOPSTRUCTA * LPSHFILEOPSTRUCTA
#define CSIDL_FLAG_CREATE
DWORD WINAPI DoEnvironmentSubstW(LPWSTR pszString, UINT cchString)
Definition: shellord.c:2050
DWORD WINAPI DoEnvironmentSubstA(LPSTR pszString, UINT cchString)
Definition: shellord.c:2005
int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp)
Definition: shlfileop.cpp:1060
HRESULT hr
Definition: shlfolder.c:183
#define CSIDL_COMMON_TEMPLATES
Definition: shlobj.h:2217
#define CSIDL_COMMON_DESKTOPDIRECTORY
Definition: shlobj.h:2197
#define CSIDL_TEMPLATES
Definition: shlobj.h:2193
#define CSIDL_PROGRAM_FILES
Definition: shlobj.h:2210
#define CSIDL_INTERNET_CACHE
Definition: shlobj.h:2204
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2188
#define CSIDL_SENDTO
Definition: shlobj.h:2182
#define CSIDL_RECENT
Definition: shlobj.h:2181
#define CSIDL_MYDOCUMENTS
Definition: shlobj.h:2185
#define CSIDL_ADMINTOOLS
Definition: shlobj.h:2220
#define CSIDL_COMMON_STARTMENU
Definition: shlobj.h:2194
@ SHGFP_TYPE_DEFAULT
Definition: shlobj.h:2150
@ SHGFP_TYPE_CURRENT
Definition: shlobj.h:2149
#define CSIDL_CDBURN_AREA
Definition: shlobj.h:2228
#define CSIDL_COMMON_ALTSTARTUP
Definition: shlobj.h:2202
#define CSIDL_FONTS
Definition: shlobj.h:2192
#define CSIDL_PERSONAL
Definition: shlobj.h:2178
#define CSIDL_FAVORITES
Definition: shlobj.h:2179
#define CSIDL_COMMON_APPDATA
Definition: shlobj.h:2207
#define CSIDL_CONNECTIONS
Definition: shlobj.h:2221
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2195
#define CSIDL_COMPUTERSNEARME
Definition: shlobj.h:2229
#define CSIDL_MYPICTURES
Definition: shlobj.h:2211
#define CSIDL_COOKIES
Definition: shlobj.h:2205
#define CSIDL_COMMON_FAVORITES
Definition: shlobj.h:2203
#define CSIDL_PRINTERS
Definition: shlobj.h:2177
@ KF_FLAG_NO_ALIAS
Definition: shlobj.h:103
@ KF_FLAG_SIMPLE_IDLIST
Definition: shlobj.h:99
@ KF_FLAG_DONT_UNEXPAND
Definition: shlobj.h:104
@ KF_FLAG_DEFAULT
Definition: shlobj.h:98
#define CSIDL_RESOURCES
Definition: shlobj.h:2225
#define CSIDL_SYSTEM
Definition: shlobj.h:2209
#define CSIDL_HISTORY
Definition: shlobj.h:2206
#define CSIDL_LOCAL_APPDATA
Definition: shlobj.h:2200
#define CSIDL_PROFILE
Definition: shlobj.h:2212
#define CSIDL_PROGRAM_FILES_COMMONX86
Definition: shlobj.h:2216
#define CSIDL_PROGRAM_FILES_COMMON
Definition: shlobj.h:2215
#define CSIDL_COMMON_MUSIC
Definition: shlobj.h:2222
#define CSIDL_COMMON_VIDEO
Definition: shlobj.h:2224
#define CSIDL_DESKTOP
Definition: shlobj.h:2173
#define CSIDL_NETWORK
Definition: shlobj.h:2190
#define CSIDL_STARTMENU
Definition: shlobj.h:2184
#define CSIDL_PROGRAM_FILESX86
Definition: shlobj.h:2214
static BOOL ILIsEmpty(_In_opt_ PCUIDLIST_RELATIVE pidl)
Definition: shlobj.h:2519
#define CSIDL_COMMON_PICTURES
Definition: shlobj.h:2223
#define CSIDL_PROGRAMS
Definition: shlobj.h:2175
#define CSIDL_COMMON_STARTUP
Definition: shlobj.h:2196
#define CSIDL_APPDATA
Definition: shlobj.h:2198
#define CSIDL_PRINTHOOD
Definition: shlobj.h:2199
#define CSIDL_ALTSTARTUP
Definition: shlobj.h:2201
#define CSIDL_SYSTEMX86
Definition: shlobj.h:2213
#define KF_FLAG_DEFAULT_PATH
Definition: shlobj.h:325
#define CSIDL_STARTUP
Definition: shlobj.h:2180
#define CSIDL_WINDOWS
Definition: shlobj.h:2208
#define CSIDL_DRIVES
Definition: shlobj.h:2189
#define CSIDL_MYMUSIC
Definition: shlobj.h:2186
#define CSIDL_INTERNET
Definition: shlobj.h:2174
#define CSIDL_COMMON_DOCUMENTS
Definition: shlobj.h:2218
#define CSIDL_CONTROLS
Definition: shlobj.h:2176
#define CSIDL_BITBUCKET
Definition: shlobj.h:2183
#define CSIDL_NETHOOD
Definition: shlobj.h:2191
#define CSIDL_COMMON_OEM_LINKS
Definition: shlobj.h:2227
#define CSIDL_COMMON_ADMINTOOLS
Definition: shlobj.h:2219
#define CSIDL_MYVIDEO
Definition: shlobj.h:2187
#define CSIDL_RESOURCES_LOCALIZED
Definition: shlobj.h:2226
enum tagKF_DEFINITION_FLAGS KF_DEFINITION_FLAGS
static void FreeKnownFolderDefinitionFields(KNOWNFOLDER_DEFINITION *pKFD)
Definition: shobjidl.idl:4149
@ KFDF_PUBLISHEXPANDEDPATH
Definition: shobjidl.idl:4014
@ KFDF_LOCAL_REDIRECT_ONLY
Definition: shobjidl.idl:4010
@ KFDF_ROAMABLE
Definition: shobjidl.idl:4011
@ KFDF_PRECREATE
Definition: shobjidl.idl:4012
@ KFDF_STREAM
Definition: shobjidl.idl:4013
pointer_default(unique)] interface IFileDialogCustomize enum tagKF_REDIRECTION_CAPABILITIES KF_REDIRECTION_CAPABILITIES
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
KNOWNFOLDERID * REFKNOWNFOLDERID
Definition: shtypes.idl:147
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
WORD cb
Definition: shtypes.idl:27
SHITEMID mkid
Definition: shtypes.idl:34
Definition: fci.c:127
Definition: fci.c:116
Definition: copy.c:22
const DWORD attributes
Definition: shellpath.c:329
const char * sRelativePath
Definition: shellpath.c:327
const KF_CATEGORY category
Definition: shellpath.c:325
const int csidl
Definition: shellpath.c:322
const KNOWNFOLDERID * folderId
Definition: shellpath.c:320
const char * sFolderId
Definition: shellpath.c:321
const char * sName
Definition: shellpath.c:324
const KF_DEFINITION_FLAGS definitionFlags
Definition: shellpath.c:330
const char * sCsidl
Definition: shellpath.c:323
const int line
Definition: shellpath.c:331
const KNOWNFOLDERID * fidParents[2]
Definition: shellpath.c:326
const char * sParsingName
Definition: shellpath.c:328
const BYTE * types
Definition: shellpath.c:84
KF_DEFINITION_FLAGS kfdFlags
Definition: shobjidl.idl:4030
Definition: cmds.c:130
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * LPBYTE
Definition: typedefs.h:53
PVOID HANDLE
Definition: typedefs.h:73
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
DWORD dwAttributes
Definition: vdmdbg.h:34
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
int ret
#define ZeroMemory
Definition: winbase.h:1736
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define STARTF_USESHOWWINDOW
Definition: winbase.h:516
#define WAIT_OBJECT_0
Definition: winbase.h:431
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:2696
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:2345
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_HANDLE
Definition: winerror.h:2850
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define SW_SHOWNORMAL
Definition: winuser.h:773
LPSTR WINAPI CharPrevA(_In_ LPCSTR, _In_ LPCSTR)
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193