From 526377c5119edc8db1eeb6d7379ac9c97361eabd Mon Sep 17 00:00:00 2001 From: Michael Jung Date: Sat, 25 Jun 2005 17:56:13 +0000 Subject: [PATCH] Use the CallForAttributes registry value, instead of promoting the root folder's SFGAO_FILESYSTEM flag to the registry. --- dlls/shell32/regsvr.c | 28 +++++++++++++---- dlls/shell32/shfldr_unixfs.c | 58 ++++++++++++++++-------------------- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/dlls/shell32/regsvr.c b/dlls/shell32/regsvr.c index 1abcbf6e35c..755aa5c2dac 100644 --- a/dlls/shell32/regsvr.c +++ b/dlls/shell32/regsvr.c @@ -64,13 +64,17 @@ struct regsvr_coclass LPCSTR ips32; /* can be NULL to omit */ LPCSTR ips32_tmodel; /* can be NULL to omit */ DWORD flags; + DWORD dwAttributes; + DWORD dwCallForAttributes; LPCSTR clsid_str; /* can be NULL to omit */ LPCSTR progid; /* can be NULL to omit */ }; /* flags for regsvr_coclass.flags */ -#define SHELLEX_MAYCHANGEDEFAULTMENU 0x00000001 -#define SHELLFOLDER_WANTSFORPARSING 0x00000002 +#define SHELLEX_MAYCHANGEDEFAULTMENU 0x00000001 +#define SHELLFOLDER_WANTSFORPARSING 0x00000002 +#define SHELLFOLDER_ATTRIBUTES 0x00000004 +#define SHELLFOLDER_CALLFORATTRIBUTES 0x00000008 static HRESULT register_coclasses(struct regsvr_coclass const *list); static HRESULT unregister_coclasses(struct regsvr_coclass const *list); @@ -110,6 +114,8 @@ static WCHAR const mcdm_keyname[21] = { 'a', 'u', 'l', 't', 'M', 'e', 'n', 'u', 0 }; static char const tmodel_valuename[] = "ThreadingModel"; static char const wfparsing_valuename[] = "WantsFORPARSING"; +static char const attributes_valuename[] = "Attributes"; +static char const cfattributes_valuename[] = "CallForAttributes"; /*********************************************************************** * static helper functions @@ -285,15 +291,23 @@ static HRESULT register_coclasses(struct regsvr_coclass const *list) RegCloseKey(mcdm_key); } - if (list->flags & SHELLFOLDER_WANTSFORPARSING) { + if (list->flags & + (SHELLFOLDER_WANTSFORPARSING|SHELLFOLDER_ATTRIBUTES|SHELLFOLDER_CALLFORATTRIBUTES)) + { HKEY shellfolder_key; res = RegCreateKeyExW(clsid_key, shellfolder_keyname, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &shellfolder_key, NULL); if (res != ERROR_SUCCESS) goto error_close_clsid_key; - res = RegSetValueExA(shellfolder_key, wfparsing_valuename, 0, REG_SZ, - "", 1); + if (list->flags & SHELLFOLDER_WANTSFORPARSING) + res = RegSetValueExA(shellfolder_key, wfparsing_valuename, 0, REG_SZ, "", 1); + if (list->flags & SHELLFOLDER_ATTRIBUTES) + res = RegSetValueExA(shellfolder_key, attributes_valuename, 0, REG_DWORD, + (LPBYTE)&list->dwAttributes, sizeof(DWORD)); + if (list->flags & SHELLFOLDER_CALLFORATTRIBUTES) + res = RegSetValueExA(shellfolder_key, cfattributes_valuename, 0, REG_DWORD, + (LPBYTE)&list->dwCallForAttributes, sizeof(DWORD)); RegCloseKey(shellfolder_key); if (res != ERROR_SUCCESS) goto error_close_clsid_key; } @@ -531,7 +545,9 @@ static struct regsvr_coclass const coclass_list[] = { NULL, "shell32.dll", "Apartment", - SHELLFOLDER_WANTSFORPARSING + SHELLFOLDER_WANTSFORPARSING|SHELLFOLDER_ATTRIBUTES|SHELLFOLDER_CALLFORATTRIBUTES, + SFGAO_FILESYSANCESTOR|SFGAO_FOLDER|SFGAO_HASSUBFOLDER, + SFGAO_FILESYSTEM }, { NULL } /* list terminator */ }; diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c index 78c3f88414f..43b133d9c32 100644 --- a/dlls/shell32/shfldr_unixfs.c +++ b/dlls/shell32/shfldr_unixfs.c @@ -869,16 +869,31 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_CreateViewObject(IShellFolder2* i static HRESULT WINAPI UnixFolder_IShellFolder2_GetAttributesOf(IShellFolder2* iface, UINT cidl, LPCITEMIDLIST* apidl, SFGAOF* rgfInOut) { - UINT i; - SFGAOF flags= ~(SFGAOF)0; + UnixFolder *This = ADJUST_THIS(UnixFolder, IShellFolder2, iface); + const StatStruct *pStatStruct; - TRACE("(iface=%p, cidl=%u, apidl=%p, rgfInOut=%p) semi-stub\n", iface, cidl, apidl, rgfInOut); - - for (i=0; isfAttr; + TRACE("(iface=%p, cidl=%u, apidl=%p, rgfInOut=%p)\n", iface, cidl, apidl, rgfInOut); + + if (!rgfInOut || (cidl && !apidl)) + return E_INVALIDARG; + + if (cidl == 0) { + if (!strcmp(This->m_pszPath, "/")) { + *rgfInOut &= dwRootAttr; + } else { + pStatStruct = LPSTATSTRUCT_FROM_LPSHITEMID(ILFindLastID(This->m_pidlLocation)); + if (!pStatStruct) return E_FAIL; + *rgfInOut &= pStatStruct->sfAttr; + } + } else { + UINT i; + for (i=0; isfAttr; + } + } - *rgfInOut = *rgfInOut & flags; - return S_OK; } @@ -1146,33 +1161,12 @@ static HRESULT WINAPI UnixFolder_IPersistFolder2_Initialize(IPersistFolder2* ifa if (!UNIXFS_pidl_to_path(pidl, This)) return E_FAIL; - - /* Attributes of a shell namespace extension's root folder (in this case the '/' folder) - * are not queried for with ShellFolder's GetAttributesOf, but looked up in the registry - * (see MSDN: Creating a Shell Namespace Extension > Implementing the Basic Folder Object - * Interface > Registering an Extension). When they change, we have to write them there. - */ + if (!strcmp(This->m_pszPath, "/")) { - DWORD dwTempAttr = SFGAO_FOLDER|SFGAO_HASSUBFOLDER|SFGAO_FILESYSANCESTOR; struct stat statRoot; - if (stat(This->m_pszPath, &statRoot)) return E_FAIL; - if (UNIXFS_is_dos_device(&statRoot)) dwTempAttr |= SFGAO_FILESYSTEM; - - if (dwRootAttr != dwTempAttr) { - HKEY hKey; - static const WCHAR wszFolderAttrValue[] = { 'A','t','t','r','i','b','u','t','e','s',0 }; - static const WCHAR wszFolderAttrKey[] = { 'C','L','S','I','D','\\', - '{','9','D','2','0','A','A','E','8','-','0','6','2','5','-','4','4','B','0','-', - '9','C','A','7','-','7','1','8','8','9','C','2','2','5','4','D','9','}','\\', - 'S','h','e','l','l','F','o','l','d','e','r',0 }; - - dwRootAttr = dwTempAttr; - if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszFolderAttrKey, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS) { - RegSetValueExW(hKey, wszFolderAttrValue, 0, REG_DWORD, (BYTE*)&dwTempAttr, sizeof(DWORD)); - RegCloseKey(hKey); - } - } + dwRootAttr = SFGAO_FOLDER|SFGAO_HASSUBFOLDER|SFGAO_FILESYSANCESTOR; + if (UNIXFS_is_dos_device(&statRoot)) dwRootAttr |= SFGAO_FILESYSTEM; } return S_OK;