Index: explorer/shell/shellfs.cpp =================================================================== --- explorer/shell/shellfs.cpp (revision 47244) +++ explorer/shell/shellfs.cpp (working copy) @@ -260,110 +260,24 @@ { 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); - } + if (!(scan_flags&SCAN_NO_FILESYSTEM) && get_path(buffer, COUNTOF(buffer)) && _tcsncmp(buffer,TEXT("::{"),3)) + { + scan_win_dir(this, scan_flags, buffer); } else // SCAN_NO_FILESYSTEM #endif { + int level = _level + 1; + + Entry* first_entry = NULL; + Entry* last = NULL; + ShellItemEnumerator enumerator(_folder, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN|SHCONTF_SHAREABLE|SHCONTF_STORAGE); TCHAR name[MAX_PATH]; @@ -474,13 +388,12 @@ } } } while(SUCCEEDED(hr_next)); - } + if (last) + last->_next = NULL; - if (last) - last->_next = NULL; - - _down = first_entry; - _scanned = true; + _down = first_entry; + _scanned = true; + } } const void* ShellDirectory::get_next_path_component(const void* p) const Index: explorer/shell/winfs.cpp =================================================================== --- explorer/shell/winfs.cpp (revision 47244) +++ explorer/shell/winfs.cpp (working copy) @@ -118,34 +118,40 @@ } -void WinDirectory::read_directory(int scan_flags) +void scan_win_dir(Entry * parent, int scan_flags, LPCTSTR path) { - CONTEXT("WinDirectory::read_directory()"); + CONTEXT("WinDirectory::read_directory()"); - int level = _level + 1; + int level = parent->_level + 1; Entry* first_entry = NULL; Entry* last = NULL; Entry* entry; - LPCTSTR path = (LPCTSTR)_path; - TCHAR buffer[MAX_PATH], *pname; - for(pname=buffer; *path; ) - *pname++ = *path++; + String mask = String(path) + TEXT("\\*"); - lstrcpy(pname, TEXT("\\*")); - WIN32_FIND_DATA w32fd; - HANDLE hFind = FindFirstFile(buffer, &w32fd); + HANDLE hFind = FindFirstFile(mask, &w32fd); if (hFind != INVALID_HANDLE_VALUE) { do { - lstrcpy(pname+1, w32fd.cFileName); + // 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; + + String fname = String(path) + TEXT('\\') + w32fd.cFileName; + if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - entry = new WinDirectory(this, buffer); + entry = new WinDirectory(parent, fname); else - entry = new WinEntry(this); + entry = new WinEntry(parent); if (!first_entry) first_entry = entry; @@ -153,14 +159,14 @@ if (last) last->_next = entry; - memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA)); + entry->_data = w32fd; entry->_level = level; // display file type names, but don't hide file extensions - g_Globals._ftype_mgr.set_type(entry, true); + LPCTSTR ext = g_Globals._ftype_mgr.set_type(entry, true); if (!(scan_flags & SCAN_DONT_ACCESS)) { - HANDLE hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + HANDLE hFile = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if (hFile != INVALID_HANDLE_VALUE) { @@ -174,6 +180,32 @@ } } + 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; // There is always at least one entry, because FindFirstFile() succeeded and we don't filter the file entries. } while(FindNextFile(hFind, &w32fd)); @@ -183,11 +215,17 @@ FindClose(hFind); } - _down = first_entry; - _scanned = true; + parent->_down = first_entry; + parent->_scanned = true; } +void WinDirectory::read_directory(int scan_flags) +{ + scan_win_dir(this, scan_flags, reinterpret_cast(_path)); +} + + const void* WinDirectory::get_next_path_component(const void* p) const { LPCTSTR s = (LPCTSTR) p; Index: explorer/shell/winfs.h =================================================================== --- explorer/shell/winfs.h (revision 47244) +++ explorer/shell/winfs.h (working copy) @@ -66,3 +66,4 @@ }; extern int ScanNTFSStreams(Entry* entry, HANDLE hFile); +extern void scan_win_dir(Entry * parent, int scan_flags, LPCTSTR path);