Use the CallForAttributes registry value, instead of promoting the
root folder's SFGAO_FILESYSTEM flag to the registry.
This commit is contained in:
parent
11cadc368a
commit
526377c511
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -869,15 +869,30 @@ 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);
|
||||
TRACE("(iface=%p, cidl=%u, apidl=%p, rgfInOut=%p)\n", iface, cidl, apidl, rgfInOut);
|
||||
|
||||
for (i=0; i<cidl; i++)
|
||||
flags &= LPSTATSTRUCT_FROM_LPSHITEMID(apidl[i])->sfAttr;
|
||||
if (!rgfInOut || (cidl && !apidl))
|
||||
return E_INVALIDARG;
|
||||
|
||||
*rgfInOut = *rgfInOut & flags;
|
||||
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; i<cidl; i++) {
|
||||
pStatStruct = LPSTATSTRUCT_FROM_LPSHITEMID(apidl[i]);
|
||||
if (!pStatStruct) return E_INVALIDARG;
|
||||
*rgfInOut &= pStatStruct->sfAttr;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -1147,32 +1162,11 @@ 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;
|
||||
|
|
Loading…
Reference in New Issue