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
GetRegString(HKEY hKey,PCWSTR SubKey,PCWSTR Name,PWSTR Buffer,UINT cchBuf)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
HCR_GetProgIdKeyOfExtension(PCWSTR szExtension,PHKEY phKey,BOOL AllowFallback)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
HCR_MapTypeToValueW(LPCWSTR szExtension,LPWSTR szFileType,LONG len,BOOL bPrependDot)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
HCR_MapTypeToValueA(LPCSTR szExtension,LPSTR szFileType,LONG len,BOOL bPrependDot)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
HCR_GetDefaultVerbW(HKEY hkeyClass,LPCWSTR szVerb,LPWSTR szDest,DWORD len)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
HCR_GetExecuteCommandW(HKEY hkeyClass,LPCWSTR szClass,LPCWSTR szVerb,LPWSTR szDest,DWORD len)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 */
HCR_RegOpenClassIDKey(REFIID riid,HKEY * hkey)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
HCR_RegGetIconW(HKEY hkey,LPWSTR szDest,LPCWSTR szName,DWORD len,int * picon_idx)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
HCR_RegGetIconA(HKEY hkey,LPSTR szDest,LPCSTR szName,DWORD len,int * picon_idx)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
HCR_GetIconW(LPCWSTR szClass,LPWSTR szDest,LPCWSTR szName,DWORD len,int * picon_idx)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
HCR_GetIconA(LPCSTR szClass,LPSTR szDest,LPCSTR szName,DWORD len,int * picon_idx)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__
HCU_GetIconW(LPCWSTR szClass,LPWSTR szDest,LPCWSTR szName,DWORD len,int * picon_idx)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
HLM_GetIconW(int reg_idx,LPWSTR szDest,DWORD len,int * picon_idx)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 */
HCR_GetClassNameW(REFIID riid,LPWSTR szDest,DWORD len)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
HCR_GetClassNameA(REFIID riid,LPSTR szDest,DWORD len)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 */
HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder,LPDWORD pdwAttributes)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