1 /* 2 * file type mapping 3 * (HKEY_CLASSES_ROOT - Stuff) 4 * 5 * Copyright 1998, 1999, 2000 Juergen Schmied 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include <wine/config.h> 23 24 #include <stdio.h> 25 26 #define WIN32_NO_STATUS 27 #define _INC_WINDOWS 28 #define COBJMACROS 29 30 #include <windef.h> 31 #include <winbase.h> 32 #include <shlobj.h> 33 #include <shlguid_undoc.h> 34 #include <shlwapi.h> 35 #include <wine/debug.h> 36 #include <wine/unicode.h> 37 #ifdef __REACTOS__ 38 #include <strsafe.h> 39 #endif 40 41 #include "pidl.h" 42 #include "shell32_main.h" 43 #include "shresdef.h" 44 45 WINE_DEFAULT_DEBUG_CHANNEL(shell); 46 47 #define MAX_EXTENSION_LENGTH 20 // FIXME: The limit is 254? 48 49 static LONG GetRegString(HKEY hKey, PCWSTR SubKey, PCWSTR Name, PWSTR Buffer, UINT cchBuf) 50 { 51 DWORD cb = sizeof(*Buffer) * cchBuf; 52 return RegGetValueW(hKey, SubKey, Name, RRF_RT_REG_SZ, NULL, Buffer, &cb); 53 } 54 55 HRESULT HCR_GetProgIdKeyOfExtension(PCWSTR szExtension, PHKEY phKey, BOOL AllowFallback) 56 { 57 LONG err; 58 WCHAR ext[max(1 + MAX_EXTENSION_LENGTH + 1, MAX_PATH)]; 59 WCHAR progid[MAX_PATH]; 60 if (szExtension[0] != '.') 61 { 62 ext[0] = '.'; 63 lstrcpynW(ext + 1, szExtension, _countof(ext) - 1); 64 szExtension = ext; 65 } 66 err = GetRegString(HKEY_CLASSES_ROOT, szExtension, NULL, progid, _countof(progid)); 67 if (!err && progid[0] != UNICODE_NULL) 68 { 69 err = RegOpenKeyExW(HKEY_CLASSES_ROOT, progid, 0, KEY_READ, phKey); 70 if (!err) 71 return err; /* A real ProgId key, return S_OK */ 72 } 73 if (AllowFallback) 74 { 75 err = RegOpenKeyExW(HKEY_CLASSES_ROOT, szExtension, 0, KEY_READ, phKey); 76 if (!err) 77 return S_FALSE; 78 } 79 return HRESULT_FROM_WIN32(err); 80 } 81 82 BOOL HCR_MapTypeToValueW(LPCWSTR szExtension, LPWSTR szFileType, LONG len, BOOL bPrependDot) 83 { 84 HKEY hkey; 85 WCHAR szTemp[MAX_EXTENSION_LENGTH + 2]; 86 87 TRACE("%s %p\n", debugstr_w(szExtension), szFileType); 88 89 /* added because we do not want to have double dots */ 90 if (szExtension[0] == '.') 91 bPrependDot = FALSE; 92 93 if (bPrependDot) 94 szTemp[0] = '.'; 95 96 lstrcpynW(szTemp + (bPrependDot?1:0), szExtension, MAX_EXTENSION_LENGTH); 97 98 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szTemp, 0, KEY_READ, &hkey)) 99 { 100 return FALSE; 101 } 102 103 if (RegQueryValueW(hkey, NULL, szFileType, &len)) 104 { 105 RegCloseKey(hkey); 106 return FALSE; 107 } 108 109 RegCloseKey(hkey); 110 111 TRACE("--UE;\n} %s\n", debugstr_w(szFileType)); 112 113 return TRUE; 114 } 115 116 BOOL HCR_MapTypeToValueA(LPCSTR szExtension, LPSTR szFileType, LONG len, BOOL bPrependDot) 117 { 118 HKEY hkey; 119 char szTemp[MAX_EXTENSION_LENGTH + 2]; 120 121 TRACE("%s %p\n", szExtension, szFileType); 122 123 /* added because we do not want to have double dots */ 124 if (szExtension[0] == '.') 125 bPrependDot = FALSE; 126 127 if (bPrependDot) 128 szTemp[0] = '.'; 129 130 lstrcpynA(szTemp + (bPrependDot?1:0), szExtension, MAX_EXTENSION_LENGTH); 131 132 if (RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_READ, &hkey)) 133 { 134 return FALSE; 135 } 136 137 if (RegQueryValueA(hkey, NULL, szFileType, &len)) 138 { 139 RegCloseKey(hkey); 140 return FALSE; 141 } 142 143 RegCloseKey(hkey); 144 145 TRACE("--UE;\n} %s\n", szFileType); 146 147 return TRUE; 148 } 149 150 EXTERN_C HRESULT SHELL32_EnumDefaultVerbList(LPCWSTR List, UINT Index, LPWSTR Verb, SIZE_T cchMax); 151 152 BOOL HCR_GetDefaultVerbW( HKEY hkeyClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len ) 153 { 154 WCHAR sTemp[MAX_PATH], verbs[MAX_PATH]; 155 LONG size; 156 HKEY hkey; 157 158 TRACE("%p %s %p\n", hkeyClass, debugstr_w(szVerb), szDest); 159 160 if (szVerb && *szVerb) 161 { 162 lstrcpynW(szDest, szVerb, len); 163 return TRUE; 164 } 165 166 /* MSDN says to first try the default verb */ 167 size = _countof(verbs); 168 if (!RegQueryValueW(hkeyClass, L"shell", verbs, &size) && *verbs) 169 { 170 for (UINT i = 0;; ++i) 171 { 172 if (FAILED(SHELL32_EnumDefaultVerbList(verbs, i, szDest, len))) 173 break; 174 if (FAILED(StringCchPrintfW(sTemp, _countof(sTemp), L"shell\\%s\\command", szDest))) 175 break; 176 if (!RegOpenKeyExW(hkeyClass, sTemp, 0, KEY_READ, &hkey)) 177 { 178 RegCloseKey(hkey); 179 TRACE("default verb=%s\n", debugstr_w(szDest)); 180 return TRUE; 181 } 182 } 183 } 184 *szDest = UNICODE_NULL; 185 186 /* then fallback to 'open' */ 187 lstrcpyW(sTemp, L"shell\\open\\command"); 188 if (!RegOpenKeyExW(hkeyClass, sTemp, 0, KEY_READ, &hkey)) 189 { 190 RegCloseKey(hkey); 191 lstrcpynW(szDest, L"open", len); 192 TRACE("default verb=open\n"); 193 return TRUE; 194 } 195 196 /* and then just use the first verb on Windows >= 2000 */ 197 #ifdef __REACTOS__ 198 if (!RegOpenKeyExW(hkeyClass, L"shell", 0, KEY_READ, &hkey)) 199 { 200 if (!RegEnumKeyW(hkey, 0, szDest, len) && *szDest) 201 { 202 TRACE("default verb=first verb=%s\n", debugstr_w(szDest)); 203 RegCloseKey(hkey); 204 return TRUE; 205 } 206 RegCloseKey(hkey); 207 } 208 #else 209 if (!RegEnumKeyW(hkeyClass, 0, szDest, len) && *szDest) 210 { 211 TRACE("default verb=first verb=%s\n", debugstr_w(szDest)); 212 return TRUE; 213 } 214 #endif 215 216 TRACE("no default verb!\n"); 217 return FALSE; 218 } 219 220 BOOL HCR_GetExecuteCommandW( HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len ) 221 { 222 WCHAR sTempVerb[MAX_PATH]; 223 BOOL ret; 224 225 TRACE("%p %s %s %p\n", hkeyClass, debugstr_w(szClass), debugstr_w(szVerb), szDest); 226 227 if (szClass) 228 RegOpenKeyExW(HKEY_CLASSES_ROOT, szClass, 0, KEY_READ, &hkeyClass); 229 if (!hkeyClass) 230 return FALSE; 231 ret = FALSE; 232 233 if (HCR_GetDefaultVerbW(hkeyClass, szVerb, sTempVerb, sizeof(sTempVerb)/sizeof(sTempVerb[0]))) 234 { 235 WCHAR sTemp[MAX_PATH]; 236 lstrcpyW(sTemp, L"shell\\"); 237 lstrcatW(sTemp, sTempVerb); 238 lstrcatW(sTemp, L"\\command"); 239 ret = (ERROR_SUCCESS == SHGetValueW(hkeyClass, sTemp, NULL, NULL, szDest, &len)); 240 } 241 if (szClass) 242 RegCloseKey(hkeyClass); 243 244 TRACE("-- %s\n", debugstr_w(szDest) ); 245 return ret; 246 } 247 248 /*************************************************************************************** 249 * HCR_GetDefaultIcon [internal] 250 * 251 * Gets the icon for a filetype 252 */ 253 BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey) 254 { 255 char xriid[50]; 256 sprintf( xriid, "CLSID\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", 257 riid->Data1, riid->Data2, riid->Data3, 258 riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], 259 riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] ); 260 261 TRACE("%s\n",xriid ); 262 263 return !RegOpenKeyExA(HKEY_CLASSES_ROOT, xriid, 0, KEY_READ, hkey); 264 } 265 266 static BOOL HCR_RegGetIconW(HKEY hkey, LPWSTR szDest, LPCWSTR szName, DWORD len, int* picon_idx) 267 { 268 DWORD dwType, size = len * sizeof(WCHAR); 269 WCHAR sTemp[MAX_PATH]; 270 WCHAR sNum[5]; 271 272 if (!RegQueryValueExW(hkey, szName, 0, &dwType, (LPBYTE)szDest, &size)) 273 { 274 if (dwType == REG_EXPAND_SZ) 275 { 276 ExpandEnvironmentStringsW(szDest, sTemp, MAX_PATH); 277 lstrcpynW(szDest, sTemp, len); 278 } 279 if (ParseFieldW (szDest, 2, sNum, _countof(sNum))) 280 *picon_idx = atoiW(sNum); 281 else 282 *picon_idx=0; /* sometimes the icon number is missing */ 283 ParseFieldW (szDest, 1, szDest, len); 284 PathUnquoteSpacesW(szDest); 285 return TRUE; 286 } 287 return FALSE; 288 } 289 290 static BOOL HCR_RegGetIconA(HKEY hkey, LPSTR szDest, LPCSTR szName, DWORD len, int* picon_idx) 291 { 292 DWORD dwType; 293 char sTemp[MAX_PATH]; 294 char sNum[5]; 295 296 if (!RegQueryValueExA(hkey, szName, 0, &dwType, (LPBYTE)szDest, &len)) 297 { 298 if (dwType == REG_EXPAND_SZ) 299 { 300 ExpandEnvironmentStringsA(szDest, sTemp, MAX_PATH); 301 lstrcpynA(szDest, sTemp, len); 302 } 303 if (ParseFieldA (szDest, 2, sNum, 5)) 304 *picon_idx=atoi(sNum); 305 else 306 *picon_idx=0; /* sometimes the icon number is missing */ 307 ParseFieldA (szDest, 1, szDest, len); 308 PathUnquoteSpacesA(szDest); 309 return TRUE; 310 } 311 return FALSE; 312 } 313 314 BOOL HCR_GetIconW(LPCWSTR szClass, LPWSTR szDest, LPCWSTR szName, DWORD len, int* picon_idx) 315 { 316 HKEY hkey; 317 WCHAR sTemp[MAX_PATH]; 318 BOOL ret = FALSE; 319 320 TRACE("%s\n",debugstr_w(szClass) ); 321 322 lstrcpynW(sTemp, szClass, MAX_PATH); 323 lstrcatW(sTemp, L"\\DefaultIcon"); 324 325 if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, sTemp, 0, KEY_READ, &hkey)) 326 { 327 ret = HCR_RegGetIconW(hkey, szDest, szName, len, picon_idx); 328 RegCloseKey(hkey); 329 } 330 331 if(ret) 332 TRACE("-- %s %i\n", debugstr_w(szDest), *picon_idx); 333 else 334 TRACE("-- not found\n"); 335 336 return ret; 337 } 338 339 BOOL HCR_GetIconA(LPCSTR szClass, LPSTR szDest, LPCSTR szName, DWORD len, int* picon_idx) 340 { 341 HKEY hkey; 342 char sTemp[MAX_PATH]; 343 BOOL ret = FALSE; 344 345 TRACE("%s\n",szClass ); 346 347 sprintf(sTemp, "%s\\DefaultIcon",szClass); 348 349 if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, sTemp, 0, KEY_READ, &hkey)) 350 { 351 ret = HCR_RegGetIconA(hkey, szDest, szName, len, picon_idx); 352 RegCloseKey(hkey); 353 } 354 355 if (ret) 356 TRACE("-- %s %i\n", szDest, *picon_idx); 357 else 358 TRACE("-- not found\n"); 359 360 return ret; 361 } 362 363 #ifdef __REACTOS__ 364 BOOL HCU_GetIconW(LPCWSTR szClass, LPWSTR szDest, LPCWSTR szName, DWORD len, int* picon_idx) 365 { 366 HKEY hkey; 367 WCHAR sTemp[MAX_PATH]; 368 BOOL ret = FALSE; 369 370 TRACE("%s\n", debugstr_w(szClass)); 371 372 StringCchPrintfW(sTemp, _countof(sTemp), L"%s\\DefaultIcon", szClass); 373 374 if (!RegOpenKeyExW(HKEY_CURRENT_USER, sTemp, 0, KEY_READ, &hkey)) 375 { 376 ret = HCR_RegGetIconW(hkey, szDest, szName, len, picon_idx); 377 RegCloseKey(hkey); 378 } 379 380 if (ret) 381 TRACE("-- %s %i\n", debugstr_w(szDest), *picon_idx); 382 else 383 TRACE("-- not found\n"); 384 385 return ret; 386 } 387 388 BOOL HLM_GetIconW(int reg_idx, LPWSTR szDest, DWORD len, int* picon_idx) 389 { 390 HKEY hkey; 391 WCHAR sTemp[5]; 392 BOOL ret = FALSE; 393 394 TRACE("%d\n", reg_idx); 395 396 StringCchPrintfW(sTemp, _countof(sTemp), L"%d", reg_idx); 397 398 if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE, 399 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons", 400 0, 401 KEY_READ, 402 &hkey)) 403 { 404 ret = HCR_RegGetIconW(hkey, szDest, sTemp, len, picon_idx); 405 RegCloseKey(hkey); 406 } 407 408 if (ret) 409 TRACE("-- %s %i\n", debugstr_w(szDest), *picon_idx); 410 else 411 TRACE("-- not found\n"); 412 413 return ret; 414 } 415 #endif 416 417 /*************************************************************************************** 418 * HCR_GetClassName [internal] 419 * 420 * Gets the name of a registered class 421 */ 422 BOOL HCR_GetClassNameW(REFIID riid, LPWSTR szDest, DWORD len) 423 { 424 HKEY hkey; 425 BOOL ret = FALSE; 426 DWORD buflen = len; 427 #ifdef __REACTOS__ 428 WCHAR szName[100]; 429 LPOLESTR pStr; 430 #endif 431 432 szDest[0] = 0; 433 434 #ifdef __REACTOS__ 435 if (StringFromCLSID(riid, &pStr) == S_OK) 436 { 437 DWORD dwLen = buflen * sizeof(WCHAR); 438 swprintf(szName, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", pStr); 439 if (!RegGetValueW(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, NULL, (PVOID)szDest, &dwLen)) 440 { 441 ret = TRUE; 442 } 443 CoTaskMemFree(pStr); 444 } 445 if (!ret && HCR_RegOpenClassIDKey(riid, &hkey)) 446 #else 447 if (HCR_RegOpenClassIDKey(riid, &hkey)) 448 #endif 449 { 450 if (!RegLoadMUIStringW(hkey, L"LocalizedString", szDest, len, NULL, 0, NULL) || 451 !RegQueryValueExW(hkey, L"", 0, NULL, (LPBYTE)szDest, &len)) 452 { 453 ret = TRUE; 454 } 455 RegCloseKey(hkey); 456 } 457 458 if (!ret || !szDest[0]) 459 { 460 if(IsEqualIID(riid, &CLSID_ShellDesktop)) 461 { 462 if (LoadStringW(shell32_hInstance, IDS_DESKTOP, szDest, buflen)) 463 ret = TRUE; 464 } 465 else if (IsEqualIID(riid, &CLSID_MyComputer)) 466 { 467 if(LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen)) 468 ret = TRUE; 469 } 470 #ifdef __REACTOS__ 471 else if (IsEqualIID(riid, &CLSID_MyDocuments)) 472 { 473 if(LoadStringW(shell32_hInstance, IDS_PERSONAL, szDest, buflen)) 474 ret = TRUE; 475 } 476 else if (IsEqualIID(riid, &CLSID_RecycleBin)) 477 { 478 if(LoadStringW(shell32_hInstance, IDS_RECYCLEBIN_FOLDER_NAME, szDest, buflen)) 479 ret = TRUE; 480 } 481 else if (IsEqualIID(riid, &CLSID_ControlPanel)) 482 { 483 if(LoadStringW(shell32_hInstance, IDS_CONTROLPANEL, szDest, buflen)) 484 ret = TRUE; 485 } 486 else if (IsEqualIID(riid, &CLSID_AdminFolderShortcut)) 487 { 488 if(LoadStringW(shell32_hInstance, IDS_ADMINISTRATIVETOOLS, szDest, buflen)) 489 ret = TRUE; 490 } 491 #endif 492 } 493 TRACE("-- %s\n", debugstr_w(szDest)); 494 return ret; 495 } 496 497 BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len) 498 { HKEY hkey; 499 BOOL ret = FALSE; 500 DWORD buflen = len; 501 #ifdef __REACTOS__ 502 CHAR szName[100]; 503 LPOLESTR pStr; 504 #endif 505 506 szDest[0] = 0; 507 508 #ifdef __REACTOS__ 509 if (StringFromCLSID(riid, &pStr) == S_OK) 510 { 511 DWORD dwLen = buflen * sizeof(CHAR); 512 sprintf(szName, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%S", pStr); 513 if (!RegGetValueA(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, NULL, (PVOID)szDest, &dwLen)) 514 { 515 ret = TRUE; 516 } 517 CoTaskMemFree(pStr); 518 } 519 if (!ret && HCR_RegOpenClassIDKey(riid, &hkey)) 520 #else 521 if (HCR_RegOpenClassIDKey(riid, &hkey)) 522 #endif 523 { 524 if (!RegLoadMUIStringA(hkey,"LocalizedString",szDest,len,NULL,0,NULL) || 525 !RegQueryValueExA(hkey,"",0,NULL,(LPBYTE)szDest,&len)) 526 { 527 ret = TRUE; 528 } 529 RegCloseKey(hkey); 530 } 531 532 if (!ret || !szDest[0]) 533 { 534 if(IsEqualIID(riid, &CLSID_ShellDesktop)) 535 { 536 if (LoadStringA(shell32_hInstance, IDS_DESKTOP, szDest, buflen)) 537 ret = TRUE; 538 } 539 else if (IsEqualIID(riid, &CLSID_MyComputer)) 540 { 541 if(LoadStringA(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen)) 542 ret = TRUE; 543 } 544 #ifdef __REACTOS__ 545 else if (IsEqualIID(riid, &CLSID_MyDocuments)) 546 { 547 if(LoadStringA(shell32_hInstance, IDS_PERSONAL, szDest, buflen)) 548 ret = TRUE; 549 } 550 else if (IsEqualIID(riid, &CLSID_RecycleBin)) 551 { 552 if(LoadStringA(shell32_hInstance, IDS_RECYCLEBIN_FOLDER_NAME, szDest, buflen)) 553 ret = TRUE; 554 } 555 else if (IsEqualIID(riid, &CLSID_ControlPanel)) 556 { 557 if(LoadStringA(shell32_hInstance, IDS_CONTROLPANEL, szDest, buflen)) 558 ret = TRUE; 559 } 560 else if (IsEqualIID(riid, &CLSID_AdminFolderShortcut)) 561 { 562 if(LoadStringA(shell32_hInstance, IDS_ADMINISTRATIVETOOLS, szDest, buflen)) 563 ret = TRUE; 564 } 565 #endif 566 } 567 568 TRACE("-- (%s)\n", szDest); 569 570 return ret; 571 } 572 573 /****************************************************************************** 574 * HCR_GetFolderAttributes [Internal] 575 * 576 * Query the registry for a shell folders' attributes 577 * 578 * PARAMS 579 * pidlFolder [I] A simple pidl of type PT_GUID. 580 * pdwAttributes [IO] In: Attributes to be queried, OUT: Resulting attributes. 581 * 582 * RETURNS 583 * TRUE: Found information for the attributes in the registry 584 * FALSE: No attribute information found 585 * 586 * NOTES 587 * If queried for an attribute, which is set in the CallForAttributes registry 588 * value, the function binds to the shellfolder objects and queries it. 589 */ 590 BOOL HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder, LPDWORD pdwAttributes) 591 { 592 HKEY hSFKey; 593 LPOLESTR pwszCLSID; 594 LONG lResult; 595 DWORD dwTemp, dwLen; 596 WCHAR wszShellFolderKey[] = L"CLSID\\{00021400-0000-0000-C000-000000000046}\\ShellFolder"; 597 598 TRACE("(pidlFolder=%p, pdwAttributes=%p)\n", pidlFolder, pdwAttributes); 599 600 if (!_ILIsPidlSimple(pidlFolder)) { 601 static BOOL firstHit = TRUE; 602 if (firstHit) { 603 ERR("should be called for simple PIDL's only!\n"); 604 firstHit = FALSE; 605 } 606 return FALSE; 607 } 608 609 if (!_ILIsDesktop(pidlFolder)) { 610 if (FAILED(StringFromCLSID(_ILGetGUIDPointer(pidlFolder), &pwszCLSID))) return FALSE; 611 memcpy(&wszShellFolderKey[6], pwszCLSID, 38 * sizeof(WCHAR)); 612 CoTaskMemFree(pwszCLSID); 613 } 614 615 lResult = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszShellFolderKey, 0, KEY_READ, &hSFKey); 616 #ifdef __REACTOS__ 617 if (lResult != ERROR_SUCCESS) 618 { 619 ERR("Cannot open key: %ls\n", wszShellFolderKey); 620 return FALSE; 621 } 622 #else 623 if (lResult != ERROR_SUCCESS) return FALSE; 624 #endif 625 626 dwLen = sizeof(DWORD); 627 lResult = RegQueryValueExW(hSFKey, L"CallForAttributes", 0, NULL, (LPBYTE)&dwTemp, &dwLen); 628 if ((lResult == ERROR_SUCCESS) && (dwTemp & *pdwAttributes)) { 629 LPSHELLFOLDER psfDesktop, psfFolder; 630 HRESULT hr; 631 632 RegCloseKey(hSFKey); 633 hr = SHGetDesktopFolder(&psfDesktop); 634 if (SUCCEEDED(hr)) { 635 hr = IShellFolder_BindToObject(psfDesktop, pidlFolder, NULL, &IID_IShellFolder, 636 (LPVOID*)&psfFolder); 637 if (SUCCEEDED(hr)) { 638 hr = IShellFolder_GetAttributesOf(psfFolder, 0, NULL, pdwAttributes); 639 IShellFolder_Release(psfFolder); 640 } 641 IShellFolder_Release(psfDesktop); 642 } 643 if (FAILED(hr)) return FALSE; 644 } else { 645 lResult = RegQueryValueExW(hSFKey, L"Attributes", 0, NULL, (LPBYTE)&dwTemp, &dwLen); 646 RegCloseKey(hSFKey); 647 if (lResult == ERROR_SUCCESS) { 648 *pdwAttributes &= dwTemp; 649 } else { 650 return FALSE; 651 } 652 } 653 654 TRACE("-- *pdwAttributes == 0x%08x\n", *pdwAttributes); 655 656 return TRUE; 657 } 658