void ShellDirectory::read_directory(int scan_flags) { CONTEXT("ShellDirectory::read_directory()"); int level = _level + 1; ShellEntry* first_entry = NULL; ShellEntry* last = NULL; /*if (_folder.empty()) return;*/ ShellItemEnumerator enumerator(_folder, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE); TCHAR name[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; 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)) { DWORD attribs2 = SFGAO_READONLY; HRESULT hr = _folder->GetAttributesOf(1, (LPCITEMIDLIST*)&pidls[n], &attribs2); if (SUCCEEDED(hr)) attribs |= attribs2; } } else attribs = 0; fill_w32fdata_shell(pidls[n], attribs, &w32fd, !(scan_flags&SCAN_DONT_ACCESS)&&!removeable); try { ShellEntry* 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 (SUCCEEDED(name_from_pidl(_folder, pidls[n], name, MAX_PATH, 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; // 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(); } 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; }
void ShellDirectory::read_directory(int scan_flags) { CONTEXT("ShellDirectory::read_directory()"); int level = _level + 1; Entry* first_entry = NULL; Entry* last = NULL; /*if (_folder.empty()) return;*/ #ifndef _NO_WIN_FS TCHAR buffer[_MAX_PATH+_MAX_FNAME]; if (!(scan_flags&SCAN_NO_FILESYSTEM) && get_path(buffer, COUNTOF(buffer)) && _tcsncmp(buffer,TEXT("::{"),3)) { 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; }