HRESULT SHELL32_GetGuidItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes) { if (!_ILIsSpecialFolder(pidl)) { ERR("Got wrong type of pidl!\n"); *pdwAttributes &= SFGAO_CANLINK; return S_OK; } if (*pdwAttributes & ~dwSupportedAttr) { WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes & ~dwSupportedAttr)); *pdwAttributes &= dwSupportedAttr; } /* First try to get them from the registry */ if (HCR_GetFolderAttributes(pidl, pdwAttributes) && *pdwAttributes) { return S_OK; } else { /* If we can't get it from the registry we have to query the child */ CComPtr<IShellFolder> psf2; if (SUCCEEDED(psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &psf2)))) { return psf2->GetAttributesOf(0, NULL, pdwAttributes); } } *pdwAttributes &= SFGAO_CANLINK; return S_OK; }
HRESULT CRegFolder::GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes) { DWORD dwAttributes = *pdwAttributes; /* First try to get them from the registry */ if (!HCR_GetFolderAttributes(pidl, pdwAttributes)) { /* We couldn't get anything */ *pdwAttributes = 0; } /* Items have more attributes when on desktop */ if (_ILIsDesktop(m_pidlRoot)) { *pdwAttributes |= (dwAttributes & (SFGAO_CANLINK|SFGAO_CANDELETE|SFGAO_CANRENAME|SFGAO_HASPROPSHEET)); } /* In any case, links can be created */ if (*pdwAttributes == NULL) { *pdwAttributes |= (dwAttributes & SFGAO_CANLINK); } return S_OK; }
/*********************************************************************** * SHELL32_GetItemAttributes * * NOTES * Observed values: * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER * file: 0x40000177 FILESYSTEM * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR * (seems to be default for shell extensions if no registry entry exists) * * win2k: * folder: 0xF0400177 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER * file: 0x40400177 FILESYSTEM | CANMONIKER * drive 0xF0400154 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER | CANRENAME (LABEL) * * According to the MSDN documentation this function should not set flags. It claims only to reset flags when necessary. * However it turns out the native shell32.dll _sets_ flags in several cases - so do we. */ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes) { DWORD dwAttributes; BOOL has_guid; static const DWORD dwSupportedAttr= SFGAO_CANCOPY | /*0x00000001 */ SFGAO_CANMOVE | /*0x00000002 */ SFGAO_CANLINK | /*0x00000004 */ SFGAO_CANRENAME | /*0x00000010 */ SFGAO_CANDELETE | /*0x00000020 */ SFGAO_HASPROPSHEET | /*0x00000040 */ SFGAO_DROPTARGET | /*0x00000100 */ SFGAO_LINK | /*0x00010000 */ SFGAO_READONLY | /*0x00040000 */ SFGAO_HIDDEN | /*0x00080000 */ SFGAO_FILESYSANCESTOR | /*0x10000000 */ SFGAO_FOLDER | /*0x20000000 */ SFGAO_FILESYSTEM | /*0x40000000 */ SFGAO_HASSUBFOLDER; /*0x80000000 */ TRACE ("0x%08x\n", *pdwAttributes); if (*pdwAttributes & ~dwSupportedAttr) { WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes & ~dwSupportedAttr)); *pdwAttributes &= dwSupportedAttr; } has_guid = _ILGetGUIDPointer(pidl) != NULL; dwAttributes = *pdwAttributes; if (_ILIsDrive (pidl)) { *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR| SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK; } else if (has_guid && HCR_GetFolderAttributes(pidl, &dwAttributes)) { *pdwAttributes = dwAttributes; } else if (_ILGetDataPointer (pidl)) { dwAttributes = _ILGetFileAttributes (pidl, NULL, 0); if (!dwAttributes && has_guid) { WCHAR path[MAX_PATH]; STRRET strret; /* File attributes are not present in the internal PIDL structure, so get them from the file system. */ HRESULT hr = IShellFolder_GetDisplayNameOf(psf, pidl, SHGDN_FORPARSING, &strret); if (SUCCEEDED(hr)) { hr = StrRetToBufW(&strret, pidl, path, MAX_PATH); /* call GetFileAttributes() only for file system paths, not for parsing names like "::{...}" */ if (SUCCEEDED(hr) && path[0]!=':') dwAttributes = GetFileAttributesW(path); } } /* Set common attributes */ *pdwAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANCOPY; if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) *pdwAttributes |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); else *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); if (dwAttributes & FILE_ATTRIBUTE_HIDDEN) *pdwAttributes |= SFGAO_HIDDEN; else *pdwAttributes &= ~SFGAO_HIDDEN; if (dwAttributes & FILE_ATTRIBUTE_READONLY) *pdwAttributes |= SFGAO_READONLY; else *pdwAttributes &= ~SFGAO_READONLY; if (SFGAO_LINK & *pdwAttributes) { char ext[MAX_PATH]; if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk")) *pdwAttributes &= ~SFGAO_LINK; } } else { *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK; } TRACE ("-- 0x%08x\n", *pdwAttributes); return S_OK; }