⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shellfs.cpp

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -