📄 shellfs.cpp
字号:
/*
* Copyright 2003, 2004, 2005, 2006 Martin Fuchs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// Explorer clone
//
// shellfs.cpp
//
// Martin Fuchs, 23.07.2003
//
#include <precomp.h>
//#include "shellfs.h"
//#include "winfs.h"
#include <shlwapi.h>
bool ShellDirectory::fill_w32fdata_shell(LPCITEMIDLIST pidl, SFGAOF attribs, WIN32_FIND_DATA* pw32fdata, BY_HANDLE_FILE_INFORMATION* pbhfi, bool do_access)
{
CONTEXT("ShellDirectory::fill_w32fdata_shell()");
bool bhfi_valid = false;
if (do_access && !( (attribs&SFGAO_FILESYSTEM) && SUCCEEDED(
SHGetDataFromIDList(_folder, pidl, SHGDFIL_FINDDATA, pw32fdata, sizeof(WIN32_FIND_DATA))) )) {
WIN32_FILE_ATTRIBUTE_DATA fad;
IDataObject* pDataObj;
STGMEDIUM medium = {0, {0}, 0};
FORMATETC fmt = {g_Globals._cfStrFName, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
HRESULT hr = _folder->GetUIObjectOf(0, 1, &pidl, IID_IDataObject, 0, (LPVOID*)&pDataObj);
if (SUCCEEDED(hr)) {
hr = pDataObj->GetData(&fmt, &medium);
pDataObj->Release();
if (SUCCEEDED(hr)) {
LPCTSTR path = (LPCTSTR)GlobalLock(medium.UNION_MEMBER(hGlobal));
if (path) {
// fill with drive names "C:", ...
assert(_tcslen(path) < GlobalSize(medium.UNION_MEMBER(hGlobal)));
_tcscpy(pw32fdata->cFileName, path);
UINT sem_org = SetErrorMode(SEM_FAILCRITICALERRORS);
if (GetFileAttributesEx(path, GetFileExInfoStandard, &fad)) {
pw32fdata->dwFileAttributes = fad.dwFileAttributes;
pw32fdata->ftCreationTime = fad.ftCreationTime;
pw32fdata->ftLastAccessTime = fad.ftLastAccessTime;
pw32fdata->ftLastWriteTime = fad.ftLastWriteTime;
if (!(fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
// copy file size
pw32fdata->nFileSizeLow = fad.nFileSizeLow;
pw32fdata->nFileSizeHigh = fad.nFileSizeHigh;
} else {
// ignore FILE_ATTRIBUTE_HIDDEN attribute of NTFS drives - this would hide those drives in ShellBrowser
if (pw32fdata->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
if (path[1]==':' && path[2]=='\\' && !path[3]) // Is it a drive path?
pw32fdata->dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN;
}
}
}
HANDLE hFile = CreateFile(path, 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, pbhfi))
bhfi_valid = true;
CloseHandle(hFile);
}
SetErrorMode(sem_org);
GlobalUnlock(medium.UNION_MEMBER(hGlobal));
GlobalFree(medium.UNION_MEMBER(hGlobal));
}
}
}
}
if (!do_access || !(attribs&SFGAO_FILESYSTEM)) // Archiv files should not be displayed as folders in explorer view.
if (attribs & (SFGAO_FOLDER|SFGAO_HASSUBFOLDER))
pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
if (attribs & SFGAO_READONLY)
pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
if (attribs & SFGAO_COMPRESSED)
pw32fdata->dwFileAttributes |= FILE_ATTRIBUTE_COMPRESSED;
return bhfi_valid;
}
ShellPath ShellEntry::create_absolute_pidl() const
{
CONTEXT("ShellEntry::create_absolute_pidl()");
if (_up)
if (_up->_etype == ET_SHELL) {
ShellDirectory* dir = static_cast<ShellDirectory*>(_up);
if (dir->_pidl->mkid.cb) // Caching of absolute PIDLs could enhance performance.
return _pidl.create_absolute_pidl(dir->create_absolute_pidl());
} else
return _pidl.create_absolute_pidl(_up->create_absolute_pidl());
return _pidl;
}
// get full path of a shell entry
bool ShellEntry::get_path(PTSTR path, size_t path_count) const
{
if (!path || path_count==0)
return false;
/*
path[0] = TEXT('\0');
if (FAILED(path_from_pidl(get_parent_folder(), &*_pidl, path, path_count)))
return false;
*/
FileSysShellPath fs_path(create_absolute_pidl());
LPCTSTR ret = fs_path;
if (ret) {
lstrcpyn(path, ret, path_count);
return true;
} else
return false;
}
// get full path of a shell folder
bool ShellDirectory::get_path(PTSTR path, size_t path_count) const
{
CONTEXT("ShellDirectory::get_path()");
if (!path || path_count==0)
return false;
path[0] = TEXT('\0');
if (_folder.empty())
return false;
SFGAOF attribs = SFGAO_FILESYSTEM;
if (FAILED(const_cast<ShellFolder&>(_folder)->GetAttributesOf(1, (LPCITEMIDLIST*)&_pidl, &attribs)))
return false;
if (!(attribs & SFGAO_FILESYSTEM))
return false;
if (FAILED(path_from_pidl(get_parent_folder(), &*_pidl, path, path_count)))
return false;
return true;
}
BOOL ShellEntry::launch_entry(HWND hwnd, UINT nCmdShow)
{
CONTEXT("ShellEntry::launch_entry()");
SHELLEXECUTEINFO shexinfo;
shexinfo.cbSize = sizeof(SHELLEXECUTEINFO);
shexinfo.fMask = SEE_MASK_INVOKEIDLIST; // SEE_MASK_IDLIST is also possible.
shexinfo.hwnd = hwnd;
shexinfo.lpVerb = NULL;
shexinfo.lpFile = NULL;
shexinfo.lpParameters = NULL;
shexinfo.lpDirectory = NULL;
shexinfo.nShow = nCmdShow;
ShellPath shell_path = create_absolute_pidl();
shexinfo.lpIDList = &*shell_path;
// add PIDL to the recent file list
SHAddToRecentDocs(SHARD_PIDL, shexinfo.lpIDList);
BOOL ret = TRUE;
if (!ShellExecuteEx(&shexinfo)) {
display_error(hwnd, GetLastError());
ret = FALSE;
}
return ret;
}
HRESULT ShellEntry::do_context_menu(HWND hwnd, LPPOINT pptScreen, CtxMenuInterfaces& cm_ifs)
{
ShellDirectory* dir = static_cast<ShellDirectory*>(_up);
ShellFolder folder = dir? dir->_folder: GetDesktopFolder();
LPCITEMIDLIST pidl = _pidl;
return ShellFolderContextMenu(folder, hwnd, 1, &pidl, pptScreen->x, pptScreen->y, cm_ifs);
}
HRESULT ShellEntry::GetUIObjectOf(HWND hWnd, REFIID riid, LPVOID* ppvOut)
{
LPCITEMIDLIST pidl = _pidl;
return get_parent_folder()->GetUIObjectOf(hWnd, 1, &pidl, riid, NULL, ppvOut);
}
ShellFolder Entry::get_shell_folder() const
{
return ShellFolder(create_absolute_pidl());
}
ShellFolder ShellEntry::get_shell_folder() const
{
return get_parent_folder();
}
ShellFolder ShellDirectory::get_shell_folder() const
{
return _folder;
}
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)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -