Public Member Functions | Public Attributes | Protected Member Functions

Entry Struct Reference

base of all file and directory entries More...

#include <entries.h>

Inheritance diagram for Entry:
Inheritance graph
[legend]
Collaboration diagram for Entry:
Collaboration graph
[legend]

List of all members.

Public Member Functions

virtual ~Entry ()
void free_subentries ()
void read_directory_base (SORT_ORDER sortOrder=SORT_NAME, int scan_flags=0)
Entryread_tree (const void *path, SORT_ORDER sortOrder=SORT_NAME, int scan_flags=0)
void sort_directory (SORT_ORDER sortOrder)
void smart_scan (SORT_ORDER sortOrder=SORT_NAME, int scan_flags=0)
int extract_icon (ICONCACHE_FLAGS flags=ICF_NORMAL)
int safe_extract_icon (ICONCACHE_FLAGS flags=ICF_NORMAL)
virtual void read_directory (int scan_flags=0)
virtual const void * get_next_path_component (const void *) const
virtual Entryfind_entry (const void *)
virtual bool get_path (PTSTR path, size_t path_count) const =0
virtual ShellPath create_absolute_pidl () const
virtual HRESULT GetUIObjectOf (HWND hWnd, REFIID riid, LPVOID *ppvOut)
virtual ShellFolder get_shell_folder () const
virtual BOOL launch_entry (HWND hwnd, UINT nCmdShow=SW_SHOWNORMAL)
virtual HRESULT do_context_menu (HWND hwnd, const POINT &pos, CtxMenuInterfaces &cm_ifs)

Public Attributes

Entry_next
Entry_down
Entry_up
bool _expanded
bool _scanned
int _level
WIN32_FIND_DATA _data
SFGAOF _shell_attribs
LPTSTR _display_name
LPTSTR _type_name
LPTSTR _content
ENTRY_TYPE _etype
int _icon_id
BY_HANDLE_FILE_INFORMATION _bhfi
bool _bhfi_valid

Protected Member Functions

 Entry (ENTRY_TYPE etype)
 Entry (Entry *parent, ENTRY_TYPE etype)
 Entry (const Entry &)
bool get_path_base (PTSTR path, size_t path_count, ENTRY_TYPE etype) const

Detailed Description

base of all file and directory entries

Definition at line 82 of file entries.h.


Constructor & Destructor Documentation

Entry::Entry ( ENTRY_TYPE  etype ) [protected]

Definition at line 35 of file entries.cpp.

References _bhfi_valid, _content, _data, _display_name, _down, _expanded, _icon_id, _level, _next, _scanned, _type_name, _up, and ICID_UNKNOWN.

 :  _etype(etype)
{
    _up = NULL;
    _next = NULL;
    _down = NULL;
    _expanded = false;
    _scanned = false;
    _bhfi_valid = false;
    _level = 0;
    _icon_id = ICID_UNKNOWN;
    _display_name = _data.cFileName;
    _type_name = NULL;
    _content = NULL;
}
Entry::Entry ( Entry parent,
ENTRY_TYPE  etype 
) [protected]

Definition at line 51 of file entries.cpp.

References _bhfi_valid, _content, _data, _display_name, _down, _expanded, _icon_id, _level, _next, _scanned, _shell_attribs, _type_name, and ICID_UNKNOWN.

 :  _up(parent),
    _etype(etype)
{
    _next = NULL;
    _down = NULL;
    _expanded = false;
    _scanned = false;
    _bhfi_valid = false;
    _level = 0;
    _icon_id = ICID_UNKNOWN;
    _shell_attribs = 0;
    _display_name = _data.cFileName;
    _type_name = NULL;
    _content = NULL;
}
Entry::Entry ( const Entry other ) [protected]

Definition at line 68 of file entries.cpp.

References _bhfi, _bhfi_valid, _content, _data, _display_name, _down, _etype, _expanded, _icon_id, _level, _next, _scanned, _shell_attribs, _type_name, and _up.

{
    _next = NULL;
    _down = NULL;
    _up = NULL;

    assert(!other._next);
    assert(!other._down);
    assert(!other._up);

    _expanded = other._expanded;
    _scanned = other._scanned;
    _level = other._level;

    _data = other._data;

    _shell_attribs = other._shell_attribs;
    _display_name = other._display_name==other._data.cFileName? _data.cFileName: _tcsdup(other._display_name);
    _type_name = other._type_name? _tcsdup(other._type_name): NULL;
    _content = other._content? _tcsdup(other._content): NULL;

    _etype = other._etype;
    _icon_id = other._icon_id;

    _bhfi = other._bhfi;
    _bhfi_valid = other._bhfi_valid;
}
Entry::~Entry (  ) [virtual]

Definition at line 97 of file entries.cpp.

References _content, _data, _display_name, _down, ExplorerGlobals::_icon_cache, _icon_id, _type_name, IconCache::free_icon(), g_Globals, and ICID_NONE.

{
    if (_icon_id > ICID_NONE)
        g_Globals._icon_cache.free_icon(_icon_id);

    if (_display_name != _data.cFileName)
        free(_display_name);

    if (_type_name)
        free(_type_name);

    if (_content)
        free(_content);

    if (_down)
        delete _down;
}

Here is the call graph for this function:


Member Function Documentation

virtual ShellPath Entry::create_absolute_pidl (  ) const [inline, virtual]

Reimplemented in FATEntry, ShellEntry, and WinEntry.

Definition at line 126 of file entries.h.

Referenced by StartMenu::ActivateEntry(), ShellEntry::create_absolute_pidl(), do_context_menu(), extract_icon(), and get_shell_folder().

{return (LPCITEMIDLIST)NULL;}

Here is the caller graph for this function:

HRESULT Entry::do_context_menu ( HWND  hwnd,
const POINT &  pos,
CtxMenuInterfaces cm_ifs 
) [virtual]

Definition at line 517 of file entries.cpp.

References create_absolute_pidl(), GetDesktopFolder(), ShellFolderContextMenu(), and TEXT.

Referenced by ShellBrowser::OnTreeItemRClick(), StartMenu::WndProc(), QuickLaunchBar::WndProc(), and FileChildWindow::WndProc().

{
    ShellPath shell_path = create_absolute_pidl();
    LPCITEMIDLIST pidl_abs = shell_path;

    if (!pidl_abs)
        return S_FALSE; // no action for registry entries, etc.

#ifdef USE_MY_SHBINDTOPARENT
    IShellFolder* parentFolder;
    LPCITEMIDLIST pidlLast;

     // get and use the parent folder to display correct context menu in all cases -> correct "Properties" dialog for directories, ...
    HRESULT hr = my_SHBindToParent(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast);

    if (SUCCEEDED(hr)) {
        hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y, cm_ifs);

        parentFolder->Release();
    }

    return hr;
#else
    static DynamicFct<HRESULT(WINAPI*)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEMIDLIST*)> SHBindToParent(TEXT("SHELL32"), "SHBindToParent");

    if (SHBindToParent) {
        IShellFolder* parentFolder;
        LPCITEMIDLIST pidlLast;

         // get and use the parent folder to display correct context menu in all cases -> correct "Properties" dialog for directories, ...
        HRESULT hr = (*SHBindToParent)(pidl_abs, IID_IShellFolder, (LPVOID*)&parentFolder, &pidlLast);

        if (SUCCEEDED(hr)) {
            hr = ShellFolderContextMenu(parentFolder, hwnd, 1, &pidlLast, pos.x, pos.y, cm_ifs);

            parentFolder->Release();
        }

        return hr;
    } else {
        /**@todo use parent folder instead of desktop folder
        Entry* dir = _up;

        ShellPath parent_path;

        if (dir)
            parent_path = dir->create_absolute_pidl();
        else
            parent_path = DesktopFolderPath();

        ShellPath shell_path = create_relative_pidl(parent_path);
        LPCITEMIDLIST pidl = shell_path;

        ShellFolder parent_folder = parent_path;
        return ShellFolderContextMenu(parent_folder, hwnd, 1, &pidl, pos.x, pos.y);
        */
        return ShellFolderContextMenu(GetDesktopFolder(), hwnd, 1, &pidl_abs, pos.x, pos.y, cm_ifs);
    }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Entry::extract_icon ( ICONCACHE_FLAGS  flags = ICF_NORMAL )

Definition at line 363 of file entries.cpp.

References _etype, ExplorerGlobals::_icon_cache, COUNTOF, create_absolute_pidl(), ET_SHELL, IconCache::extract(), g_Globals, get_path(), GetUIObjectOf(), ICF_MIDDLE, ICF_OPEN, ICF_OVERLAYS, and ICID_NONE.

Referenced by safe_extract_icon().

{
    TCHAR path[MAX_PATH];

    ICON_ID icon_id = ICID_NONE;

    if (_etype!=ET_SHELL && get_path(path, COUNTOF(path)))  // not for ET_SHELL to display the correct desktop icon
        if (!(flags & ICF_MIDDLE))  // not for ICF_MIDDLE to extract 24x24 icons because SHGetFileInfo() doesn't support this icon size
            icon_id = g_Globals._icon_cache.extract(path, flags);

    if (icon_id == ICID_NONE) {
        if (!(flags & ICF_OVERLAYS)) {
            IExtractIcon* pExtract;
            if (SUCCEEDED(GetUIObjectOf(0, IID_IExtractIcon, (LPVOID*)&pExtract))) {
                unsigned gil_flags = 0;
                int idx;

                if (flags & ICF_OPEN)
                    gil_flags |= GIL_OPENICON;

                if (SUCCEEDED(pExtract->GetIconLocation(GIL_FORSHELL, path, COUNTOF(path), &idx, &gil_flags))) {
                    if (gil_flags & GIL_NOTFILENAME)
                        icon_id = g_Globals._icon_cache.extract(pExtract, path, idx, flags);
                    else {
                        if (idx == -1)
                            idx = 0;    // special case for some control panel applications ("System")

                        icon_id = g_Globals._icon_cache.extract(path, idx, flags);
                    }

                /* using create_absolute_pidl() [see below] results in more correct icons for some control panel applets (NVidia display driver).
                    if (icon_id == ICID_NONE) {
                        SHFILEINFO sfi;

                        if (SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_SMALLICON))
                            icon_id = g_Globals._icon_cache.add(sfi.hIcon)._id;
                    } */
                /*
                    if (icon_id == ICID_NONE) {
                        LPBYTE b = (LPBYTE) alloca(0x10000);
                        SHFILEINFO sfi;

                        FILE* file = fopen(path, "rb");
                        if (file) {
                            int l = fread(b, 1, 0x10000, file);
                            fclose(file);

                            if (l)
                                icon_id = g_Globals._icon_cache.add(CreateIconFromResourceEx(b, l, TRUE, 0x00030000, 16, 16, LR_DEFAULTCOLOR));
                        }
                    } */
                }
            }
        }

        if (icon_id == ICID_NONE) {
            const ShellPath& pidl_abs = create_absolute_pidl();
            LPCITEMIDLIST pidl = pidl_abs;

            icon_id = g_Globals._icon_cache.extract(pidl, flags);
        }
    }

    return icon_id;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual Entry* Entry::find_entry ( const void *   ) [inline, virtual]

Reimplemented in FATDirectory, NtObjDirectory, RegDirectory, ShellDirectory, and WinDirectory.

Definition at line 124 of file entries.h.

Referenced by ShellBrowser::jump_to_pidl(), and read_tree().

{return NULL;}

Here is the caller graph for this function:

void Entry::free_subentries (  )

Definition at line 741 of file entries.cpp.

References _down, _next, and free_subentries().

Referenced by CollectProgramsThread::free_dirs(), free_subentries(), FileChildWindow::scan_entry(), smart_scan(), Root::~Root(), and StartMenuDirectory::~StartMenuDirectory().

{
    Entry *entry, *next=_down;

    if (next) {
        _down = 0;

        do {
            entry = next;
            next = entry->_next;

            entry->free_subentries();
            delete entry;
        } while(next);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual const void* Entry::get_next_path_component ( const void *   ) const [inline, virtual]

Reimplemented in FATDirectory, RegDirectory, ShellDirectory, and WinDirectory.

Definition at line 123 of file entries.h.

Referenced by ShellBrowser::jump_to_pidl(), and read_tree().

{return NULL;}

Here is the caller graph for this function:

virtual bool Entry::get_path ( PTSTR  path,
size_t  path_count 
) const [pure virtual]
bool Entry::get_path_base ( PTSTR  path,
size_t  path_count,
ENTRY_TYPE  etype 
) const [protected]

Definition at line 637 of file entries.cpp.

References _data, _etype, _tcslen, _up, COUNTOF, ET_WINDOWS, get_path(), and TEXT.

Referenced by WinEntry::get_path(), RegEntry::get_path(), NtObjEntry::get_path(), and FATEntry::get_path().

{
    int level = 0;
    size_t len = 0;
    size_t l = 0;
    LPCTSTR name = NULL;
    TCHAR buffer[MAX_PATH];

    if (!path || path_count==0)
        return false;

    const Entry* entry;
    if ( path_count > 1 )
    {
        for(entry=this; entry; level++) {
            l = 0;

            if (entry->_etype == etype) {
                name = entry->_data.cFileName;

                for(LPCTSTR s=name; *s && *s!=TEXT('/') && *s!=TEXT('\\'); s++)
                    ++l;

                if (!entry->_up)
                    break;
            } else {
                if (entry->get_path(buffer, COUNTOF(buffer))) {
                    l = _tcslen(buffer);
                    name = buffer;

                    /* special handling of drive names */
                    if (l>0 && buffer[l-1]=='\\' && path[0]=='\\')
                        --l;

                    if ( len+l >= path_count )
                    {
                        if ( l + 1 > path_count )
                            len = 0;
                        else
                            len = path_count - l - 1;
                    }
                    memmove(path+l, path, len*sizeof(TCHAR));
                    if ( l+1 >= path_count )
                        l = path_count - 1;
                    memcpy(path, name, l*sizeof(TCHAR));
                    len += l;
                }

                entry = NULL;
                break;
            }

            if (l > 0) {
                if ( len+l+1 >= path_count )
                {
                    /* compare to 2 here because of terminator plus the '\\' we prepend */
                    if ( l + 2 > path_count )
                        len = 0;
                    else
                        len = path_count - l - 2;
                }
                memmove(path+l+1, path, len*sizeof(TCHAR));
                /* compare to 2 here because of terminator plus the '\\' we prepend */
                if ( l+2 >= path_count )
                    l = path_count - 2;
                memcpy(path+1, name, l*sizeof(TCHAR));
                len += l+1;

#ifndef _NO_WIN_FS
                if (etype == ET_WINDOWS && entry->_up && !(entry->_up->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))  // a NTFS stream?
                    path[0] = TEXT(':');
                else
#endif
                    path[0] = TEXT('\\');
            }

            entry = entry->_up;
        }

        if (entry) {
            if ( len+l >= path_count )
            {
                if ( l + 1 > path_count )
                    len = 0;
                else
                    len = path_count - l - 1;
            }
            memmove(path+l, path, len*sizeof(TCHAR));
            if ( l+1 >= path_count )
                l = path_count - 1;
            memcpy(path, name, l*sizeof(TCHAR));
            len += l;
        }

        if ( !level && (len+1 < path_count) )
            path[len++] = TEXT('\\');
    }

    path[len] = TEXT('\0');

    return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ShellFolder Entry::get_shell_folder (  ) const [virtual]

Reimplemented in ShellEntry, and ShellDirectory.

Definition at line 239 of file shellfs.cpp.

References create_absolute_pidl().

Referenced by MDIShellBrowserChild::entry_selected(), and SDIMainFrame::entry_selected().

Here is the call graph for this function:

Here is the caller graph for this function:

HRESULT Entry::GetUIObjectOf ( HWND  hWnd,
REFIID  riid,
LPVOID *  ppvOut 
) [virtual]

Reimplemented in ShellEntry.

Definition at line 579 of file entries.cpp.

References _data, _up, COUNTOF, and get_path().

Referenced by FindProgramDlg::collect_programs_callback(), and extract_icon().

{
    TCHAR path[MAX_PATH];
/*
    if (!get_path(path, COUNTOF(path)))
        return E_FAIL;

    ShellPath shell_path(path);

    IShellFolder* pFolder;
    LPCITEMIDLIST pidl_last = NULL;

    static DynamicFct<HRESULT(WINAPI*)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEMIDLIST*)> SHBindToParent(TEXT("SHELL32"), "SHBindToParent");

    if (!SHBindToParent)
        return E_NOTIMPL;

    HRESULT hr = (*SHBindToParent)(shell_path, IID_IShellFolder, (LPVOID*)&pFolder, &pidl_last);
    if (FAILED(hr))
        return hr;

    ShellFolder shell_folder(pFolder);

    shell_folder->Release();

    return shell_folder->GetUIObjectOf(hWnd, 1, &pidl_last, riid, NULL, ppvOut);
*/
    if (!_up)
        return E_INVALIDARG;

    if (!_up->get_path(path, COUNTOF(path)))
        return E_FAIL;

    ShellPath shell_path(path);
    ShellFolder shell_folder(shell_path);

#ifdef UNICODE
    LPWSTR wname = _data.cFileName;
#else
    WCHAR wname[MAX_PATH];
    MultiByteToWideChar(CP_ACP, 0, _data.cFileName, -1, wname, COUNTOF(wname));
#endif

    LPITEMIDLIST pidl_last = NULL;
    HRESULT hr = shell_folder->ParseDisplayName(hWnd, NULL, wname, NULL, &pidl_last, NULL);

    if (FAILED(hr))
        return hr;

    hr = shell_folder->GetUIObjectOf(hWnd, 1, (LPCITEMIDLIST*)&pidl_last, riid, NULL, ppvOut);

    ShellMalloc()->Free((void*)pidl_last);

    return hr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

BOOL Entry::launch_entry ( HWND  hwnd,
UINT  nCmdShow = SW_SHOWNORMAL 
) [virtual]

Reimplemented in NtObjEntry, RegEntry, and ShellEntry.

Definition at line 441 of file entries.cpp.

References COUNTOF, get_path(), and launch_file().

Referenced by FileChildWindow::activate_entry(), QuickLaunchBar::Command(), and FindProgramDlg::LaunchSelected().

{
    TCHAR cmd[MAX_PATH];

    if (!get_path(cmd, COUNTOF(cmd)))
        return FALSE;

     // add path to the recent file list
    SHAddToRecentDocs(SHARD_PATH, cmd);

      // start program, open document...
    return launch_file(hwnd, cmd, nCmdShow);
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void Entry::read_directory ( int  scan_flags = 0 ) [inline, virtual]

Reimplemented in FATDirectory, NtObjDirectory, RegDirectory, RegistryRoot, ShellDirectory, and WinDirectory.

Definition at line 122 of file entries.h.

Referenced by ShellBrowser::Init(), and read_directory_base().

{}

Here is the caller graph for this function:

void Entry::read_directory_base ( SORT_ORDER  sortOrder = SORT_NAME,
int  scan_flags = 0 
)

Todo:
_prescan_nodes should not be used for reading the start menu.

Definition at line 141 of file entries.cpp.

References _down, _next, ExplorerGlobals::_prescan_nodes, CONTEXT, g_Globals, read_directory(), and sort_directory().

Referenced by FileChildWindow::scan_entry(), and smart_scan().

{
    CONTEXT("Entry::read_directory_base()");

     // call into subclass
    read_directory(scan_flags);

#ifndef ROSSHELL
    if (g_Globals._prescan_nodes) { ///@todo _prescan_nodes should not be used for reading the start menu.
        for(Entry*entry=_down; entry; entry=entry->_next)
            if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                entry->read_directory(scan_flags);
                entry->sort_directory(sortOrder);
            }
    }
#endif

    sort_directory(sortOrder);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Entry * Entry::read_tree ( const void *  path,
SORT_ORDER  sortOrder = SORT_NAME,
int  scan_flags = 0 
)

Definition at line 117 of file entries.cpp.

References CONTEXT, find_entry(), get_next_path_component(), and smart_scan().

Referenced by Root::read_tree().

{
    CONTEXT("Entry::read_tree()");

    WaitCursor wait;

    Entry* entry = this;

    for(const void*p=path; p && entry; ) {
        entry->smart_scan(sortOrder, scan_flags);

        if (entry->_down)
            entry->_expanded = true;

        Entry* found = entry->find_entry(p);
        p = entry->get_next_path_component(p);

        entry = found;
    }

    return entry;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Entry::safe_extract_icon ( ICONCACHE_FLAGS  flags = ICF_NORMAL )

Definition at line 429 of file entries.cpp.

References extract_icon(), and ICID_NONE.

Referenced by ShellBrowser::OnTreeGetDispInfo(), ShellDirectory::read_directory(), and StartMenu::UpdateIcons().

{
    try {
        return extract_icon(flags);
    } catch(COMException&) {
        // ignore unexpected exceptions while extracting icons
    }

    return ICID_NONE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Entry::smart_scan ( SORT_ORDER  sortOrder = SORT_NAME,
int  scan_flags = 0 
)

Todo:
We could use IShellFolder2::GetDefaultColumn to determine sort order.

Definition at line 351 of file entries.cpp.

References _scanned, CONTEXT, free_subentries(), and read_directory_base().

Referenced by RecentStartMenu::AddEntries(), StartMenu::AddEntries(), QuickLaunchBar::AddShortcuts(), CollectProgramsThread::collect_programs(), BookmarkList::import_IE_favorites(), ShellBrowser::InsertSubitems(), ShellBrowser::jump_to(), ShellBrowser::jump_to_pidl(), ShellBrowser::OnDefaultCommand(), Root::read_tree(), and read_tree().

{
    CONTEXT("Entry::smart_scan()");

    if (!_scanned) {
        free_subentries();
        read_directory_base(sortOrder, scan_flags); ///@todo We could use IShellFolder2::GetDefaultColumn to determine sort order.
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Entry::sort_directory ( SORT_ORDER  sortOrder )

Definition at line 319 of file entries.cpp.

References _down, _next, and SORT_NONE.

Referenced by RecentStartMenu::AddEntries(), and read_directory_base().

{
    if (sortOrder != SORT_NONE) {
        Entry* entry = _down;
        Entry** array, **p;
        int len;

        len = 0;
        for(entry=_down; entry; entry=entry->_next)
            ++len;

        if (len) {
            array = (Entry**) alloca(len*sizeof(Entry*));

            p = array;
            for(entry=_down; entry; entry=entry->_next)
                *p++ = entry;

             // call qsort with the appropriate compare function
            qsort(array, len, sizeof(array[0]), sortFunctions[sortOrder]);

            _down = array[0];

            for(p=array; --len; p++)
                (*p)->_next = p[1];

            (*p)->_next = 0;
        }
    }
}

Here is the caller graph for this function:


Member Data Documentation

BY_HANDLE_FILE_INFORMATION Entry::_bhfi
WIN32_FIND_DATA Entry::_data

The documentation for this struct was generated from the following files:

ROS Explorer Source Code Documentation
generated on 02.01.2013 by doxygen

ROS Explorer Homepage