ReactOS  0.4.12-dev-918-g6c6e7b8
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  continue;
1879  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1880  ok(path != NULL, "expected path != NULL\n");
1881 
1882  path2 = NULL;
1883  hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_SIMPLE_IDLIST, NULL, &path2);
1884  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1885  ok(path2 != NULL, "expected path != NULL\n");
1886  ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n", wine_dbgstr_w(path), wine_dbgstr_w(path2));
1888 
1889  path2 = NULL;
1890  hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_DONT_UNEXPAND, NULL, &path2);
1891  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1892  ok(path2 != NULL, "expected path != NULL\n");
1893  ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n", wine_dbgstr_w(path), wine_dbgstr_w(path2));
1895 
1896  path2 = NULL;
1897  hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_UNEXPAND, NULL, &path2);
1898  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1899  ok(path2 != NULL, "expected path != NULL\n");
1900  ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n", wine_dbgstr_w(path), wine_dbgstr_w(path2));
1902 
1904  }
1905 
1906  path = NULL;
1907  hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path);
1908  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1909  ok(path != NULL, "expected path != NULL\n");
1910 
1911  hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, MAX_PATH);
1912  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1913  ok(!lstrcmpiW(path, buffer), "expected equal paths\n");
1914  len = lstrlenW(buffer);
1916 
1917  hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, 0);
1918  ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
1919 
1920 if (0) { /* crashes */
1921  hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, NULL, len + 1);
1922  ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
1923 
1924  hr = pSHGetFolderPathEx(NULL, 0, NULL, buffer, MAX_PATH);
1925  ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
1926 }
1927  hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len);
1928  ok(hr == E_NOT_SUFFICIENT_BUFFER, "expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hr);
1929 
1930  hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len + 1);
1931  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
1932 }
1933 
1934 static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
1935 {
1936  WCHAR wstr[MAX_PATH];
1937 
1938  if(!needle && !hay)
1939  return TRUE;
1940 
1941  while(hay && *hay)
1942  {
1943  DWORD ret;
1944 
1945  if(strcmp(hay, "(null)") == 0 && !needle)
1946  return TRUE;
1947 
1948  ret = MultiByteToWideChar(CP_ACP, 0, hay, -1, wstr, ARRAY_SIZE(wstr));
1949  if(ret == 0)
1950  {
1951  ok(0, "Failed to convert string\n");
1952  return FALSE;
1953  }
1954 
1955  if(lstrcmpW(wstr, needle) == 0)
1956  return TRUE;
1957 
1958  hay += strlen(hay) + 1;
1959  }
1960 
1961  return FALSE;
1962 }
1963 
1965 {
1966  HRESULT hr;
1967  int csidl, expectedCsidl, ret;
1969  IKnownFolder *folder;
1970  WCHAR sName[1024];
1971  BOOL found = FALSE;
1972  unsigned int i;
1973 
1974  for (i = 0; i < ARRAY_SIZE(known_folders); ++i)
1975  {
1976  const struct knownFolderDef *known_folder = &known_folders[i];
1977 
1978  if(IsEqualGUID(known_folder->folderId, folderId))
1979  {
1981  found = TRUE;
1982  /* verify CSIDL */
1983  if(!(known_folder->csidl & NO_CSIDL))
1984  {
1985  /* mask off winetest flags */
1986  expectedCsidl = known_folder->csidl & 0xFFFF;
1987 
1988  hr = IKnownFolderManager_FolderIdToCsidl(mgr, folderId, &csidl);
1989  ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot retrieve CSIDL for folder %s\n", known_folder->sFolderId);
1990 
1991  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);
1992  }
1993 
1994  hr = IKnownFolderManager_GetFolder(mgr, folderId, &folder);
1995  ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot get known folder for %s\n", known_folder->sFolderId);
1996  if(SUCCEEDED(hr))
1997  {
1998  hr = IKnownFolder_GetFolderDefinition(folder, &kfd);
1999  ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot get known folder definition for %s\n", known_folder->sFolderId);
2000  if(SUCCEEDED(hr))
2001  {
2002  ret = MultiByteToWideChar(CP_ACP, 0, known_folder->sName, -1, sName, ARRAY_SIZE(sName));
2003  ok_(__FILE__, known_folder->line)(ret != 0, "cannot convert known folder name \"%s\" to wide characters\n", known_folder->sName);
2004 
2005  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));
2006 
2007  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);
2008 
2009  ok_(__FILE__, known_folder->line)(IsEqualGUID(known_folder->fidParents[0], &kfd.fidParent) ||
2010  IsEqualGUID(known_folder->fidParents[1], &kfd.fidParent),
2011  "invalid known folder parent for %s: %s retrieved\n",
2012  known_folder->sFolderId, wine_dbgstr_guid(&kfd.fidParent));
2013 
2014  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));
2015 
2016  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));
2017 
2018  ok_(__FILE__, known_folder->line)(known_folder->attributes == kfd.dwAttributes ||
2019  (known_folder->csidl & WINE_ATTRIBUTES_OPTIONAL && kfd.dwAttributes == 0),
2020  "invalid known folder attributes for %s: 0x%08x expected, but 0x%08x retrieved\n", known_folder->sFolderId, known_folder->attributes, kfd.dwAttributes);
2021 
2022  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);
2023 
2025  }
2026 
2027  IKnownFolder_Release(folder);
2028  }
2029 
2030  break;
2031  }
2032  }
2033 
2034  if(!found)
2035  {
2036  trace("unknown known folder found: %s\n", wine_dbgstr_guid(folderId));
2037 
2038  hr = IKnownFolderManager_GetFolder(mgr, folderId, &folder);
2039  ok(hr == S_OK, "cannot get known folder for %s\n", wine_dbgstr_guid(folderId));
2040  if(SUCCEEDED(hr))
2041  {
2042  hr = IKnownFolder_GetFolderDefinition(folder, &kfd);
2043  todo_wine
2044  ok(hr == S_OK, "cannot get known folder definition for %s\n", wine_dbgstr_guid(folderId));
2045  if(SUCCEEDED(hr))
2046  {
2047  trace(" category: %d\n", kfd.category);
2048  trace(" name: %s\n", wine_dbgstr_w(kfd.pszName));
2049  trace(" description: %s\n", wine_dbgstr_w(kfd.pszDescription));
2050  trace(" parent: %s\n", wine_dbgstr_guid(&kfd.fidParent));
2051  trace(" relative path: %s\n", wine_dbgstr_w(kfd.pszRelativePath));
2052  trace(" parsing name: %s\n", wine_dbgstr_w(kfd.pszParsingName));
2053  trace(" tooltip: %s\n", wine_dbgstr_w(kfd.pszTooltip));
2054  trace(" localized name: %s\n", wine_dbgstr_w(kfd.pszLocalizedName));
2055  trace(" icon: %s\n", wine_dbgstr_w(kfd.pszIcon));
2056  trace(" security: %s\n", wine_dbgstr_w(kfd.pszSecurity));
2057  trace(" attributes: 0x%08x\n", kfd.dwAttributes);
2058  trace(" flags: 0x%08x\n", kfd.kfdFlags);
2059  trace(" type: %s\n", wine_dbgstr_guid(&kfd.ftidType));
2061  }
2062 
2063  IKnownFolder_Release(folder);
2064  }
2065  }
2066 }
2067 #undef NO_CSIDL
2068 
2069 static void test_knownFolders(void)
2070 {
2071  static const WCHAR sWindows[] = {'W','i','n','d','o','w','s',0};
2072  static const WCHAR sWindows2[] = {'w','i','n','d','o','w','s',0};
2073  static const WCHAR sExample[] = {'E','x','a','m','p','l','e',0};
2074  static const WCHAR sExample2[] = {'E','x','a','m','p','l','e','2',0};
2075  static const WCHAR sSubFolder[] = {'S','u','b','F','o','l','d','e','r',0};
2076  static const WCHAR sNoSuch[] = {'N','o','S','u','c','h',0};
2077  static const WCHAR sBackslash[] = {'\\',0};
2078  static const KNOWNFOLDERID newFolderId = {0x01234567, 0x89AB, 0xCDEF, {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x01} };
2079  static const KNOWNFOLDERID subFolderId = {0xFEDCBA98, 0x7654, 0x3210, {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF} };
2080  HRESULT hr;
2081  IKnownFolderManager *mgr = NULL;
2082  IKnownFolder *folder = NULL, *subFolder = NULL;
2083  KNOWNFOLDERID folderId, *folders;
2084  KF_CATEGORY cat = 0;
2085  KNOWNFOLDER_DEFINITION kfDefinition, kfSubDefinition;
2086  int csidl, i;
2087  UINT nCount = 0;
2088  LPWSTR folderPath, errorMsg;
2089  KF_REDIRECTION_CAPABILITIES redirectionCapabilities = 1;
2090  WCHAR sWinDir[MAX_PATH], sExamplePath[MAX_PATH], sExample2Path[MAX_PATH], sSubFolderPath[MAX_PATH], sSubFolder2Path[MAX_PATH];
2091  BOOL bRes;
2093 
2094  GetWindowsDirectoryW( sWinDir, MAX_PATH );
2095 
2096  GetTempPathW(ARRAY_SIZE(sExamplePath), sExamplePath);
2097  lstrcatW(sExamplePath, sExample);
2098 
2099  GetTempPathW(ARRAY_SIZE(sExample2Path), sExample2Path);
2100  lstrcatW(sExample2Path, sExample2);
2101 
2102  lstrcpyW(sSubFolderPath, sExamplePath);
2103  lstrcatW(sSubFolderPath, sBackslash);
2104  lstrcatW(sSubFolderPath, sSubFolder);
2105 
2106  lstrcpyW(sSubFolder2Path, sExample2Path);
2107  lstrcatW(sSubFolder2Path, sBackslash);
2108  lstrcatW(sSubFolder2Path, sSubFolder);
2109 
2110  CoInitialize(NULL);
2111 
2112  hr = CoCreateInstance(&CLSID_KnownFolderManager, NULL, CLSCTX_INPROC_SERVER,
2113  &IID_IKnownFolderManager, (LPVOID*)&mgr);
2114  if(hr == REGDB_E_CLASSNOTREG)
2115  win_skip("IKnownFolderManager unavailable\n");
2116  else
2117  {
2118  IUnknown *unk;
2119 
2120  ok(hr == S_OK, "failed to create KnownFolderManager instance: 0x%08x\n", hr);
2121 
2122  hr = IKnownFolderManager_QueryInterface(mgr, &IID_IMarshal, (void**)&unk);
2123  ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2124 
2125  hr = IKnownFolderManager_FolderIdFromCsidl(mgr, CSIDL_WINDOWS, &folderId);
2126  ok(hr == S_OK, "failed to convert CSIDL to KNOWNFOLDERID: 0x%08x\n", hr);
2127  ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2128 
2129  hr = IKnownFolderManager_FolderIdToCsidl(mgr, &FOLDERID_Windows, &csidl);
2130  ok(hr == S_OK, "failed to convert CSIDL to KNOWNFOLDERID: 0x%08x\n", hr);
2131  ok(csidl == CSIDL_WINDOWS, "invalid CSIDL returned\n");
2132 
2133  hr = IKnownFolderManager_GetFolder(mgr, &FOLDERID_Windows, &folder);
2134  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2135  if(SUCCEEDED(hr))
2136  {
2137  hr = IKnownFolder_QueryInterface(folder, &IID_IMarshal, (void**)&unk);
2138  ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2139 
2140  hr = IKnownFolder_GetCategory(folder, &cat);
2141  ok(hr == S_OK, "failed to get folder category: 0x%08x\n", hr);
2142  ok(cat==KF_CATEGORY_FIXED, "invalid folder category: %d\n", cat);
2143 
2144  hr = IKnownFolder_GetId(folder, &folderId);
2145  ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2146  ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2147 
2148  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2149  ok(hr == S_OK, "failed to get path from known folder: 0x%08x\n", hr);
2150  ok(lstrcmpiW(sWinDir, folderPath)==0, "invalid path returned: \"%s\", expected: \"%s\"\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sWinDir));
2151  CoTaskMemFree(folderPath);
2152 
2153  hr = IKnownFolder_GetRedirectionCapabilities(folder, &redirectionCapabilities);
2154  ok(hr == S_OK, "failed to get redirection capabilities: 0x%08x\n", hr);
2155  todo_wine
2156  ok(redirectionCapabilities==0, "invalid redirection capabilities returned: %d\n", redirectionCapabilities);
2157 
2158  hr = IKnownFolder_SetPath(folder, 0, sWinDir);
2159  todo_wine
2160  ok(hr == E_INVALIDARG, "unexpected value from SetPath: 0x%08x\n", hr);
2161 
2162  hr = IKnownFolder_GetFolderDefinition(folder, &kfDefinition);
2163  ok(hr == S_OK, "failed to get folder definition: 0x%08x\n", hr);
2164  if(SUCCEEDED(hr))
2165  {
2166  ok(kfDefinition.category==KF_CATEGORY_FIXED, "invalid folder category: 0x%08x\n", kfDefinition.category);
2167  ok(lstrcmpW(kfDefinition.pszName, sWindows)==0, "invalid folder name: %s\n", wine_dbgstr_w(kfDefinition.pszName));
2168  ok(kfDefinition.dwAttributes==0, "invalid folder attributes: %d\n", kfDefinition.dwAttributes);
2169  FreeKnownFolderDefinitionFields(&kfDefinition);
2170  }
2171 
2172  hr = IKnownFolder_Release(folder);
2173  ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2174  }
2175 
2176  hr = IKnownFolderManager_GetFolderByName(mgr, sWindows, &folder);
2177  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2178  if(SUCCEEDED(hr))
2179  {
2180  hr = IKnownFolder_GetId(folder, &folderId);
2181  ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2182  ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2183 
2184  hr = IKnownFolder_Release(folder);
2185  ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2186  }
2187 
2188  hr = IKnownFolderManager_GetFolderByName(mgr, sWindows2, &folder);
2189  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2190  if(SUCCEEDED(hr))
2191  {
2192  hr = IKnownFolder_GetId(folder, &folderId);
2193  ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2194  ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2195 
2196  hr = IKnownFolder_Release(folder);
2197  ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2198  }
2199 
2200  folder = (IKnownFolder *)0xdeadbeef;
2201  hr = IKnownFolderManager_GetFolderByName(mgr, sNoSuch, &folder);
2202  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
2203  ok(folder == NULL, "got %p\n", folder);
2204 
2205  for(i=0; i < ARRAY_SIZE(known_folder_found); ++i)
2207 
2208  hr = IKnownFolderManager_GetFolderIds(mgr, &folders, &nCount);
2209  ok(hr == S_OK, "failed to get known folders: 0x%08x\n", hr);
2210  for(i=0;i<nCount;++i)
2211  check_known_folder(mgr, &folders[i]);
2212 
2213  for(i=0; i < ARRAY_SIZE(known_folder_found); ++i)
2214  if(!known_folder_found[i])
2215  trace("Known folder %s not found on current platform\n", known_folders[i].sFolderId);
2216 
2217  CoTaskMemFree(folders);
2218 
2219  /* test of registering new known folders */
2220  bRes = CreateDirectoryW(sExamplePath, NULL);
2221  ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sExamplePath));
2222  bRes = CreateDirectoryW(sExample2Path, NULL);
2223  ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sExample2Path));
2224  bRes = CreateDirectoryW(sSubFolderPath, NULL);
2225  ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sSubFolderPath));
2226 
2227  ZeroMemory(&kfDefinition, sizeof(kfDefinition));
2228  kfDefinition.category = KF_CATEGORY_PERUSER;
2229  kfDefinition.pszName = CoTaskMemAlloc(sizeof(sExample));
2230  lstrcpyW(kfDefinition.pszName, sExample);
2231  kfDefinition.pszDescription = CoTaskMemAlloc(sizeof(sExample));
2232  lstrcpyW(kfDefinition.pszDescription, sExample);
2233  kfDefinition.pszRelativePath = CoTaskMemAlloc(sizeof(sExamplePath));
2234  lstrcpyW(kfDefinition.pszRelativePath, sExamplePath);
2235 
2236  hr = IKnownFolderManager_RegisterFolder(mgr, &newFolderId, &kfDefinition);
2238  win_skip("No permissions required to register custom known folder\n");
2239  else
2240  {
2241  ok(hr == S_OK, "failed to register known folder: 0x%08x\n", hr);
2242  if(SUCCEEDED(hr))
2243  {
2244  hr = IKnownFolderManager_GetFolder(mgr, &newFolderId, &folder);
2245  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2246  if(SUCCEEDED(hr))
2247  {
2248  hr = IKnownFolder_GetCategory(folder, &cat);
2249  ok(hr == S_OK, "failed to get folder category: hr=0x%0x\n", hr);
2250  ok(cat == KF_CATEGORY_PERUSER, "invalid category returned: %d, while %d (KF_CATEGORY_PERUSER) expected\n", cat, KF_CATEGORY_PERUSER);
2251 
2252  hr = IKnownFolder_GetId(folder, &folderId);
2253  ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2254  ok(IsEqualGUID(&folderId, &newFolderId)==TRUE, "invalid KNOWNFOLDERID returned\n");
2255 
2256  /* current path should be Temp\Example */
2257  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2258  ok(hr == S_OK, "failed to get path from known folder: 0x%08x\n", hr);
2259  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2260  CoTaskMemFree(folderPath);
2261 
2262  /* register sub-folder and mark it as child of Example folder */
2263  ZeroMemory(&kfSubDefinition, sizeof(kfSubDefinition));
2264  kfSubDefinition.category = KF_CATEGORY_PERUSER;
2265  kfSubDefinition.pszName = CoTaskMemAlloc(sizeof(sSubFolder));
2266  lstrcpyW(kfSubDefinition.pszName, sSubFolder);
2267  kfSubDefinition.pszDescription = CoTaskMemAlloc(sizeof(sSubFolder));
2268  lstrcpyW(kfSubDefinition.pszDescription, sSubFolder);
2269  kfSubDefinition.pszRelativePath = CoTaskMemAlloc(sizeof(sSubFolder));
2270  lstrcpyW(kfSubDefinition.pszRelativePath, sSubFolder);
2271  kfSubDefinition.fidParent = newFolderId;
2272 
2273  hr = IKnownFolderManager_RegisterFolder(mgr, &subFolderId, &kfSubDefinition);
2274  ok(hr == S_OK, "failed to register known folder: 0x%08x\n", hr);
2275  if(SUCCEEDED(hr))
2276  {
2277 
2278  hr = IKnownFolderManager_GetFolder(mgr, &subFolderId, &subFolder);
2279  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2280  if(SUCCEEDED(hr))
2281  {
2282  /* check sub folder path */
2283  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2284  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2285  ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2286  CoTaskMemFree(folderPath);
2287 
2288 
2289  /* try to redirect Example to Temp\Example2 */
2290  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 0, NULL, &errorMsg);
2291  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2292 
2293  /* verify */
2294  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2295  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2296  ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2297  CoTaskMemFree(folderPath);
2298 
2299  /* verify sub folder - it should fail now, as we redirected its parent folder, but we have no sub folder in new location */
2300  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2301  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "unexpected value from GetPath(): 0x%08x\n", hr);
2302  ok(folderPath==NULL, "invalid known folder path retrieved: \"%s\" when NULL pointer was expected\n", wine_dbgstr_w(folderPath));
2303  CoTaskMemFree(folderPath);
2304 
2305 
2306  /* set Example path to original. Using SetPath() is valid here, as it also uses redirection internally */
2307  hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2308  ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2309 
2310  /* verify */
2311  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2312  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2313  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2314  CoTaskMemFree(folderPath);
2315 
2316 
2317  /* create sub folder in Temp\Example2 */
2318  bRes = CreateDirectoryW(sSubFolder2Path, NULL);
2319  ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sSubFolder2Path));
2320 
2321  /* again perform that same redirection */
2322  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 0, NULL, &errorMsg);
2323  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2324 
2325  /* verify sub folder. It should succeed now, as the required sub folder exists */
2326  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2327  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2328  ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2329  CoTaskMemFree(folderPath);
2330 
2331  /* remove newly created directory */
2332  RemoveDirectoryW(sSubFolder2Path);
2333 
2334  /* verify subfolder. It still succeeds, so Windows does not check folder presence each time */
2335  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2336  todo_wine
2337  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2338  todo_wine
2339  ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2340  CoTaskMemFree(folderPath);
2341 
2342 
2343  /* set Example path to original */
2344  hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2345  ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2346 
2347  /* verify */
2348  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2349  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2350  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2351  CoTaskMemFree(folderPath);
2352 
2353  /* verify sub folder */
2354  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2355  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2356  ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2357  CoTaskMemFree(folderPath);
2358 
2359 
2360  /* create sub folder in Temp\Example2 */
2361  bRes = CreateDirectoryW(sSubFolder2Path, NULL);
2362  ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sSubFolder2Path));
2363 
2364  /* do that same redirection, but try to exclude sub-folder */
2365  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 1, &subFolderId, &errorMsg);
2366  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2367 
2368  /* verify */
2369  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2370  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2371  ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2372  CoTaskMemFree(folderPath);
2373 
2374  /* 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 */
2375  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2376  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2377  ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2378  CoTaskMemFree(folderPath);
2379 
2380  /* remove newly created directory */
2381  RemoveDirectoryW(sSubFolder2Path);
2382 
2383 
2384  /* set Example path to original */
2385  hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2386  ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2387 
2388  /* verify */
2389  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2390  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2391  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2392  CoTaskMemFree(folderPath);
2393 
2394  /* verify sub folder */
2395  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2396  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2397  ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2398  CoTaskMemFree(folderPath);
2399 
2400 
2401  /* do that same redirection again, but set it to copy content. It should also copy the sub folder, so checking it would succeed now */
2402  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS, sExample2Path, 0, NULL, &errorMsg);
2403  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2404 
2405  /* verify */
2406  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2407  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2408  ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2409  CoTaskMemFree(folderPath);
2410 
2411  /* verify sub folder */
2412  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2413  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2414  ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2415  CoTaskMemFree(folderPath);
2416 
2417  /* remove copied directory */
2418  RemoveDirectoryW(sSubFolder2Path);
2419 
2420 
2421  /* set Example path to original */
2422  hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2423  ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2424 
2425  /* verify */
2426  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2427  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2428  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2429  CoTaskMemFree(folderPath);
2430 
2431  /* verify sub folder */
2432  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2433  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2434  ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2435  CoTaskMemFree(folderPath);
2436 
2437 
2438  /* redirect again, set it to copy content and remove originals */
2439  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS | KF_REDIRECT_DEL_SOURCE_CONTENTS, sExample2Path, 0, NULL, &errorMsg);
2440  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2441 
2442  /* verify */
2443  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2444  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2445  ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2446  CoTaskMemFree(folderPath);
2447 
2448  /* verify sub folder */
2449  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2450  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2451  ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2452  CoTaskMemFree(folderPath);
2453 
2454  /* check if original directory was really removed */
2455  dwAttributes = GetFileAttributesW(sExamplePath);
2456  ok(dwAttributes==INVALID_FILE_ATTRIBUTES, "directory should not exist, but has attributes: 0x%08x\n", dwAttributes );
2457 
2458 
2459  /* redirect (with copy) to original path */
2460  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS, sExamplePath, 0, NULL, &errorMsg);
2461  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2462 
2463  /* verify */
2464  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2465  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2466  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2467  CoTaskMemFree(folderPath);
2468 
2469  /* verify sub folder */
2470  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2471  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2472  ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2473  CoTaskMemFree(folderPath);
2474 
2475  /* check shell utility functions */
2476  if(!pSHGetKnownFolderPath || !pSHSetKnownFolderPath)
2477  todo_wine
2478  win_skip("cannot get SHGet/SetKnownFolderPath routines\n");
2479  else
2480  {
2481  /* try to get current known folder path */
2482  hr = pSHGetKnownFolderPath(&newFolderId, 0, NULL, &folderPath);
2483  todo_wine
2484  ok(hr==S_OK, "cannot get known folder path: hr=0x%0x\n", hr);
2485  todo_wine
2486  ok(lstrcmpW(folderPath, sExamplePath)==0, "invalid path returned: %s\n", wine_dbgstr_w(folderPath));
2487 
2488  /* set it to new value */
2489  hr = pSHSetKnownFolderPath(&newFolderId, 0, NULL, sExample2Path);
2490  todo_wine
2491  ok(hr==S_OK, "cannot set known folder path: hr=0x%0x\n", hr);
2492 
2493  /* check if it changed */
2494  hr = pSHGetKnownFolderPath(&newFolderId, 0, NULL, &folderPath);
2495  todo_wine
2496  ok(hr==S_OK, "cannot get known folder path: hr=0x%0x\n", hr);
2497  todo_wine
2498  ok(lstrcmpW(folderPath, sExample2Path)==0, "invalid path returned: %s\n", wine_dbgstr_w(folderPath));
2499 
2500  /* set it back */
2501  hr = pSHSetKnownFolderPath(&newFolderId, 0, NULL, sExamplePath);
2502  todo_wine
2503  ok(hr==S_OK, "cannot set known folder path: hr=0x%0x\n", hr);
2504  }
2505 
2506  IKnownFolder_Release(subFolder);
2507  }
2508 
2509  hr = IKnownFolderManager_UnregisterFolder(mgr, &subFolderId);
2510  ok(hr == S_OK, "failed to unregister folder: 0x%08x\n", hr);
2511  }
2512 
2513  FreeKnownFolderDefinitionFields(&kfSubDefinition);
2514 
2515  hr = IKnownFolder_Release(folder);
2516  ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2517 
2518  /* update the folder */
2519  CoTaskMemFree(kfDefinition.pszName);
2520  kfDefinition.pszName = CoTaskMemAlloc(sizeof(sExample2));
2521  lstrcpyW(kfDefinition.pszName, sExample2);
2522  hr = IKnownFolderManager_RegisterFolder(mgr, &newFolderId, &kfDefinition);
2523  ok(hr == S_OK, "failed to re-register known folder: 0x%08x\n", hr);
2524 
2525  hr = IKnownFolderManager_GetFolder(mgr, &newFolderId, &folder);
2526  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2527 
2528  hr = IKnownFolder_GetFolderDefinition(folder, &kfSubDefinition);
2529  ok(hr == S_OK, "failed to get folder definition: 0x%08x\n", hr);
2530  ok(!memcmp(kfDefinition.pszName, kfSubDefinition.pszName, sizeof(sExample2)),
2531  "Got wrong updated name: %s\n", wine_dbgstr_w(kfSubDefinition.pszName));
2532 
2533  FreeKnownFolderDefinitionFields(&kfSubDefinition);
2534 
2535  hr = IKnownFolder_Release(folder);
2536  ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2537  }
2538 
2539  hr = IKnownFolderManager_UnregisterFolder(mgr, &newFolderId);
2540  ok(hr == S_OK, "failed to unregister folder: 0x%08x\n", hr);
2541  }
2542  }
2543  FreeKnownFolderDefinitionFields(&kfDefinition);
2544 
2545  RemoveDirectoryW(sSubFolder2Path);
2546  RemoveDirectoryW(sSubFolderPath);
2547  RemoveDirectoryW(sExamplePath);
2548  RemoveDirectoryW(sExample2Path);
2549 
2550  hr = IKnownFolderManager_Release(mgr);
2551  ok(hr == S_OK, "failed to release KnownFolderManager instance: 0x%08x\n", hr);
2552  }
2553  CoUninitialize();
2554 }
2555 
2556 
2557 static void test_DoEnvironmentSubst(void)
2558 {
2559  WCHAR expectedW[MAX_PATH];
2560  WCHAR bufferW[MAX_PATH];
2561  CHAR expectedA[MAX_PATH];
2562  CHAR bufferA[MAX_PATH];
2563  DWORD res;
2564  DWORD res2;
2565  DWORD len;
2566  INT i;
2567  static const WCHAR does_not_existW[] = {'%','D','O','E','S','_','N','O','T','_','E','X','I','S','T','%',0};
2568  static const CHAR does_not_existA[] = "%DOES_NOT_EXIST%";
2569  static const CHAR *names[] = {
2570  /* interactive apps and services (works on all windows versions) */
2571  "%ALLUSERSPROFILE%", "%APPDATA%", "%LOCALAPPDATA%",
2572  "%NUMBER_OF_PROCESSORS%", "%OS%", "%PROCESSOR_ARCHITECTURE%",
2573  "%PROCESSOR_IDENTIFIER%", "%PROCESSOR_LEVEL%", "%PROCESSOR_REVISION%",
2574  "%ProgramFiles%", "%SystemDrive%",
2575  "%SystemRoot%", "%USERPROFILE%", "%windir%",
2576  /* todo_wine: "%COMPUTERNAME%", "%ProgramData%", "%PUBLIC%", */
2577 
2578  /* replace more than one var is allowed */
2579  "%HOMEDRIVE%%HOMEPATH%",
2580  "%OS% %windir%"}; /* always the last entry in the table */
2581 
2582  for (i = 0; i < (ARRAY_SIZE(names)); i++)
2583  {
2584  memset(bufferA, '#', MAX_PATH - 1);
2585  bufferA[MAX_PATH - 1] = 0;
2586  lstrcpyA(bufferA, names[i]);
2587  MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2588 
2589  res2 = ExpandEnvironmentStringsA(names[i], expectedA, MAX_PATH);
2590  res = DoEnvironmentSubstA(bufferA, MAX_PATH);
2591 
2592  /* is the space for the terminating 0 included? */
2593  if (!i && HIWORD(res) && (LOWORD(res) == (lstrlenA(bufferA))))
2594  {
2595  win_skip("DoEnvironmentSubstA/W are broken on NT 4\n");
2596  return;
2597  }
2598  ok(HIWORD(res) && (LOWORD(res) == res2),
2599  "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2600  ok(!lstrcmpA(bufferA, expectedA),
2601  "%d: got %s (expected %s)\n", i, bufferA, expectedA);
2602 
2603  res2 = ExpandEnvironmentStringsW(bufferW, expectedW, MAX_PATH);
2604  res = DoEnvironmentSubstW(bufferW, MAX_PATH);
2605  ok(HIWORD(res) && (LOWORD(res) == res2),
2606  "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2607  ok(!lstrcmpW(bufferW, expectedW),
2608  "%d: got %s (expected %s)\n", i, wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2609  }
2610 
2611  i--; /* reuse data in the last table entry */
2612  len = LOWORD(res); /* needed length */
2613 
2614  /* one character extra is fine */
2615  memset(bufferA, '#', MAX_PATH - 1);
2616  bufferA[len + 2] = 0;
2617  lstrcpyA(bufferA, names[i]);
2618  MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2619 
2620  res2 = ExpandEnvironmentStringsA(bufferA, expectedA, MAX_PATH);
2621  res = DoEnvironmentSubstA(bufferA, len + 1);
2622  ok(HIWORD(res) && (LOWORD(res) == res2),
2623  "+1: got %d/%d (expected TRUE/%d)\n", HIWORD(res), LOWORD(res), res2);
2624  ok(!lstrcmpA(bufferA, expectedA),
2625  "+1: got %s (expected %s)\n", bufferA, expectedA);
2626 
2627  res2 = ExpandEnvironmentStringsW(bufferW, expectedW, MAX_PATH);
2628  res = DoEnvironmentSubstW(bufferW, len + 1);
2629  ok(HIWORD(res) && (LOWORD(res) == res2),
2630  "+1: got %d/%d (expected TRUE/%d)\n", HIWORD(res), LOWORD(res), res2);
2631  ok(!lstrcmpW(bufferW, expectedW),
2632  "+1: got %s (expected %s)\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2633 
2634 
2635  /* minimal buffer length (result string and terminating 0) */
2636  memset(bufferA, '#', MAX_PATH - 1);
2637  bufferA[len + 2] = 0;
2638  lstrcpyA(bufferA, names[i]);
2639  MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2640 
2641  /* ANSI version failed without an extra byte, as documented on msdn */
2642  res = DoEnvironmentSubstA(bufferA, len);
2643  ok(!HIWORD(res) && (LOWORD(res) == len),
2644  " 0: got %d/%d (expected FALSE/%d)\n", HIWORD(res), LOWORD(res), len);
2645  ok(!lstrcmpA(bufferA, names[i]),
2646  " 0: got %s (expected %s)\n", bufferA, names[i]);
2647 
2648  /* DoEnvironmentSubstW works as expected */
2649  res2 = ExpandEnvironmentStringsW(bufferW, expectedW, MAX_PATH);
2650  res = DoEnvironmentSubstW(bufferW, len);
2651  ok(HIWORD(res) && (LOWORD(res) == res2),
2652  " 0: got %d/%d (expected TRUE/%d)\n", HIWORD(res), LOWORD(res), res2);
2653  ok(!lstrcmpW(bufferW, expectedW),
2654  " 0: got %s (expected %s)\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2655 
2656 
2657  /* Buffer too small */
2658  /* result: FALSE / provided buffer length / the buffer is untouched */
2659  memset(bufferA, '#', MAX_PATH - 1);
2660  bufferA[len + 2] = 0;
2661  lstrcpyA(bufferA, names[i]);
2662  MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2663 
2664  res = DoEnvironmentSubstA(bufferA, len - 1);
2665  ok(!HIWORD(res) && (LOWORD(res) == (len - 1)),
2666  "-1: got %d/%d (expected FALSE/%d)\n", HIWORD(res), LOWORD(res), len - 1);
2667  ok(!lstrcmpA(bufferA, names[i]),
2668  "-1: got %s (expected %s)\n", bufferA, names[i]);
2669 
2670  lstrcpyW(expectedW, bufferW);
2671  res = DoEnvironmentSubstW(bufferW, len - 1);
2672  ok(!HIWORD(res) && (LOWORD(res) == (len - 1)),
2673  "-1: got %d/%d (expected FALSE/%d)\n", HIWORD(res), LOWORD(res), len - 1);
2674  ok(!lstrcmpW(bufferW, expectedW),
2675  "-1: got %s (expected %s)\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2676 
2677 
2678  /* unknown variable */
2679  /* result: TRUE / string length including terminating 0 / the buffer is untouched */
2680  memset(bufferA, '#', MAX_PATH - 1);
2681  bufferA[MAX_PATH - 1] = 0;
2682  lstrcpyA(bufferA, does_not_existA);
2683  MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2684 
2685  res2 = lstrlenA(does_not_existA) + 1;
2686  res = DoEnvironmentSubstA(bufferA, MAX_PATH);
2687  ok(HIWORD(res) && (LOWORD(res) == res2),
2688  "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2689  ok(!lstrcmpA(bufferA, does_not_existA),
2690  "%d: got %s (expected %s)\n", i, bufferA, does_not_existA);
2691 
2692  res = DoEnvironmentSubstW(bufferW, MAX_PATH);
2693  ok(HIWORD(res) && (LOWORD(res) == res2),
2694  "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2695  ok(!lstrcmpW(bufferW, does_not_existW),
2696  "%d: got %s (expected %s)\n", i, wine_dbgstr_w(bufferW), wine_dbgstr_w(does_not_existW));
2697 
2698 
2699  if (0)
2700  {
2701  /* NULL crashes on windows */
2704  }
2705 }
2706 
2708 {
2709  static const WCHAR shortW[] = {'f','i','l','e','.','t','s','t',0};
2710  static const WCHAR short2W[] = {'f','i','l','e',' ','(','2',')','.','t','s','t',0};
2711  static const WCHAR tmpW[] = {'t','m','p',0};
2712  static const WCHAR longW[] = {'n','a','m','e',0};
2713  static const WCHAR long2W[] = {'n','a','m','e',' ','(','2',')',0};
2714  WCHAR nameW[MAX_PATH], buffW[MAX_PATH], pathW[MAX_PATH];
2715  HANDLE file;
2716  BOOL ret;
2717 
2718  if (!pPathYetAnotherMakeUniqueName)
2719  {
2720  win_skip("PathYetAnotherMakeUniqueName() is not available.\n");
2721  return;
2722  }
2723 
2724 if (0)
2725 {
2726  /* crashes on Windows */
2727  ret = pPathYetAnotherMakeUniqueName(NULL, NULL, NULL, NULL);
2728  ok(!ret, "got %d\n", ret);
2729 
2730  ret = pPathYetAnotherMakeUniqueName(nameW, NULL, NULL, NULL);
2731  ok(!ret, "got %d\n", ret);
2732 }
2733 
2734  GetTempPathW(ARRAY_SIZE(pathW), pathW);
2735 
2736  /* Using short name only first */
2737  nameW[0] = 0;
2738  ret = pPathYetAnotherMakeUniqueName(nameW, pathW, shortW, NULL);
2739  ok(ret, "got %d\n", ret);
2740  lstrcpyW(buffW, pathW);
2741  lstrcatW(buffW, shortW);
2742  ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2743 
2744  /* now create a file with this name and get next name */
2746  ok(file != NULL, "got %p\n", file);
2747 
2748  nameW[0] = 0;
2749  ret = pPathYetAnotherMakeUniqueName(nameW, pathW, shortW, NULL);
2750  ok(ret, "got %d\n", ret);
2751  lstrcpyW(buffW, pathW);
2752  lstrcatW(buffW, short2W);
2753  ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2754 
2755  CloseHandle(file);
2756 
2757  /* Using short and long */
2758  nameW[0] = 0;
2759  ret = pPathYetAnotherMakeUniqueName(nameW, pathW, tmpW, longW);
2760  ok(ret, "got %d\n", ret);
2761  lstrcpyW(buffW, pathW);
2762  lstrcatW(buffW, longW);
2763  ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2764 
2766  ok(file != NULL, "got %p\n", file);
2767 
2768  nameW[0] = 0;
2769  ret = pPathYetAnotherMakeUniqueName(nameW, pathW, tmpW, longW);
2770  ok(ret, "got %d\n", ret);
2771  lstrcpyW(buffW, pathW);
2772  lstrcatW(buffW, long2W);
2773  ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2774 
2775  CloseHandle(file);
2776 
2777  /* Using long only */
2778  nameW[0] = 0;
2779  ret = pPathYetAnotherMakeUniqueName(nameW, pathW, NULL, longW);
2780  ok(ret, "got %d\n", ret);
2781  lstrcpyW(buffW, pathW);
2782  lstrcatW(buffW, longW);
2783  ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2784 }
2785 
2787 {
2788  PIDLIST_ABSOLUTE pidl;
2789  HRESULT hr;
2790 
2791  if (!pSHGetKnownFolderIDList)
2792  {
2793  win_skip("SHGetKnownFolderIDList is not available.\n");
2794  return;
2795  }
2796 
2797  hr = pSHGetKnownFolderIDList(NULL, 0, NULL, NULL);
2798  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2799 
2800 if (0) { /* crashes on native */
2801  pidl = (void*)0xdeadbeef;
2802  hr = pSHGetKnownFolderIDList(NULL, 0, NULL, &pidl);
2803 }
2804  /* not a known folder */
2805  pidl = (void*)0xdeadbeef;
2806  hr = pSHGetKnownFolderIDList(&IID_IUnknown, 0, NULL, &pidl);
2807  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
2808  ok(pidl == NULL, "got %p\n", pidl);
2809 
2810  hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, 0, NULL, NULL);
2811  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2812 
2813  pidl = (void*)0xdeadbeef;
2814  hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, 0, NULL, &pidl);
2815  ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2816  ok(ILIsEmpty(pidl), "pidl should be empty.\n");
2817  ok(pidl->mkid.cb == 0, "get wrong value: %d\n", pidl->mkid.cb);
2818  ILFree(pidl);
2819 
2820  pidl = (void*)0xdeadbeef;
2821  hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, KF_FLAG_NO_ALIAS, NULL, &pidl);
2822  ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2823  todo_wine ok(!ILIsEmpty(pidl), "pidl should not be empty.\n");
2824  todo_wine ok(pidl->mkid.cb == 20, "get wrong value: %d\n", pidl->mkid.cb);
2825  ILFree(pidl);
2826 
2827  pidl = (void*)0xdeadbeef;
2828  hr = pSHGetKnownFolderIDList(&FOLDERID_Documents, 0, NULL, &pidl);
2829  ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2830  ok(!ILIsEmpty(pidl), "pidl should not be empty.\n");
2831  ok(pidl->mkid.cb == 20, "get wrong value: %d\n", pidl->mkid.cb);
2832  ILFree(pidl);
2833 
2834  pidl = (void*)0xdeadbeef;
2835  hr = pSHGetKnownFolderIDList(&FOLDERID_Documents, KF_FLAG_NO_ALIAS, NULL, &pidl);
2836  ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2837  ok(!ILIsEmpty(pidl), "pidl should not be empty.\n");
2838  ok(pidl->mkid.cb == 20, "get wrong value: %d\n", pidl->mkid.cb);
2839  ILFree(pidl);
2840 }
2841 
2842 START_TEST(shellpath)
2843 {
2844  if (!init()) return;
2845 
2846  loadShell32();
2847  pGetSystemWow64DirectoryA = (void *)GetProcAddress( GetModuleHandleA("kernel32.dll"),
2848  "GetSystemWow64DirectoryA" );
2849  if (myARGC >= 3)
2850  doChild(myARGV[2]);
2851  else
2852  {
2853  /* Report missing functions once */
2854  if (!pSHGetFolderLocation)
2855  win_skip("SHGetFolderLocation is not available\n");
2856 
2857  /* first test various combinations of parameters: */
2858  test_parameters();
2859 
2860  /* check known values: */
2861  test_PidlTypes();
2862  test_GUIDs();
2863  test_EnvVars();
2864  testWinDir();
2865  testSystemDir();
2872  }
2873 }
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:1964
#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:2786
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:4041
#define CSIDL_COOKIES
Definition: shlobj.h:2035
#define trace(...)
Definition: kmt_test.h:217
#define PT_FOLDER
Definition: shellpath.c:63
static void doChild(const char *arg)
Definition: shellpath.c:1693
KF_DEFINITION_FLAGS kfdFlags
Definition: shobjidl.idl:3906
#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:398
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:422
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:2842
uint16_t * PWSTR
Definition: typedefs.h:54
#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:3346
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:1635
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:2988
char * LPSTR
Definition: xmlstorage.h:182
#define CSIDL_FONTS
Definition: shlobj.h:2022
#define lstrlenW
Definition: compat.h:407
#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:2069
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:2557
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:1934
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:207
#define CSIDL_CONNECTIONS
Definition: shlobj.h:2051
BOOL WINAPI SHGetSpecialFolderPathA(HWND hwndOwner, LPSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:2553
#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:2707
#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
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: CString.cpp:62
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:110
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
#define ok(value,...)
Definition: CComObject.cpp:34
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 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:2687
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:4772
#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:8
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:154
#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:819
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:3234
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:78
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define lstrcpyW
Definition: compat.h:406
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:2326
static char selfname[MAX_PATH]
Definition: shellpath.c:1683
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1991
#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
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
#define skip(...)
Definition: CString.cpp:57
Definition: services.c:325
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:4021
#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:400
#define CSIDL_NETHOOD
Definition: shlobj.h:2021
int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp)
Definition: shlfileop.cpp:999
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1897
#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:410
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:2598
SHITEMID mkid
Definition: shtypes.idl:34
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:319
#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:4831
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:141
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
#define LOWORD(l)
Definition: pedump.c:82
static HMODULE hShell32
Definition: string.c:34
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
#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: CString.cpp:56
Definition: path.c:42
#define printf
Definition: config.h:203
static void FreeKnownFolderDefinitionFields(KNOWNFOLDER_DEFINITION *pKFD)") cpp_quote("
Definition: shobjidl.idl:4025
#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