xref: /reactos/dll/win32/shell32/wine/classes.c (revision f6a25d48)
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