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