ReactOS  0.4.14-dev-608-gd495a4f
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 
44 DEFINE_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 
79 static GUID CLSID_CommonDocuments = { 0x0000000c, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x1a } };
80 
82  int folder;
83  int numTypes;
84  const BYTE *types;
85 };
86 
87 static HRESULT (WINAPI *pDllGetVersion)(DLLVERSIONINFO *);
88 static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
89 static HRESULT (WINAPI *pSHGetFolderLocation)(HWND, int, HANDLE, DWORD,
90  LPITEMIDLIST *);
91 static BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
92 static HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *);
93 static LPITEMIDLIST (WINAPI *pILFindLastID)(LPCITEMIDLIST);
94 static int (WINAPI *pSHFileOperationA)(LPSHFILEOPSTRUCTA);
95 static HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *);
96 static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR,UINT);
97 static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *);
98 static HRESULT (WINAPI *pSHSetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR);
99 static HRESULT (WINAPI *pSHGetFolderPathEx)(REFKNOWNFOLDERID, DWORD, HANDLE, LPWSTR, DWORD);
100 static BOOL (WINAPI *pPathYetAnotherMakeUniqueName)(PWSTR, PCWSTR, PCWSTR, PCWSTR);
101 static HRESULT (WINAPI *pSHGetKnownFolderIDList)(REFKNOWNFOLDERID, DWORD, HANDLE, PIDLIST_ABSOLUTE*);
102 
105 static const BYTE guidType[] = { PT_GUID };
107 static const BYTE folderType[] = { PT_FOLDER, PT_FOLDERW };
108 static const BYTE favoritesType[] = { PT_FOLDER, PT_FOLDERW, 0, PT_IESPECIAL2 /* Win98 */ };
110 static 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 */
113 static const BYTE printersType[] = { PT_YAGUID, PT_SHELLEXT, 0x71 };
114 static const BYTE ieSpecialType[] = { PT_IESPECIAL2 };
115 static const BYTE shellExtType[] = { PT_SHELLEXT };
116 static const BYTE workgroupType[] = { PT_WORKGRP };
117 #define DECLARE_TYPE(x, y) { x, ARRAY_SIZE(y), y }
118 static const struct shellExpectedValues requiredShellValues[] = {
126 /* FIXME: the following fails in Wine, returns type PT_FOLDER
127  DECLARE_TYPE(CSIDL_HISTORY, ieSpecialType),
128  */
141 };
142 static const struct shellExpectedValues optionalShellValues[] = {
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 
186 static 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 */
235 static 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 */
314 static const GUID _FOLDERID_CryptoKeys = {0xB88F4DAA, 0xE7BD, 0x49A9, {0xB7, 0x4D, 0x02, 0x88, 0x5A, 0x5D, 0xC7, 0x65} };
315 static const GUID _FOLDERID_DpapiKeys = {0x10C07CD0, 0xEF91, 0x4567, {0xB8, 0x50, 0x44, 0x8B, 0x77, 0xCB, 0x37, 0xF9} };
316 static const GUID _FOLDERID_SystemCertificates = {0x54EED2E0, 0xE7CA, 0x4FDB, {0x91, 0x48, 0x0F, 0x42, 0x47, 0x29, 0x1C, 0xFA} };
317 static 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  */
343 static 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,
447  CSIDL_DRIVES,
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,
558  CSIDL_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,
956  CSIDL_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,
1001  CSIDL_APPDATA,
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,
1017  KFDF_PRECREATE),
1018  KNOWN_FOLDER(FOLDERID_SamplePictures,
1020  "SamplePictures",
1021  KF_CATEGORY_COMMON,
1022  FOLDERID_PublicPictures, GUID_NULL,
1023  "Sample Pictures\0",
1024  NULL,
1026  KFDF_PRECREATE),
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,
1044  KFDF_PRECREATE),
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,
1091  CSIDL_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,
1125  KFDF_PRECREATE),
1126  KNOWN_FOLDER(FOLDERID_Startup,
1127  CSIDL_STARTUP,
1128  "Startup",
1129  KF_CATEGORY_PERUSER,
1130  FOLDERID_Programs, GUID_NULL,
1131  "StartUp\0",
1132  NULL,
1134  KFDF_PRECREATE),
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,
1166  CSIDL_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,
1200  KFDF_PRECREATE),
1201  KNOWN_FOLDER(FOLDERID_UserProfiles,
1202  NO_CSIDL,
1203  "UserProfiles",
1204  KF_CATEGORY_FIXED,
1206  NULL,
1207  NULL,
1209  KFDF_PRECREATE),
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,
1247  CSIDL_MYVIDEO,
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,
1265  CSIDL_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 
1313 static 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);
1451  if (ret && winetest_interactive)
1452  printf("%s: %s\n", getFolderName(folder), path);
1453  ok(ret || optional,
1454  "SHGetSpecialFolderPathA(NULL, path, %s, FALSE) failed\n",
1456 }
1457 
1458 static 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  }
1479  type = testSHGetSpecialFolderLocation(testEntries[i].folder);
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  */
1507 static 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  */
1529 static 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),
1551  wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid));
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. */
1563 static void test_PidlTypes(void)
1564 {
1565  /* Desktop */
1568 
1571 }
1572 
1573 /* FIXME: Should be in shobjidl.idl */
1574 DEFINE_GUID(CLSID_NetworkExplorerFolder, 0xF02C1A0D, 0xBE21, 0x4350, 0x88, 0xB0, 0x73, 0x67, 0xFC, 0x96, 0xEF, 0x3C);
1575 DEFINE_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. */
1578 static 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  */
1593 static 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 */
1606 static 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  */
1630 static 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  */
1651 static 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 */
1680 static int myARGC;
1681 static char **myARGV;
1682 static char base[MAX_PATH];
1683 static char selfname[MAX_PATH];
1684 
1685 static BOOL init(void)
1686 {
1688  if (!GetCurrentDirectoryA(sizeof(base), base)) return FALSE;
1689  strcpy(selfname, myARGV[0]);
1690  return TRUE;
1691 }
1692 
1693 static 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");
1743  DeleteFileA(path);
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  */
1773 static 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);
1816  winetest_wait_child_process( info.hProcess );
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);
1822  RegFlushKey(key);
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)
1837  RegCloseKey(key);
1838  }
1839  else skip("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n", userShellFolders);
1840 }
1841 
1842 static 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 
1855 if (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 
1923 if (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 
1937 static 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 
2072 static 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;
2084  IKnownFolderManager *mgr = NULL;
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 
2113  CoInitialize(NULL);
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  }
2556  CoUninitialize();
2557 }
2558 
2559 
2560 static void test_DoEnvironmentSubst(void)
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 
2727 if (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 
2758  CloseHandle(file);
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 
2778  CloseHandle(file);
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 
2803 if (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 
2845 START_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: */
2861  test_parameters();
2862 
2863  /* check known values: */
2864  test_PidlTypes();
2865  test_GUIDs();
2866  test_EnvVars();
2867  testWinDir();
2868  testSystemDir();
2875  }
2876 }
static void test_PidlTypes(void)
Definition: shellpath.c:1563
static int myARGC
Definition: shellpath.c:1680
static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId)
Definition: shellpath.c:1967
#define PT_DRIVE
Definition: shellpath.c:54
static char ** myARGV
Definition: shellpath.c:1681
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
static BYTE testSHGetFolderLocation(int folder)
Definition: shellpath.c:1376
static const WCHAR path2[]
Definition: path.c:29
static void test_SHGetKnownFolderIDList(void)
Definition: shellpath.c:2789
struct _SHFILEOPSTRUCTA * LPSHFILEOPSTRUCTA
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:4023
#define CSIDL_COOKIES
Definition: shlobj.h:2035
#define PT_FOLDER
Definition: shellpath.c:63
static void doChild(const char *arg)
Definition: shellpath.c:1693
KF_DEFINITION_FLAGS kfdFlags
Definition: shobjidl.idl:3911
#define KNOWN_FOLDER(id, csidl, name, category, parent1, parent2, relative_path, parsing_name, attributes, definitionFlags)
Definition: shellpath.c:310
#define TRUE
Definition: types.h:120
static const GUID _FOLDERID_CredentialManager
Definition: shellpath.c:317
#define CloseHandle
Definition: compat.h:406
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:925
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
Definition: fci.c:115
static const struct shellExpectedValues optionalShellValues[]
Definition: shellpath.c:142
const char * sCsidl
Definition: shellpath.c:323
#define E_HANDLE
Definition: winerror.h:2850
KNOWNFOLDERID * REFKNOWNFOLDERID
Definition: shtypes.idl:147
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:420
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
#define CSIDL_MYVIDEO
Definition: shlobj.h:2017
HRESULT hr
Definition: shlfolder.c:183
static void test_ShellValues(const struct shellExpectedValues testEntries[], int numEntries, BOOL optional)
Definition: shellpath.c:1458
static const BYTE folderOrSpecialType[]
Definition: shellpath.c:109
#define CSIDL_COMMON_DESKTOPDIRECTORY
Definition: shlobj.h:2027
#define CSIDL_MYPICTURES
Definition: shlobj.h:2041
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
interface IMalloc * LPMALLOC
Definition: objfwd.h:12
#define CSIDL_DESKTOP
Definition: shlobj.h:2003
#define CSIDL_COMMON_FAVORITES
Definition: shlobj.h:2033
GLsizei const GLchar ** path
Definition: glext.h:7234
START_TEST(shellpath)
Definition: shellpath.c:2845
uint16_t * PWSTR
Definition: typedefs.h:54
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define HKEY_CURRENT_USER
Definition: winreg.h:11
char CHAR
Definition: xmlstorage.h:175
static const BYTE favoritesType[]
Definition: shellpath.c:108
const DWORD attributes
Definition: shellpath.c:329
static void test_GUIDs(void)
Definition: shellpath.c:1578
#define PT_YAGUID
Definition: shellpath.c:72
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define CSIDL_COMMON_STARTUP
Definition: shlobj.h:2026
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2282
HANDLE HWND
Definition: compat.h:13
HRESULT WINAPI SHGetMalloc(LPMALLOC *lpmal)
Definition: shellole.c:290
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3331
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define PT_SHELLEXT
Definition: shellpath.c:60
const char * wine_dbgstr_guid(const GUID *guid)
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
GLuint buffer
Definition: glext.h:5915
int startup(int argc, const char *argv[])
Definition: startup.c:430
#define PT_WORKGRP
Definition: shellpath.c:69
#define CSIDL_BITBUCKET
Definition: shlobj.h:2013
#define PT_CPL
Definition: shellpath.c:48
#define CSIDL_HISTORY
Definition: shlobj.h:2036
#define CSIDL_PROGRAM_FILES
Definition: shlobj.h:2040
#define CSIDL_COMMON_PICTURES
Definition: shlobj.h:2053
int winetest_interactive
DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#define CSIDL_PROFILE
Definition: shlobj.h:2042
static LPSTR
Definition: shellpath.c:88
#define CSIDL_COMMON_OEM_LINKS
Definition: shlobj.h:2057
LONG WINAPI RegFlushKey(HKEY hKey)
Definition: reg.c:2974
char * LPSTR
Definition: xmlstorage.h:182
#define CSIDL_FONTS
Definition: shlobj.h:2022
#define lstrlenW
Definition: compat.h:415
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
Definition: ntifs_ex.h:384
#define E_FAIL
Definition: ddrawi.h:102
static void test_knownFolders(void)
Definition: shellpath.c:2072
int32_t INT
Definition: typedefs.h:56
#define CSIDL_INTERNET_CACHE
Definition: shlobj.h:2034
WORD cb
Definition: shtypes.idl:27
DWORD dwAttributes
Definition: vdmdbg.h:34
#define CSIDL_COMMON_TEMPLATES
Definition: shlobj.h:2047
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2351
#define CSIDL_CONTROLS
Definition: shlobj.h:2006
#define CSIDL_PROGRAM_FILESX86
Definition: shlobj.h:2044
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2025
struct _test_info info[]
Definition: SetCursorPos.c:19
#define CSIDL_MYDOCUMENTS
Definition: shlobj.h:2015
static void test_SHGetSpecialFolderPath(BOOL optional, int folder)
Definition: shellpath.c:1443
#define CSIDL_RECENT
Definition: shlobj.h:2011
#define sprintf(buf, format,...)
Definition: sprintf.c:55
GLuint GLuint * names
Definition: glext.h:11545
static void test_DoEnvironmentSubst(void)
Definition: shellpath.c:2560
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
Definition: shellpath.c:1937
static void test_SHGetFolderPath(BOOL optional, int folder)
Definition: shellpath.c:1431
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
STDAPI DllGetVersion(DLLVERSIONINFO *info)
Definition: browseui.cpp:218
#define CSIDL_CONNECTIONS
Definition: shlobj.h:2051
BOOL WINAPI SHGetSpecialFolderPathA(HWND hwndOwner, LPSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:2561
#define CSIDL_PRINTERS
Definition: shlobj.h:2007
const GUID * guid
#define CSIDL_DRIVES
Definition: shlobj.h:2019
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
static void test_PathYetAnotherMakeUniqueName(void)
Definition: shellpath.c:2710
#define DECLARE_TYPE(x, y)
Definition: shellpath.c:117
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2079
#define CSIDL_FAVORITES
Definition: shlobj.h:2009
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
const int line
Definition: shellpath.c:331
unsigned int BOOL
Definition: ntddk_ex.h:94
static const BYTE ieSpecialType[]
Definition: shellpath.c:114
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:802
#define GENERIC_WRITE
Definition: nt_native.h:90
static BYTE testSHGetSpecialFolderLocation(int folder)
Definition: shellpath.c:1404
#define OLD_CSIDL_MYDOCUMENTS
Definition: shellpath.c:42
static GUID CLSID_CommonDocuments
Definition: shellpath.c:79
enum tagKF_DEFINITION_FLAGS KF_DEFINITION_FLAGS
#define E_INVALIDARG
Definition: ddrawi.h:101
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
smooth NULL
Definition: ftsmooth.c:416
#define PT_DRIVE2
Definition: shellpath.c:57
static const BYTE guidType[]
Definition: shellpath.c:105
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:189
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:399
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
const BYTE * types
Definition: shellpath.c:84
BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:926
#define CSIDL_COMMON_STARTMENU
Definition: shlobj.h:2024
static const BYTE personalType[]
Definition: shellpath.c:110
#define CSIDL_WINDOWS
Definition: shlobj.h:2038
#define CSIDL_CDBURN_AREA
Definition: shlobj.h:2058
const char * LPCSTR
Definition: xmlstorage.h:183
#define STARTF_USESHOWWINDOW
Definition: winbase.h:472
struct CFFOLDER folder
Definition: fdi.c:102
const KF_DEFINITION_FLAGS definitionFlags
Definition: shellpath.c:330
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define CSIDL_PROFILES
Definition: shellpath.c:231
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
const char * sName
Definition: shellpath.c:324
static LPWSTR
Definition: shellpath.c:99
static const struct shellExpectedValues requiredShellValues[]
Definition: shellpath.c:118
Definition: msg.h:41
static const BYTE workgroupType[]
Definition: shellpath.c:116
static void test_parameters(void)
Definition: shellpath.c:1313
const GUID IID_IOleObject
static UINT
Definition: shellpath.c:96
const char * sParsingName
Definition: shellpath.c:328
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
static const WCHAR nameW[]
Definition: main.c:46
static const BYTE shellExtType[]
Definition: shellpath.c:115
#define CSIDL_COMMON_ALTSTARTUP
Definition: shlobj.h:2032
#define CSIDL_COMMON_ADMINTOOLS
Definition: shlobj.h:2049
static void loadShell32(void)
Definition: shellpath.c:186
#define WAIT_OBJECT_0
Definition: winbase.h:387
DWORD WINAPI DoEnvironmentSubstW(LPWSTR pszString, UINT cchString)
Definition: shellord.c:1465
#define trace
Definition: atltest.h:70
#define PT_GUID
Definition: shellpath.c:51
Definition: cmds.c:130
#define CSIDL_ADMINTOOLS
Definition: shlobj.h:2050
#define PT_IESPECIAL2
Definition: shellpath.c:76
__wchar_t WCHAR
Definition: xmlstorage.h:180
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:2695
LONG HRESULT
Definition: typedefs.h:77
static LPITEMIDLIST *static BOOL
Definition: shellpath.c:91
const GUID IID_IUnknown
#define CSIDL_LOCAL_APPDATA
Definition: shlobj.h:2030
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:4742
#define CSIDL_SENDTO
Definition: shlobj.h:2012
#define CSIDL_APPDATA
Definition: shlobj.h:2028
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
static PCWSTR
Definition: shellpath.c:100
#define FILE_FLAG_DELETE_ON_CLOSE
Definition: disk.h:42
static const GUID _FOLDERID_SystemCertificates
Definition: shellpath.c:316
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define GET_PROC(func)
static const BYTE folderType[]
Definition: shellpath.c:107
unsigned long DWORD
Definition: ntddk_ex.h:95
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
Definition: id3.c:18
static const GUID _FOLDERID_DpapiKeys
Definition: shellpath.c:315
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int winetest_get_mainargs(char ***pargv)
#define CSIDL_COMMON_VIDEO
Definition: shlobj.h:2054
const int csidl
Definition: shellpath.c:322
DWORD WINAPI DoEnvironmentSubstA(LPSTR pszString, UINT cchString)
Definition: shellord.c:1420
static HANDLE
Definition: shellpath.c:88
static const BYTE printersType[]
Definition: shellpath.c:113
int ret
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
BOOL known_folder_found[ARRAY_SIZE(known_folders)]
Definition: shellpath.c:1311
static const WCHAR L[]
Definition: oid.c:1250
#define todo_wine
Definition: test.h:163
#define CSIDL_RESOURCES_LOCALIZED
Definition: shlobj.h:2056
#define CSIDL_COMMON_APPDATA
Definition: shlobj.h:2037
static const GUID _FOLDERID_CryptoKeys
Definition: shellpath.c:314
static const char * getFolderName(int folder)
Definition: shellpath.c:235
HKEY key
Definition: reg.c:42
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
unsigned char BYTE
Definition: mem.h:68
#define GUID_NULL
Definition: ks.h:106
#define NO_CSIDL
Definition: shellpath.c:308
static const WCHAR shortW[]
Definition: tokenize.c:73
static LPMALLOC pMalloc
Definition: shellpath.c:104
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:2345
LPSTR WINAPI CharPrevA(_In_ LPCSTR, _In_ LPCSTR)
#define broken(x)
Definition: _sntprintf.h:21
#define CSIDL_PROGRAM_FILES_COMMONX86
Definition: shlobj.h:2046
#define CSIDL_STARTUP
Definition: shlobj.h:2010
void winetest_wait_child_process(HANDLE process)
#define CSIDL_PROGRAM_FILES_COMMON
Definition: shlobj.h:2045
#define CSIDL_COMMON_MUSIC
Definition: shlobj.h:2052
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
const KF_CATEGORY category
Definition: shellpath.c:325
const KNOWNFOLDERID * fidParents[2]
Definition: shellpath.c:326
#define CSIDL_TO_STR(x)
#define S_OK
Definition: intsafe.h:59
#define CREATE_ALWAYS
Definition: disk.h:72
#define CSIDL_RESOURCES
Definition: shlobj.h:2055
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:2696
static WCHAR does_not_existW[]
Definition: localmon.c:90
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define lstrcpyW
Definition: compat.h:414
static void testWinDir(void)
Definition: shellpath.c:1630
static BOOL init(void)
Definition: shellpath.c:1685
const char * sFolderId
Definition: shellpath.c:321
HRESULT WINAPI SHGetFolderPathA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath)
Definition: shellpath.c:2329
static char selfname[MAX_PATH]
Definition: shellpath.c:1683
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define ARRAY_SIZE(a)
Definition: main.h:24
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define CSIDL_PRINTHOOD
Definition: shlobj.h:2029
static void matchGUID(int folder, const GUID *guid, const GUID *guid_alt)
Definition: shellpath.c:1529
#define ok(value,...)
Definition: atltest.h:57
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2336
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
#define PT_FOLDERW
Definition: shellpath.c:66
#define CSIDL_COMMON_DOCUMENTS
Definition: shlobj.h:2048
static PWSTR *static PWSTR
Definition: shellpath.c:98
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
#define CSIDL_FLAG_CREATE
#define CSIDL_INTERNET
Definition: shlobj.h:2004
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
#define MultiByteToWideChar
Definition: compat.h:100
#define CreateFileW
Definition: compat.h:408
#define CSIDL_NETHOOD
Definition: shlobj.h:2021
#define skip(...)
Definition: atltest.h:64
int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp)
Definition: shlfileop.cpp:1000
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
#define CSIDL_PERSONAL
Definition: shlobj.h:2008
static int
Definition: shellpath.c:88
static BOOL myPathIsRootA(LPCSTR lpszPath)
Definition: shellpath.c:1606
#define CSIDL_STARTMENU
Definition: shlobj.h:2014
static const BYTE controlPanelType[]
Definition: shellpath.c:106
#define CSIDL_ALTSTARTUP
Definition: shlobj.h:2031
GLuint res
Definition: glext.h:9613
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define CSIDL_COMPUTERSNEARME
Definition: shlobj.h:2059
#define HIWORD(l)
Definition: typedefs.h:246
static PIDLIST_ABSOLUTE *static DLLVERSIONINFO shellVersion
Definition: shellpath.c:103
static BOOL ILIsEmpty(_In_opt_ LPCITEMIDLIST pidl)
Definition: shlobj.h:2310
static void test_SHGetFolderPathEx(void)
Definition: shellpath.c:1842
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static void test_NonExistentPath(void)
Definition: shellpath.c:1773
static const WCHAR longW[]
Definition: tokenize.c:63
pointer_default(unique)] interface IFileDialogCustomize enum tagKF_REDIRECTION_CAPABILITIES KF_REDIRECTION_CAPABILITIES
static LPITEMIDLIST *static LPITEMIDLIST(WINAPI *pILFindLastID)(LPCITEMIDLIST)
#define GetProcAddress(x, y)
Definition: compat.h:418
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:2606
SHITEMID mkid
Definition: shtypes.idl:34
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:320
#define CSIDL_SYSTEM
Definition: shlobj.h:2039
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2018
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4812
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static DWORD
Definition: shellpath.c:88
#define CSIDL_NETWORK
Definition: shlobj.h:2020
static void testSystemDir(void)
Definition: shellpath.c:1651
const KNOWNFOLDERID * folderId
Definition: shellpath.c:320
#define CSIDL_PROGRAMS
Definition: shlobj.h:2005
#define CSIDL_TEMPLATES
Definition: shlobj.h:2023
#define memset(x, y, z)
Definition: compat.h:39
const char * sRelativePath
Definition: shellpath.c:327
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
static void matchSpecialFolderPathToEnv(int folder, const char *envVar)
Definition: shellpath.c:1507
#define win_skip
Definition: test.h:150
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:404
#define LOWORD(l)
Definition: pedump.c:82
static HMODULE hShell32
Definition: string.c:34
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define CSIDL_SYSTEMX86
Definition: shlobj.h:2043
#define WINE_ATTRIBUTES_OPTIONAL
Definition: shellpath.c:309
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static LPSTR myPathRemoveBackslashA(LPSTR lpszPath)
Definition: shellpath.c:1613
#define ok_(x1, x2)
Definition: atltest.h:61
Definition: path.c:41
#define printf
Definition: config.h:203
static void FreeKnownFolderDefinitionFields(KNOWNFOLDER_DEFINITION *pKFD)") cpp_quote("
Definition: shobjidl.idl:4030
#define CSIDL_MYMUSIC
Definition: shlobj.h:2016
static const struct knownFolderDef known_folders[]
Definition: shellpath.c:343
Definition: fci.c:126
static HRESULT(WINAPI *pDllGetVersion)(DLLVERSIONINFO *)
static void test_EnvVars(void)
Definition: shellpath.c:1593