Support for shellfolder's CallForAttributes registry value.
diff --git a/dlls/shell32/classes.c b/dlls/shell32/classes.c
index 5ecd5d4..334b2ac 100644
--- a/dlls/shell32/classes.c
+++ b/dlls/shell32/classes.c
@@ -26,6 +26,9 @@
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
+
+#define COBJMACROS
+
#include "wine/debug.h"
#include "winerror.h"
#include "windef.h"
@@ -39,6 +42,7 @@
#include "shlguid.h"
#include "shresdef.h"
#include "shlwapi.h"
+#include "pidl.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
@@ -341,47 +345,81 @@
return ret;
}
-/***************************************************************************************
-* HCR_GetFolderAttributes [internal]
-*
-* gets the folder attributes of a class
-*
-* FIXME
-* verify the defaultvalue for *szDest
-*/
-BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest)
-{ HKEY hkey;
- char xriid[60];
- DWORD attributes;
- DWORD len = 4;
+/******************************************************************************
+ * HCR_GetFolderAttributes [Internal]
+ *
+ * Query the registry for a shell folders' attributes
+ *
+ * PARAMS
+ * pidlFolder [I] A simple pidl of type PT_GUID.
+ * pdwAttributes [IO] In: Attributes to be queried, OUT: Resulting attributes.
+ *
+ * RETURNS
+ * TRUE: Found information for the attributes in the registry
+ * FALSE: No attribute information found
+ *
+ * NOTES
+ * If queried for an attribute, which is set in the CallForAttributes registry
+ * value, the function binds to the shellfolder objects and queries it.
+ */
+BOOL HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder, LPDWORD pdwAttributes)
+{
+ HKEY hSFKey;
+ LPOLESTR pwszCLSID;
+ LONG lResult;
+ DWORD dwTemp, dwLen;
+ static const WCHAR wszAttributes[] = { 'A','t','t','r','i','b','u','t','e','s',0 };
+ static const WCHAR wszCallForAttributes[] = {
+ 'C','a','l','l','F','o','r','A','t','t','r','i','b','u','t','e','s',0 };
+ WCHAR wszShellFolderKey[] = { 'C','L','S','I','D','\\','{','0','0','0','2','1','4','0','0','-',
+ '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0','0',
+ '0','0','0','4','6','}','\\','S','h','e','l','l','F','o','l','d','e','r',0 };
- sprintf( xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
- riid->Data1, riid->Data2, riid->Data3,
- riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
- riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
- TRACE("%s\n",xriid );
+ TRACE("(pidlFolder=%p, pdwAttributes=%p)\n", pidlFolder, pdwAttributes);
+
+ if (!_ILIsPidlSimple(pidlFolder)) {
+ ERR("HCR_GetFolderAttributes should be called for simple PIDL's only!\n");
+ return FALSE;
+ }
+
+ if (!_ILIsDesktop(pidlFolder)) {
+ if (FAILED(StringFromCLSID(_ILGetGUIDPointer(pidlFolder), &pwszCLSID))) return FALSE;
+ memcpy(&wszShellFolderKey[6], pwszCLSID, 38 * sizeof(WCHAR));
+ CoTaskMemFree(pwszCLSID);
+ }
+
+ lResult = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszShellFolderKey, 0, KEY_READ, &hSFKey);
+ if (lResult != ERROR_SUCCESS) return FALSE;
+
+ dwLen = sizeof(DWORD);
+ lResult = RegQueryValueExW(hSFKey, wszCallForAttributes, 0, NULL, (LPBYTE)&dwTemp, &dwLen);
+ if ((lResult == ERROR_SUCCESS) && (dwTemp & *pdwAttributes)) {
+ LPSHELLFOLDER psfDesktop, psfFolder;
+ HRESULT hr;
- if (!szDest) return FALSE;
- *szDest = SFGAO_FOLDER|SFGAO_FILESYSTEM;
+ RegCloseKey(hSFKey);
+ hr = SHGetDesktopFolder(&psfDesktop);
+ if (SUCCEEDED(hr)) {
+ hr = IShellFolder_BindToObject(psfDesktop, pidlFolder, NULL, &IID_IShellFolder,
+ (LPVOID*)&psfFolder);
+ if (SUCCEEDED(hr)) {
+ hr = IShellFolder_GetAttributesOf(psfFolder, 0, NULL, pdwAttributes);
+ }
+ }
+ IShellFolder_Release(psfFolder);
+ IShellFolder_Release(psfDesktop);
+ if (FAILED(hr)) return FALSE;
+ } else {
+ lResult = RegQueryValueExW(hSFKey, wszAttributes, 0, NULL, (LPBYTE)&dwTemp, &dwLen);
+ RegCloseKey(hSFKey);
+ if (lResult == ERROR_SUCCESS) {
+ *pdwAttributes &= dwTemp;
+ } else {
+ return FALSE;
+ }
+ }
- strcat (xriid, "\\ShellFolder");
+ TRACE("-- *pdwAttributes == 0x%08lx\n", *pdwAttributes);
- if (RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey))
- {
- return FALSE;
- }
-
- if (RegQueryValueExA(hkey,"Attributes",0,NULL,(LPBYTE)&attributes,&len))
- {
- RegCloseKey(hkey);
- return FALSE;
- }
-
- RegCloseKey(hkey);
-
- TRACE("-- 0x%08lx\n", attributes);
-
- *szDest = attributes;
-
- return TRUE;
+ return TRUE;
}