📄 filesystem.cpp
字号:
//////////////////////////////////////////////////////////////////////
// FileFury
// Copyright (c) 2000 Tenebril Incorporated
// All rights reserved.
//
// This source code is governed by the Tenebril open source
// license (http://www.tenebril.com/developers/opensource/license.html)
//
// For more information on this and other open source applications,
// visit the Tenebril OpenSource page:
// http://www.tenebril.com/developers/opensource
//
//////////////////////////////////////////////////////////////////////
// FileSystem.cpp: implementation of the CFileSystem class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Oscar.h"
#include "FileSystem.h"
#include "Defines.h"
#include <windows.h>
#include <shlobj.h>
#include <math.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFileSystem::CFileSystem()
{
}
CFileSystem::~CFileSystem()
{
}
bool CFileSystem::ExecuteFile(HWND hWnd, LPCTSTR strName)
{
if(::ShellExecute(hWnd, "open", strName, NULL, NULL,
SW_SHOWNORMAL) <= (HINSTANCE)32)
return false;
return true;
}
BOOL CFileSystem::FindFile(LPCTSTR pstrName, DWORD dwUnused)
{
return m_cFileFind.FindFile(pstrName, dwUnused);
}
BOOL CFileSystem::FindNextFile()
{
return m_cFileFind.FindNextFile( );
}
BOOL CFileSystem::IsDots()
{
return m_cFileFind.IsDots();
}
CString CFileSystem::GetFilePath()
{
return m_cFileFind.GetFilePath();
}
BOOL CFileSystem::FillFileInfo(LPCTSTR pszPath, SHFILEINFO *fiInfo, UINT uFlags)
{
BOOL bRet = SHGetFileInfo( pszPath, 0, fiInfo, sizeof( SHFILEINFO ), uFlags );
if(bRet && fiInfo && (uFlags & SHGFI_ICON))
{
// Store the icon we found, if any.
// Get the system icon library.
COscarApp *pApp = (COscarApp *)AfxGetApp();
ASSERT(pApp);
CSettingsArchive *pArchive = pApp->GetArchive();
ASSERT(pArchive);
CSystemIconLibrary *pIconLibrary = &pArchive->m_cIconLibrary;
// Get the type of icon.
int nIconType;
if(uFlags & SHGFI_OPENICON) nIconType = OPEN_ICON;
else if(uFlags & SHGFI_SMALLICON) nIconType = SMALL_ICON;
else // Large icon is zero; therefore we just check the over flag.
nIconType = LARGE_ICON;
// Handle the special icons.
if(!IsDirectory(pszPath))
{
pIconLibrary->UpdateIcon(pszPath, fiInfo->iIcon, nIconType);
}
}
return bRet;
}
BOOL CFileSystem::GetFileStatus(LPCTSTR pszFileName, CFileStatus &rStatus)
{
return CFile::GetStatus(pszFileName, rStatus);
}
BOOL CFileSystem::IsDirectory()
{
return m_cFileFind.IsDirectory();
}
BOOL CFileSystem::IsHidden()
{
return m_cFileFind.IsHidden();
}
BOOL CFileSystem::MoveFile(LPCTSTR pszOldName, LPCTSTR pszNewName)
{
return ::MoveFile(pszOldName, pszNewName);
}
LPCTSTR CFileSystem::GetSubPath(LPCTSTR strPath)
{
//
// getting the last SubPath from a PathString
// e.g. C:\temp\readme.txt
// the result = readme.txt
static CString strTemp;
int iPos;
strTemp = strPath;
if ( strTemp.Right(1) == '\\' )
strTemp.SetAt( strTemp.GetLength() - 1, '\0' );
iPos = strTemp.ReverseFind( '\\' );
if ( iPos != -1 )
strTemp = strTemp.Mid( iPos + 1);
return (LPCTSTR)strTemp;
}
HRESULT CFileSystem::CreateLink(LPCSTR lpszPathObj, LPSTR lpszPathLink,
LPSTR lpszDesc)
{
HRESULT hres;
IShellLink* psl;
// Get a pointer to the IShellLink interface.
hres = CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl);
if (SUCCEEDED(hres)) {
IPersistFile* ppf;
// Set the path to the shortcut target, and add the
// description.
psl->SetPath(lpszPathObj);
psl->SetDescription(lpszDesc);
// Query IShellLink for the IPersistFile interface for saving the
// shortcut in persistent storage.
hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
if (SUCCEEDED(hres)) {
WORD wsz[MAX_PATH];
// Ensure that the string is ANSI.
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1,
wsz, MAX_PATH);
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
return (HRESULT)1;
}
HRESULT CFileSystem::ResolveLink(HWND hwnd, LPCSTR lpszLinkFile, LPSTR lpszPath)
{
HRESULT hres;
IShellLink* psl;
char szGotPath[MAX_PATH];
char szDescription[MAX_PATH];
WIN32_FIND_DATA wfd;
*lpszPath = 0; // assume failure
// Get a pointer to the IShellLink interface.
hres = CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl);
if (SUCCEEDED(hres)) {
IPersistFile* ppf;
// Get a pointer to the IPersistFile interface.
hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
if (SUCCEEDED(hres)) {
WORD wsz[MAX_PATH];
// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, lpszLinkFile, -1, wsz,
MAX_PATH);
// Load the shortcut.
hres = ppf->Load(wsz, STGM_READ);
if (SUCCEEDED(hres)) {
// Resolve the link.
hres = psl->Resolve(hwnd, SLR_ANY_MATCH);
if (SUCCEEDED(hres)) {
// Get the path to the link target.
hres = psl->GetPath(szGotPath,
MAX_PATH, (WIN32_FIND_DATA *)&wfd,
SLGP_SHORTPATH );
if (!SUCCEEDED(hres))
return (HRESULT)0;
// Get the description of the target.
hres = psl->GetDescription(szDescription, MAX_PATH);
if (!SUCCEEDED(hres))
return (HRESULT)0;
lstrcpy(lpszPath, szGotPath);
}
}
// Release the pointer to the IPersistFile interface.
ppf->Release();
}
// Release the pointer to the IShellLink interface.
psl->Release();
}
return (HRESULT)1;
}
LPCTSTR CFileSystem::GetFileDisplayName(LPCTSTR strName)
{
SHFILEINFO shFinfo;
if ( !FillFileInfo( strName,
&shFinfo,
SHGFI_DISPLAYNAME) )
{
return BLANK;
}
return GetFileDisplayName(shFinfo);
}
LPCTSTR CFileSystem::GetFileDisplayName(SHFILEINFO shFinfo)
{
static CString strType;
strType = CString(shFinfo.szDisplayName);
return (LPCTSTR)strType;
}
LPCTSTR CFileSystem::GetFileSize(LPCTSTR strName)
{
CFileStatus fileStatus;
if(IsDirectory(strName))
return BLANK;
if( GetFileStatus( strName, fileStatus ) )
{
static CString strSize;
LONG lSize;
double dInt;
lSize = fileStatus.m_size;
dInt = ceil((double)lSize / 1024.0);
if(dInt < 1000) // Report in kilobytes if less than 1Mb
strSize.Format("%iKB", (int)dInt);
else // Report in kilobytes anyway
{
CString strTemp, strChop;
int i, l, c;
strSize.Format("%iKB", (int)dInt);
// Add commas
l = strSize.GetLength();
strTemp = strSize.Mid(l - 5, 5);
for(i = l - 6; i >= 0; i -= 3)
{
if(i - 2 >= 0)
c = 3;
else
c = i + 1;
strChop = strSize.Mid(i, c);
strTemp = strChop + CString(_T(",")) + strTemp;
}
strSize = strTemp;
}
return (LPCTSTR)strSize;
}
return BLANK;
}
bool CFileSystem::IsDirectory(LPCTSTR strName)
{
SHFILEINFO shFinfo;
// We should just return for drives. Otherwise we may
// ping a removable drive.
if(IsVolume(strName, FALSE))
return true;
if ( !FillFileInfo( strName,
&shFinfo,
SHGFI_ATTRIBUTES ) )
{
return false;
}
return IsDirectory(shFinfo);
}
bool CFileSystem::IsLink(LPCTSTR strName)
{
SHFILEINFO shFinfo;
if ( !FillFileInfo( strName,
&shFinfo,
SHGFI_ATTRIBUTES ) )
{
return false;
}
return IsLink(shFinfo);
}
bool CFileSystem::IsLink(SHFILEINFO shFinfo)
{
return ((shFinfo.dwAttributes & SFGAO_LINK) != 0);
}
bool CFileSystem::IsDirectory(SHFILEINFO shFinfo)
{
return ((shFinfo.dwAttributes & SFGAO_FOLDER) != 0);
}
LPCTSTR CFileSystem::GetFileType(LPCTSTR strName)
{
SHFILEINFO shFinfo;
if ( !FillFileInfo( strName,
&shFinfo,
SHGFI_TYPENAME ) )
{
return BLANK;
}
return GetFileType(shFinfo);
}
bool CFileSystem::IsVolume(LPCTSTR strName, BOOL bCheckDir)
{
if(bCheckDir && !IsDirectory(strName))
return false;
// Remove the last backslash
CString cszTrunkName = strName;
if(cszTrunkName.GetAt(cszTrunkName.GetLength() - 1) == _T('\\'))
cszTrunkName = cszTrunkName.Left(cszTrunkName.GetLength() - 1);
return (cszTrunkName.Find(_T('\\')) == -1);
}
LPCTSTR CFileSystem::GetFileType(SHFILEINFO shFinfo)
{
static CString strType;
strType = CString(shFinfo.szTypeName);
return (LPCTSTR)strType;
}
time_t CFileSystem::GetFileModificationTime(LPCTSTR strName)
{
CFileStatus fileStatus;
if( GetFileStatus( strName, fileStatus ) )
{
static CString strTime;
CTime timeModify;
timeModify = fileStatus.m_mtime;
return timeModify.GetTime();
}
return (time_t)0;
}
CString CFileSystem::GetFullPathName(LPCTSTR lpFileName)
{
CString cszFileName = CString(lpFileName);
CString cszLast;
// We don't want a volume label
if(IsVolume(cszFileName))
return cszFileName;
// Remove trailing '//'.
if(cszFileName.GetLength() == 0) return _T("");
if(cszFileName.GetAt(cszFileName.GetLength() - 1) == _T('\\'))
cszFileName = cszFileName.Left(cszFileName.GetLength() - 1);
// Handles all the directories
for(int i = 0; i < cszFileName.GetLength(); i++)
{
if(cszFileName.GetAt(i) == _T('\\'))
{
CString cszRight = cszFileName.Right(cszFileName.GetLength() - i - 1);
CString cszLeft, cszMiddle;
if(cszFileName.GetAt(i - 1) == _T(':'))
{
cszLast = cszFileName.Left(i + 1);
continue;
}
cszFileName.SetAt(i, _T('\0')); // Careful...
cszLeft = cszLast;
cszMiddle = GetFileDisplayName(cszFileName);
cszFileName = cszLast + cszMiddle +
CString(_T("\\")) + cszRight;
cszLast = cszLeft + CString(cszMiddle) + CString(_T("\\"));
i = cszLast.GetLength();
}
}
// Handle the last directory or file
CString cszMiddle = GetFileDisplayName(cszFileName);
cszFileName = cszLast + cszMiddle;
return cszFileName;
}
UINT CFileSystem::GetDriveType(LPCTSTR lpRootPathName)
{
return ::GetDriveType( lpRootPathName );
// Possible types:
// DRIVE_UNKNOWN
// DRIVE_NO_ROOT_DIR
// DRIVE_REMOVABLE
// DRIVE_FIXED
// DRIVE_REMOTE
// DRIVE_CDROM
// DRIVE_RAMDISK
}
DWORD CFileSystem::GetLogicalDriveStrings(DWORD nBufferLength, LPTSTR lpBuffer)
{
return ::GetLogicalDriveStrings( nBufferLength, lpBuffer );
}
LPCTSTR CFileSystem::GetRecycleDirectory()
{
HRESULT hCrazy;
LPITEMIDLIST pidl;
static CString cszPass;
hCrazy = SHGetSpecialFolderLocation(NULL, CSIDL_BITBUCKET,
&pidl);
if(hCrazy != NOERROR)
return BLANK;
char szPath[MAX_PATH];
if(!SHGetPathFromIDList(pidl, szPath))
return BLANK;
// Free the memory allocated by the wacky bit scheme
LPMALLOC pMalloc;
HRESULT hr = SHGetMalloc(&pMalloc);
pMalloc->Free(pidl);
pMalloc->Release();
cszPass = szPath;
return cszPass;
}
BOOL CFileSystem::IsRecycleBin(LPCTSTR cszDir)
{
// This is pretty dirty
CString cszType = GetFileType(cszDir);
return (cszType.Find(_T("Recycle")) > -1);
}
LPCTSTR CFileSystem::GetComputerName()
{
BOOL bRet = FALSE;
TCHAR *czBuffer = new TCHAR[256];
DWORD dwSize = 255;
bRet = ::GetComputerName(czBuffer, &dwSize);
if(!bRet)
return BLANK;
static CString cszPass = czBuffer;
return cszPass;
}
BOOL CFileSystem::HasSubDirectory(LPCTSTR strPath)
{
//
// Are there subDirs ?
//
CString strTemp = strPath;
BOOL bFind;
CFileFind cFFind; // We have to do this so we don't interfere
// with upper-stack searches.
if (_tcslen(strPath) == 3 )
{
if (strPath[1] == ':' && strPath[2] =='\\')
strTemp += "*.*";
else
{
if (strTemp[strTemp.GetLength()-1]=='\\')
strTemp += "*.*";
else
strTemp += "\\*.*";
}
}
else
{
if (strTemp[strTemp.GetLength()-1]=='\\')
strTemp += "*.*";
else
strTemp += "\\*.*";
}
bFind = cFFind.FindFile( strTemp );
while ( bFind )
{
bFind = cFFind.FindNextFile();
if ( cFFind.IsDirectory() && !cFFind.IsDots() )
{
return TRUE;
}
// We don't use files in the tree view
//if ( !this->IsDirectory() && bFiles && !this->IsHidden() )
// return TRUE;
}
return FALSE;
}
int CFileSystem::GetFSType()
{
return 0; // Standard filesystem.
}
BOOL CFileSystem::GetCompInfo(CStringArray &csaInfo)
{
// Get computer information.
csaInfo.RemoveAll();
csaInfo.Add(GetComputerName()); // Computer name first.
// Unused currently.
csaInfo.Add(_T("Unimplemented"));
csaInfo.Add(_T("Unimplemented"));
return TRUE;
}
BOOL CFileSystem::DeleteFile(LPCTSTR lpFileName)
{
if(!lpFileName)
return FALSE;
SHFILEOPSTRUCT shFileOpts;
CString cszFileName = lpFileName;
TCHAR *tczFiles = new TCHAR[cszFileName.GetLength() + 2]; // Double-terminated.
memset((void *)tczFiles, 0, sizeof(TCHAR) * (cszFileName.GetLength() + 2));
memcpy((void *)tczFiles, cszFileName.GetBuffer(0),
cszFileName.GetLength() * sizeof(TCHAR));
shFileOpts.hwnd = (HWND)NULL;
shFileOpts.wFunc = FO_DELETE;
shFileOpts.pFrom = tczFiles;
shFileOpts.pTo = NULL;
shFileOpts.fFlags = FOF_ALLOWUNDO; // Use recycle bin.
shFileOpts.fAnyOperationsAborted = FALSE; // Set during the operation.
shFileOpts.hNameMappings = NULL;
shFileOpts.lpszProgressTitle = NULL;
int iResult = SHFileOperation(&shFileOpts);
return (iResult == 0);
}
BOOL CFileSystem::CreateDirectory(LPCTSTR czName)
{
return ::CreateDirectory(czName, NULL);
}
BOOL CFileSystem::CopyFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName,
BOOL bFailIfExists)
{
return ::CopyFile(lpExistingFileName, lpNewFileName, bFailIfExists);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -