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