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