📄 shellfs.cpp
字号:
Entry* entry = NULL; // eliminate useless GCC warning by initializing entry
LPTSTR p = buffer + _tcslen(buffer);
lstrcpy(p, TEXT("\\*"));
WIN32_FIND_DATA w32fd;
HANDLE hFind = FindFirstFile(buffer, &w32fd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
// ignore hidden files (usefull in the start menu)
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
continue;
// ignore directory entries "." and ".."
if ((w32fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) &&
w32fd.cFileName[0]==TEXT('.') &&
(w32fd.cFileName[1]==TEXT('\0') ||
(w32fd.cFileName[1]==TEXT('.') && w32fd.cFileName[2]==TEXT('\0'))))
continue;
lstrcpy(p+1, w32fd.cFileName);
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
entry = new WinDirectory(this, buffer);
else
entry = new WinEntry(this);
if (!first_entry)
first_entry = entry;
if (last)
last->_next = entry;
memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA));
entry->_level = level;
if (!(scan_flags & SCAN_DONT_ACCESS)) {
HANDLE hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if (hFile != INVALID_HANDLE_VALUE) {
if (GetFileInformationByHandle(hFile, &entry->_bhfi))
entry->_bhfi_valid = true;
if (ScanNTFSStreams(entry, hFile))
entry->_scanned = true; // There exist named NTFS sub-streams in this file.
CloseHandle(hFile);
}
}
// set file type name
LPCTSTR ext = g_Globals._ftype_mgr.set_type(entry);
DWORD attribs = SFGAO_FILESYSTEM;
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
attribs |= SFGAO_FOLDER|SFGAO_HASSUBFOLDER;
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
attribs |= SFGAO_READONLY;
//if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
// attribs |= SFGAO_HIDDEN;
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)
attribs |= SFGAO_COMPRESSED;
if (ext && !_tcsicmp(ext, _T(".lnk"))) {
attribs |= SFGAO_LINK;
w32fd.dwFileAttributes |= ATTRIBUTE_SYMBOLIC_LINK;
}
entry->_shell_attribs = attribs;
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
entry->_icon_id = ICID_FOLDER;
else if (!(scan_flags & SCAN_DONT_EXTRACT_ICONS))
entry->_icon_id = entry->safe_extract_icon(); // Assume small icon, we can extract the large icon later on demand.
last = entry;
} while(FindNextFile(hFind, &w32fd));
FindClose(hFind);
}
}
else // SCAN_NO_FILESYSTEM
#endif
{
ShellItemEnumerator enumerator(_folder, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE);
TCHAR name[MAX_PATH];
TCHAR path[MAX_PATH];
HRESULT hr_next = S_OK;
do {
#define FETCH_ITEM_COUNT 32
LPITEMIDLIST pidls[FETCH_ITEM_COUNT];
ULONG cnt = 0;
memset(pidls, 0, sizeof(pidls));
hr_next = enumerator->Next(FETCH_ITEM_COUNT, pidls, &cnt);
/* don't break yet now: Registry Explorer Plugin returns E_FAIL!
if (!SUCCEEDED(hr_next))
break; */
if (hr_next == S_FALSE)
break;
for(ULONG n=0; n<cnt; ++n) {
WIN32_FIND_DATA w32fd;
BY_HANDLE_FILE_INFORMATION bhfi;
bool bhfi_valid = false;
memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));
SFGAOF attribs_before = ~SFGAO_READONLY & ~SFGAO_VALIDATE;
SFGAOF attribs = attribs_before;
HRESULT hr = _folder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidls[n], &attribs);
bool removeable = false;
if (SUCCEEDED(hr) && attribs!=attribs_before) {
// avoid accessing floppy drives when browsing "My Computer"
if (attribs & SFGAO_REMOVABLE) {
attribs |= SFGAO_HASSUBFOLDER;
removeable = true;
} else if (!(scan_flags & SCAN_DONT_ACCESS)) {
SFGAOF attribs2 = SFGAO_READONLY;
HRESULT hr = _folder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidls[n], &attribs2);
if (SUCCEEDED(hr))
attribs |= attribs2;
}
} else
attribs = 0;
bhfi_valid = fill_w32fdata_shell(pidls[n], attribs, &w32fd, &bhfi,
!(scan_flags&SCAN_DONT_ACCESS) && !removeable);
try {
Entry* entry = NULL; // eliminate useless GCC warning by initializing entry
if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
entry = new ShellDirectory(this, pidls[n], _hwnd);
else
entry = new ShellEntry(this, pidls[n]);
if (!first_entry)
first_entry = entry;
if (last)
last->_next = entry;
memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA));
if (bhfi_valid)
memcpy(&entry->_bhfi, &bhfi, sizeof(BY_HANDLE_FILE_INFORMATION));
// store path in entry->_data.cFileName in case fill_w32fdata_shell() didn't already fill it
if (!entry->_data.cFileName[0])
if (SUCCEEDED(path_from_pidl(_folder, pidls[n], path, COUNTOF(path))))
_tcscpy(entry->_data.cFileName, path);
if (SUCCEEDED(name_from_pidl(_folder, pidls[n], name, COUNTOF(name), SHGDN_INFOLDER|0x2000/*0x2000=SHGDN_INCLUDE_NONFILESYS*/))) {
if (!entry->_data.cFileName[0])
_tcscpy(entry->_data.cFileName, name);
else if (_tcscmp(entry->_display_name, name))
entry->_display_name = _tcsdup(name); // store display name separate from file name; sort display by file name
}
if (attribs & SFGAO_LINK)
w32fd.dwFileAttributes |= ATTRIBUTE_SYMBOLIC_LINK;
entry->_level = level;
entry->_shell_attribs = attribs;
entry->_bhfi_valid = bhfi_valid;
// set file type name
g_Globals._ftype_mgr.set_type(entry);
// get icons for files and virtual objects
if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
!(attribs & SFGAO_FILESYSTEM)) {
if (!(scan_flags & SCAN_DONT_EXTRACT_ICONS))
entry->_icon_id = entry->safe_extract_icon(); // Assume small icon, we can extract the large icon later on demand.
} else if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
entry->_icon_id = ICID_FOLDER;
else
entry->_icon_id = ICID_NONE; // don't try again later
last = entry;
} catch(COMException& e) {
HandleException(e, _hwnd);
}
}
} while(SUCCEEDED(hr_next));
}
if (last)
last->_next = NULL;
_down = first_entry;
_scanned = true;
}
const void* ShellDirectory::get_next_path_component(const void* p) const
{
LPITEMIDLIST pidl = (LPITEMIDLIST)p;
if (!pidl || !pidl->mkid.cb)
return NULL;
// go to next element
pidl = (LPITEMIDLIST)((LPBYTE)pidl+pidl->mkid.cb);
return pidl;
}
Entry* ShellDirectory::find_entry(const void* p)
{
LPITEMIDLIST pidl = (LPITEMIDLIST) p;
// handle special case of empty trailing id list entry
if (!pidl->mkid.cb)
return this;
for(Entry*entry=_down; entry; entry=entry->_next)
if (entry->_etype == ET_SHELL) {
ShellEntry* se = static_cast<ShellEntry*>(entry);
if (se->_pidl && se->_pidl->mkid.cb==pidl->mkid.cb && !memcmp(se->_pidl, pidl, se->_pidl->mkid.cb))
return entry;
} else {
const ShellPath& sp = entry->create_absolute_pidl();
static DynamicFct<LPITEMIDLIST(WINAPI*)(LPCITEMIDLIST)> ILFindLastID(TEXT("SHELL32"), "ILFindLastID");
if (ILFindLastID) {
LPCITEMIDLIST entry_pidl = (*ILFindLastID)(sp);
if (entry_pidl && entry_pidl->mkid.cb==pidl->mkid.cb && !memcmp(entry_pidl, pidl, entry_pidl->mkid.cb))
return entry;
}
}
return NULL;
}
int ShellDirectory::extract_icons(ICONCACHE_FLAGS flags)
{
int cnt = 0;
for(Entry*entry=_down; entry; entry=entry->_next)
if (entry->_icon_id == ICID_UNKNOWN) {
entry->_icon_id = entry->extract_icon(flags);
if (entry->_icon_id != ICID_NONE)
++cnt;
}
return cnt;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -