2008-09-18 03:15:49 +00:00
|
|
|
// Path.cpp: implementation of the CPath class.
|
|
|
|
//
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include <Shlobj.h>
|
2015-10-25 11:10:54 +00:00
|
|
|
#include <dos.h>
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// Constants
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
const char * const DLL_EXTENSION = "dll";
|
|
|
|
const char * const INI_EXTENSION = "ini";
|
|
|
|
const char * const EXE_EXTENSION = "exe";
|
|
|
|
const char * const WILD_NAME_EXTENSION = "*.*";
|
2008-09-18 03:15:49 +00:00
|
|
|
const TCHAR WILD_ONE = '?';
|
|
|
|
const TCHAR WILD_ANY = '*';
|
2015-10-25 11:10:54 +00:00
|
|
|
const char * const WILD_SET = "?*";
|
|
|
|
const char * const DIR_DOUBLEDELIM = "\\\\";
|
2008-09-18 03:15:49 +00:00
|
|
|
const TCHAR DRIVE_DELIMITER = ':';
|
|
|
|
const TCHAR DIRECTORY_DELIMITER = '\\';
|
|
|
|
const TCHAR EXTENSION_DELIMITER = '.';
|
|
|
|
const TCHAR DIRECTORY_DELIMITER2 = '/';
|
2015-10-25 11:10:54 +00:00
|
|
|
void * CPath::m_hInst = NULL;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// Helpers
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::SethInst ( void * hInst )
|
2009-12-28 22:22:50 +00:00
|
|
|
{
|
|
|
|
m_hInst = hInst;
|
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
void * CPath::GethInst()
|
2009-12-28 22:22:50 +00:00
|
|
|
{
|
|
|
|
return m_hInst;
|
|
|
|
}
|
|
|
|
|
2008-09-18 03:15:49 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialisation
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Helper function for the various CPath constructors.
|
|
|
|
// Initializes the data members and establishes various
|
|
|
|
// class invariants
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
inline void CPath::Init()
|
|
|
|
{
|
|
|
|
m_dwFindFileAttributes =0;
|
|
|
|
m_hFindFile =NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Helper function for the various CPath destructors.
|
|
|
|
// Cleans up varios internals
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
inline void CPath::Exit()
|
|
|
|
{
|
|
|
|
if(m_hFindFile != NULL)
|
|
|
|
{
|
|
|
|
FindClose(m_hFindFile);
|
|
|
|
m_hFindFile =NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// Construction/Destruction
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Constructs a path
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
CPath::CPath()
|
|
|
|
{
|
|
|
|
Init();
|
|
|
|
Empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Constructs a path as copy of another
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
CPath::CPath(const CPath& rPath)
|
|
|
|
{
|
|
|
|
Init();
|
|
|
|
m_strPath =rPath.m_strPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Constructs a path and points it 2 lpszPath
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
CPath::CPath(const char * lpszPath)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
Init();
|
2015-10-25 11:10:54 +00:00
|
|
|
m_strPath =lpszPath ? lpszPath : "";
|
2008-09-18 03:15:49 +00:00
|
|
|
cleanPathString(m_strPath);
|
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
CPath::CPath(const char * lpszPath, const char * NameExten)
|
2008-11-14 20:47:53 +00:00
|
|
|
{
|
|
|
|
Init();
|
2009-12-28 22:22:50 +00:00
|
|
|
SetDriveDirectory(lpszPath);
|
2008-11-14 20:47:53 +00:00
|
|
|
SetNameExtension(NameExten);
|
|
|
|
}
|
|
|
|
|
2008-09-18 03:15:49 +00:00
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Constructs a path and points it 2 strPath
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
CPath::CPath(const std::string& strPath)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
Init();
|
|
|
|
m_strPath =strPath;
|
|
|
|
cleanPathString(m_strPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Constructs a path and points it 2 strPath
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
CPath::CPath(const std::string& strPath, const char * NameExten)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
Init();
|
|
|
|
SetDriveDirectory(strPath.c_str());
|
|
|
|
SetNameExtension(NameExten);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Constructs a path and points it 2 strPath
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
CPath::CPath(const std::string& strPath, const std::string& NameExten)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
Init();
|
|
|
|
SetDriveDirectory(strPath.c_str());
|
|
|
|
SetNameExtension(NameExten.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Cleanup and destruct a path object
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
CPath::~CPath()
|
|
|
|
{
|
|
|
|
Exit();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Post : Return TRUE if paths are equal
|
|
|
|
// Task : Check if the two path are the same
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::operator ==(const CPath& rPath) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
// Get fully qualified versions of the paths
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string FullyQualified1;
|
|
|
|
std::string FullyQualified2;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetFullyQualified(FullyQualified1);
|
|
|
|
rPath.GetFullyQualified(FullyQualified2);
|
|
|
|
|
|
|
|
// Compare them
|
2015-10-25 11:10:54 +00:00
|
|
|
return _stricmp(FullyQualified1.c_str(), FullyQualified2.c_str()) == 0;
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Post : Return TRUE if paths are different
|
|
|
|
// Task : Check if the two path are different
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::operator !=(const CPath& rPath) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
return !(*this == rPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Assign a path 2 another
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
CPath& CPath::operator =(const CPath& rPath)
|
|
|
|
{
|
|
|
|
if(this != &rPath)
|
|
|
|
m_strPath =rPath.m_strPath;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Post : Return the path, so that assignements can be chained
|
|
|
|
// Task : Assign a string 2 a path
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
CPath& CPath::operator =(const char * lpszPath)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
m_strPath =lpszPath ? lpszPath : "";
|
2008-09-18 03:15:49 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Post : Return the path, so that assignements can be chained
|
|
|
|
// Task : Assign a string 2 a path
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
CPath& CPath::operator =(const std::string& strPath)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
m_strPath =strPath;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Post : Converts path 2 string
|
|
|
|
// Task : Convert path 2 string
|
|
|
|
// Warning: because this pointer 2 string point in the data
|
|
|
|
// of this class, it is possible 2 cast the result of this
|
|
|
|
// function in any non-constant pointer and alter the data.
|
|
|
|
// Very dangerous
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
CPath::operator const char *() const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
return (const char *)m_strPath.c_str();
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
CPath::CPath(DIR_CURRENT_DIRECTORY /*sdt*/, const char * NameExten)
|
2009-12-28 22:22:50 +00:00
|
|
|
{
|
|
|
|
// Application's current directory
|
|
|
|
Init();
|
|
|
|
CurrentDirectory();
|
|
|
|
if (NameExten) { SetNameExtension(NameExten); }
|
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
CPath::CPath(DIR_MODULE_DIRECTORY /*sdt*/, const char * NameExten)
|
2009-12-28 22:22:50 +00:00
|
|
|
{
|
|
|
|
// The directory where the executable of this app is
|
|
|
|
Init();
|
|
|
|
ModuleDirectory();
|
|
|
|
if (NameExten) { SetNameExtension(NameExten); }
|
|
|
|
}
|
|
|
|
|
|
|
|
CPath::CPath(DIR_MODULE_FILE /*sdt*/)
|
|
|
|
{
|
|
|
|
// The directory where the executable of this app is
|
|
|
|
Init();
|
|
|
|
Module();
|
|
|
|
}
|
|
|
|
|
2008-09-18 03:15:49 +00:00
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Post : Returns the drive component without a colon, e.g. "c"
|
|
|
|
// Returns the directory component with a leading backslash,
|
|
|
|
// but no trailing backslash, e.g. "\dir\subdir"
|
|
|
|
// Returns name compleletely without delimiters, e.g "letter"
|
|
|
|
// Returns extension completely without delimiters, e.g. "doc"
|
|
|
|
// Globals :
|
|
|
|
// I/O :
|
|
|
|
// Task : Return the individual components of this path.
|
|
|
|
// For any given argument, you can pass NULL if you are not
|
|
|
|
// interested in that component.
|
|
|
|
// Do not rely on pNames being <= 8 characters, extensions
|
|
|
|
// being <= 3 characters, or drives being 1 character
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::GetComponents(std::string* pDrive,
|
|
|
|
std::string* pDirectory,
|
|
|
|
std::string* pName,
|
|
|
|
std::string* pExtension) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
TCHAR buff_drive[_MAX_DRIVE + 1];
|
|
|
|
TCHAR buff_dir [_MAX_DIR + 1];
|
|
|
|
TCHAR buff_name [_MAX_FNAME + 1];
|
|
|
|
TCHAR buff_ext [_MAX_EXT + 1];
|
|
|
|
|
|
|
|
ZeroMemory(buff_drive,sizeof(buff_drive));
|
|
|
|
ZeroMemory(buff_dir, sizeof(buff_dir));
|
|
|
|
ZeroMemory(buff_name, sizeof(buff_name));
|
|
|
|
ZeroMemory(buff_ext, sizeof(buff_ext));
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
_splitpath(m_strPath.c_str(),
|
2009-12-28 22:22:50 +00:00
|
|
|
pDrive ? buff_drive : NULL,
|
|
|
|
pDirectory ? buff_dir : NULL,
|
|
|
|
pName ? buff_name : NULL,
|
|
|
|
pExtension ? buff_ext : NULL);
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
if(pDrive)
|
|
|
|
*pDrive =buff_drive;
|
|
|
|
if(pDirectory)
|
|
|
|
*pDirectory =buff_dir;
|
|
|
|
if(pName)
|
|
|
|
*pName =buff_name;
|
|
|
|
if(pExtension)
|
|
|
|
*pExtension =buff_ext;
|
|
|
|
|
|
|
|
// DOS's _splitpath returns "d:", we return "d"
|
|
|
|
if(pDrive)
|
|
|
|
StripTrailingChar(*pDrive,DRIVE_DELIMITER);
|
|
|
|
// DOS's _splitpath returns "\dir\subdir\", we return "\dir\subdir"
|
|
|
|
if(pDirectory)
|
|
|
|
StripTrailingBackslash(*pDirectory);
|
|
|
|
// DOS's _splitpath returns ".ext", we return "ext"
|
|
|
|
if(pExtension)
|
|
|
|
StripLeadingChar(*pExtension,EXTENSION_DELIMITER);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Get drive and directory from path
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::GetDriveDirectory(std::string& rDriveDirectory) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Drive;
|
|
|
|
std::string Directory;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetComponents(&Drive,&Directory);
|
|
|
|
rDriveDirectory =Drive;
|
|
|
|
if(!Drive.empty())
|
|
|
|
{
|
|
|
|
rDriveDirectory += DRIVE_DELIMITER;
|
|
|
|
rDriveDirectory += Directory;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string CPath::GetDriveDirectory(void) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string rDriveDirectory;
|
2008-09-18 03:15:49 +00:00
|
|
|
GetDriveDirectory(rDriveDirectory);
|
|
|
|
return rDriveDirectory;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Get directory from path
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::GetDirectory(std::string& rDirectory) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
GetComponents(NULL,&rDirectory);
|
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string CPath::GetDirectory(void) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string rDirectory;
|
2008-09-18 03:15:49 +00:00
|
|
|
GetComponents(NULL,&rDirectory);
|
|
|
|
return rDirectory;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Get filename and extension from path
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::GetNameExtension(std::string& rNameExtension) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Name;
|
|
|
|
std::string Extension;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetComponents(NULL,NULL,&Name,&Extension);
|
|
|
|
rNameExtension =Name;
|
|
|
|
if(!Extension.empty())
|
|
|
|
{
|
|
|
|
rNameExtension += EXTENSION_DELIMITER;
|
|
|
|
rNameExtension += Extension;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string CPath::GetNameExtension(void) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string rNameExtension;
|
2008-09-18 03:15:49 +00:00
|
|
|
GetNameExtension(rNameExtension);
|
|
|
|
return rNameExtension;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Get filename from path
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::GetName(std::string& rName) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
GetComponents(NULL,NULL,&rName);
|
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string CPath::GetName(void) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string rName;
|
2008-09-18 03:15:49 +00:00
|
|
|
GetComponents(NULL,NULL,&rName);
|
|
|
|
return rName;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Get file extension from path
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::GetExtension(std::string& rExtension) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
GetComponents(NULL,NULL,NULL,&rExtension);
|
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string CPath::GetExtension(void) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string rExtension;
|
2008-09-18 03:15:49 +00:00
|
|
|
GetComponents(NULL,NULL,NULL,&rExtension);
|
|
|
|
return rExtension;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Get current directory
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::GetCurrentDirectory(std::string& rDirectory) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Directory;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
rDirectory = "";
|
|
|
|
|
|
|
|
GetDirectory(Directory);
|
|
|
|
StripTrailingBackslash(Directory);
|
|
|
|
if(Directory.empty())
|
|
|
|
return;
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string::size_type nDelimiter =Directory.rfind(DIRECTORY_DELIMITER);
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
rDirectory =Directory.substr(nDelimiter);
|
|
|
|
StripLeadingBackslash(rDirectory);
|
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string CPath::GetCurrentDirectory(void) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string rDirecotry;
|
2008-09-18 03:15:49 +00:00
|
|
|
GetCurrentDirectory(rDirecotry);
|
|
|
|
return rDirecotry;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Get fully qualified path
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::GetFullyQualified(std::string& rFullyQualified) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
TCHAR buff_fullname[MAX_PATH];
|
|
|
|
|
2009-12-28 22:22:50 +00:00
|
|
|
memset(buff_fullname, 0, sizeof(buff_fullname));
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
_fullpath(buff_fullname, m_strPath.c_str(), MAX_PATH - 1);
|
2008-09-18 03:15:49 +00:00
|
|
|
rFullyQualified =buff_fullname;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Post : Return TRUE if path does not start from filesystem root
|
|
|
|
// Task : Check if path is a relative one (e.g. doesn't start with C:\...)
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::IsRelative() const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
if (m_strPath.length() > 1 && m_strPath[1] == DRIVE_DELIMITER)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (m_strPath.length() > 1 && m_strPath[0] == DIRECTORY_DELIMITER && m_strPath[1] == DIRECTORY_DELIMITER)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path components
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::SetComponents(const char * lpszDrive,
|
|
|
|
const char * lpszDirectory,
|
|
|
|
const char * lpszName,
|
|
|
|
const char * lpszExtension)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
TCHAR buff_fullname[MAX_PATH];
|
|
|
|
|
2009-12-28 22:22:50 +00:00
|
|
|
memset(buff_fullname, 0, sizeof(buff_fullname));
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
_makepath(buff_fullname, lpszDrive, lpszDirectory, lpszName, lpszExtension);
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
m_strPath.erase();
|
|
|
|
m_strPath =buff_fullname;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path's drive
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
void CPath::SetDrive(TCHAR chDrive)
|
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
stdstr_f Drive("%c",chDrive);
|
|
|
|
std::string Directory;
|
|
|
|
std::string Name;
|
|
|
|
std::string Extension;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetComponents(NULL,&Directory,&Name,&Extension);
|
|
|
|
SetComponents(Drive.c_str(),Directory.c_str(),Name.c_str(),Extension.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path's directory
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::SetDirectory(const char * lpszDirectory, bool bEnsureAbsolute /*= FALSE*/)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Drive;
|
|
|
|
std::string Directory =lpszDirectory;
|
|
|
|
std::string Name;
|
|
|
|
std::string Extension;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
if(bEnsureAbsolute)
|
|
|
|
EnsureLeadingBackslash(Directory);
|
|
|
|
EnsureTrailingBackslash(Directory);
|
|
|
|
|
|
|
|
GetComponents(&Drive,NULL,&Name,&Extension);
|
|
|
|
SetComponents(Drive.c_str(),Directory.c_str(),Name.c_str(),Extension.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path's drive and directory
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::SetDriveDirectory(const char * lpszDriveDirectory)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string DriveDirectory =lpszDriveDirectory;
|
|
|
|
std::string Name;
|
|
|
|
std::string Extension;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
EnsureTrailingBackslash(DriveDirectory);
|
|
|
|
cleanPathString(DriveDirectory);
|
|
|
|
|
|
|
|
GetComponents(NULL,NULL,&Name,&Extension);
|
|
|
|
SetComponents(NULL,DriveDirectory.c_str(),Name.c_str(),Extension.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path's filename
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::SetName(const char * lpszName)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Drive;
|
|
|
|
std::string Directory;
|
|
|
|
std::string Extension;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetComponents(&Drive,&Directory,NULL,&Extension);
|
|
|
|
SetComponents(Drive.c_str(),Directory.c_str(),lpszName,Extension.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path's filename
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
void CPath::SetName(int iName)
|
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Drive;
|
|
|
|
std::string Directory;
|
|
|
|
std::string Extension;
|
2008-09-18 03:15:49 +00:00
|
|
|
TCHAR sName[33];
|
|
|
|
|
2009-12-28 22:22:50 +00:00
|
|
|
memset(sName, 0, sizeof(sName));
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
_itoa(iName, sName, 10);
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetComponents(&Drive,&Directory,NULL,&Extension);
|
|
|
|
SetComponents(Drive.c_str(),Directory.c_str(),sName,Extension.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path's file extension
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::SetExtension(const char * lpszExtension)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Drive;
|
|
|
|
std::string Directory;
|
|
|
|
std::string Name;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetComponents(&Drive,&Directory,&Name);
|
|
|
|
SetComponents(Drive.c_str(),Directory.c_str(),Name.c_str(),lpszExtension);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path's file extension
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
void CPath::SetExtension(int iExtension)
|
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Drive;
|
|
|
|
std::string Directory;
|
|
|
|
std::string Name;
|
2008-09-18 03:15:49 +00:00
|
|
|
TCHAR sExtension[20];
|
|
|
|
|
2009-12-28 22:22:50 +00:00
|
|
|
memset(sExtension, 0, sizeof(sExtension));
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
_itoa(iExtension, sExtension, 10);
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetComponents(&Drive,&Directory,&Name);
|
|
|
|
SetComponents(Drive.c_str(),Directory.c_str(),Name.c_str(),sExtension);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path's filename and extension
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::SetNameExtension(const char * lpszNameExtension)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Drive;
|
|
|
|
std::string Directory;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetComponents(&Drive,&Directory);
|
|
|
|
SetComponents(Drive.c_str(),Directory.c_str(),lpszNameExtension,NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Append a subdirectory 2 path's directory
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::AppendDirectory(const char * lpszSubDirectory)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Drive;
|
|
|
|
std::string Directory;
|
|
|
|
std::string SubDirectory =lpszSubDirectory;
|
|
|
|
std::string Name;
|
|
|
|
std::string Extension;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
if(SubDirectory.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Strip out any preceeding backslash
|
|
|
|
StripLeadingBackslash(SubDirectory);
|
|
|
|
EnsureTrailingBackslash(SubDirectory);
|
|
|
|
|
|
|
|
GetComponents(&Drive,&Directory,&Name,&Extension);
|
|
|
|
EnsureTrailingBackslash(Directory);
|
|
|
|
Directory +=SubDirectory;
|
|
|
|
|
|
|
|
SetComponents(Drive.c_str(),Directory.c_str(),Name.c_str(),Extension.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Pre : If pLastDirectory is given we will store the name of the
|
|
|
|
// deepest directory (the one we're just exiting) in it
|
|
|
|
// Task : Remove deepest subdirectory from path
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::UpDirectory(std::string *pLastDirectory /*= NULL*/)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string Directory;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetDirectory(Directory);
|
|
|
|
StripTrailingBackslash(Directory);
|
|
|
|
if(Directory.empty())
|
|
|
|
return;
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string::size_type nDelimiter =Directory.rfind(DIRECTORY_DELIMITER);
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
if(pLastDirectory != NULL)
|
|
|
|
{
|
|
|
|
*pLastDirectory =Directory.substr(nDelimiter);
|
|
|
|
StripLeadingBackslash(*pLastDirectory);
|
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
if(nDelimiter != std::string::npos)
|
2008-09-18 03:15:49 +00:00
|
|
|
Directory =Directory.substr(0,nDelimiter);
|
|
|
|
|
|
|
|
SetDirectory(Directory.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path 2 current directory
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
void CPath::CurrentDirectory()
|
|
|
|
{
|
|
|
|
TCHAR buff_path[MAX_PATH];
|
|
|
|
|
2009-12-28 22:22:50 +00:00
|
|
|
memset(buff_path, 0, sizeof(buff_path));
|
|
|
|
|
2008-09-18 03:15:49 +00:00
|
|
|
::GetCurrentDirectory(MAX_PATH,buff_path);
|
|
|
|
|
|
|
|
Empty();
|
|
|
|
SetDriveDirectory(buff_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path 2 the name of specified module
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::Module(void * hInstance)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
TCHAR buff_path[MAX_PATH];
|
2009-12-28 22:22:50 +00:00
|
|
|
|
|
|
|
memset(buff_path, 0, sizeof(buff_path));
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
GetModuleFileName((HINSTANCE)hInstance, buff_path, MAX_PATH);
|
2008-09-18 03:15:49 +00:00
|
|
|
m_strPath =buff_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path 2 the name of current module
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
void CPath::Module()
|
|
|
|
{
|
|
|
|
TCHAR buff_path[MAX_PATH];
|
2009-12-28 22:22:50 +00:00
|
|
|
memset(buff_path, 0, sizeof(buff_path));
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
GetModuleFileName((HMODULE)m_hInst,buff_path,MAX_PATH);
|
2008-09-18 03:15:49 +00:00
|
|
|
m_strPath =buff_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path 2 the directory of specified module
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::ModuleDirectory(void * hInstance)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
Module((HINSTANCE)hInstance);
|
|
|
|
SetNameExtension("");
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Task : Set path 2 the directory of current module
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
void CPath::ModuleDirectory()
|
|
|
|
{
|
|
|
|
Module();
|
2015-10-25 11:10:54 +00:00
|
|
|
SetNameExtension("");
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
2015-02-16 06:13:37 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
// Post : Return TRUE if a directory
|
|
|
|
// Task : Check if this path represents a directory
|
|
|
|
//---------------------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::IsDirectory() const
|
2015-02-16 06:13:37 +00:00
|
|
|
{
|
|
|
|
// Check if this path has a filename
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string file_name;
|
2015-02-16 06:13:37 +00:00
|
|
|
GetNameExtension(file_name);
|
|
|
|
|
|
|
|
return file_name.empty();
|
|
|
|
}
|
|
|
|
|
2008-09-18 03:15:49 +00:00
|
|
|
//-------------------------------------------------------------
|
2015-02-16 06:13:37 +00:00
|
|
|
// Post : Return TRUE if directory exists
|
|
|
|
// Task : To determine if the directory exists, we need to
|
|
|
|
// create a test path with a wildcard (*.*) extension
|
|
|
|
// and see if FindFirstFile returns anything. We don't
|
|
|
|
// use CPath::FindFirst() because that routine parses out
|
|
|
|
// '.' and '..', which fails for empty directories
|
2008-09-18 03:15:49 +00:00
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::DirectoryExists() const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-02-16 06:13:37 +00:00
|
|
|
// Create test path
|
|
|
|
CPath TestPath(m_strPath.c_str());
|
2008-09-18 03:15:49 +00:00
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string DirName;
|
2015-02-16 06:13:37 +00:00
|
|
|
TestPath.UpDirectory(&DirName);
|
|
|
|
TestPath.SetNameExtension(DirName.c_str());
|
2009-12-28 22:22:50 +00:00
|
|
|
|
2015-02-16 06:13:37 +00:00
|
|
|
WIN32_FIND_DATA FindData;
|
2015-10-25 11:10:54 +00:00
|
|
|
HANDLE hFindFile =FindFirstFile((const char *)TestPath,&FindData); // Find anything
|
|
|
|
bool bGotFile =(hFindFile != INVALID_HANDLE_VALUE);
|
2008-09-18 03:15:49 +00:00
|
|
|
|
2015-02-16 06:13:37 +00:00
|
|
|
if(hFindFile != NULL) // Make sure we close the search
|
|
|
|
FindClose(hFindFile);
|
2008-09-18 03:15:49 +00:00
|
|
|
|
2015-02-16 06:13:37 +00:00
|
|
|
return bGotFile;
|
|
|
|
}
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
2015-02-16 06:13:37 +00:00
|
|
|
// Post : Return TRUE if these is such a file
|
|
|
|
// Task : Check if file exists
|
2008-09-18 03:15:49 +00:00
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::Exists() const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-02-16 06:13:37 +00:00
|
|
|
WIN32_FIND_DATA FindData;
|
|
|
|
HANDLE hFindFile =FindFirstFile(m_strPath.c_str(),&FindData);
|
2015-10-25 11:10:54 +00:00
|
|
|
bool bSuccess =(hFindFile != INVALID_HANDLE_VALUE);
|
2009-12-28 22:22:50 +00:00
|
|
|
|
2015-02-16 06:13:37 +00:00
|
|
|
if(hFindFile != NULL) // Make sure we close the search
|
|
|
|
FindClose(hFindFile);
|
2009-12-28 22:22:50 +00:00
|
|
|
|
2015-02-16 06:13:37 +00:00
|
|
|
return bSuccess;
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
2015-02-16 06:13:37 +00:00
|
|
|
// Post : Return TRUE on success
|
|
|
|
// Task : Delete file
|
2008-09-18 03:15:49 +00:00
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::Delete(bool bEvenIfReadOnly) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
uint32_t dwAttr =::GetFileAttributes(m_strPath.c_str());
|
|
|
|
if(dwAttr == (uint32_t)-1)
|
2015-02-16 06:13:37 +00:00
|
|
|
// File does not exists
|
|
|
|
return FALSE;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
2015-02-16 06:13:37 +00:00
|
|
|
if(((dwAttr & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) && !bEvenIfReadOnly)
|
|
|
|
// File is read-only, and we're not allowed 2 delete it
|
|
|
|
return FALSE;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
2015-02-16 06:13:37 +00:00
|
|
|
SetFileAttributes(m_strPath.c_str(),FILE_ATTRIBUTE_NORMAL);
|
2015-10-25 11:10:54 +00:00
|
|
|
return DeleteFile(m_strPath.c_str()) != 0;
|
2015-02-16 06:13:37 +00:00
|
|
|
}
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
2015-02-16 06:13:37 +00:00
|
|
|
// Post : Return TRUE on success, FALSE if there is such a target file
|
|
|
|
// and we weren't granted permission 2 overwrite file or some error
|
|
|
|
// Task : Copy file
|
|
|
|
// Since ::CopyFile will not overwrite read only files
|
|
|
|
// we will make sure the target file is writable first
|
2008-09-18 03:15:49 +00:00
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::CopyTo(const char * lpcszTargetFile, bool bOverwrite)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-02-16 06:13:37 +00:00
|
|
|
// Check if the target file exists
|
|
|
|
CPath TargetFile(lpcszTargetFile);
|
|
|
|
if(TargetFile.Exists())
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-02-16 06:13:37 +00:00
|
|
|
// Yeah there is already such a target file
|
|
|
|
// Decide if we should overwrite
|
|
|
|
if(!bOverwrite)
|
|
|
|
return FALSE;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
2015-02-16 06:13:37 +00:00
|
|
|
// Delete any previous target
|
|
|
|
if(!TargetFile.Delete(TRUE))
|
|
|
|
return FALSE;
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
2015-02-16 06:13:37 +00:00
|
|
|
|
|
|
|
// CopyFile will set the target's attributes 2 the same as
|
|
|
|
// the source after copying
|
2015-10-25 11:10:54 +00:00
|
|
|
return CopyFile(m_strPath.c_str(),lpcszTargetFile,!bOverwrite) != 0;
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
2015-02-16 06:13:37 +00:00
|
|
|
// Post : Return TRUE on success, FALSE if there is such a target file
|
|
|
|
// and we weren't granted permission 2 overwrite file or some error
|
|
|
|
// Task : Move file
|
2008-09-18 03:15:49 +00:00
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::MoveTo(const char * lpcszTargetFile, bool bOverwrite)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-02-16 06:13:37 +00:00
|
|
|
// Check if the target file exists
|
|
|
|
CPath TargetFile(lpcszTargetFile);
|
|
|
|
if(TargetFile.Exists())
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-02-16 06:13:37 +00:00
|
|
|
// Yeah there is already such a target file
|
|
|
|
// Decide if we should overwrite
|
|
|
|
if(!bOverwrite)
|
|
|
|
return FALSE;
|
2009-12-28 22:22:50 +00:00
|
|
|
|
2015-02-16 06:13:37 +00:00
|
|
|
// Delete any previous target
|
|
|
|
if(!TargetFile.Delete(TRUE))
|
|
|
|
return FALSE;
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
return MoveFile(m_strPath.c_str(),lpcszTargetFile) != 0;
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
2015-02-16 06:13:37 +00:00
|
|
|
// Post : Return TRUE if attributes do match
|
|
|
|
// Task : Compare finder attributes
|
2008-09-18 03:15:49 +00:00
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::AttributesMatch(uint32_t dwTargetAttributes, uint32_t dwFileAttributes)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
if (dwTargetAttributes == _A_ALLFILES)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(dwTargetAttributes == _A_NORMAL)
|
|
|
|
{
|
|
|
|
return ((_A_SUBDIR & dwFileAttributes) == 0);
|
|
|
|
}
|
2015-01-27 05:07:44 +00:00
|
|
|
return ( ((dwTargetAttributes & dwFileAttributes) != 0) && ((_A_SUBDIR & dwTargetAttributes) == (_A_SUBDIR & dwFileAttributes)) );
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Post : Return TRUE if any match found
|
|
|
|
// Task : Find the first file that meets this path and the specified attributes
|
|
|
|
// You can specify the current attributes of the file or directory
|
|
|
|
// The attributes are represented by a combination (|) of the following
|
|
|
|
// constants:
|
|
|
|
//
|
|
|
|
// _A_ARCH Archive. Set whenever the file is
|
|
|
|
// changed, and cleared by the BACKUP command
|
|
|
|
// _A_HIDDEN Hidden file. Not normally seen with
|
|
|
|
// the DIR command, unless the /AH option
|
|
|
|
// is used. Returns information about normal
|
|
|
|
// files as well as files with this attribute
|
|
|
|
// _A_NORMAL Normal. File can be read or written to
|
|
|
|
// without restriction
|
|
|
|
// _A_RDONLY Read-only. File cannot be opened for writing,
|
|
|
|
// and a file with the same name cannot be created
|
|
|
|
// _A_SUBDIR Subdirectory
|
|
|
|
// _A_SYSTEM System file. Not normally seen with the DIR
|
|
|
|
// command, unless the /AS option is used
|
|
|
|
//
|
|
|
|
// These attributes do not follow a simple additive logic
|
|
|
|
// Note that _A_NORMAL is 0x00, so it effectively cannot be
|
|
|
|
// removed from the attribute set. You will therefore always
|
|
|
|
// get normal files, and may also get Archive, Hidden, etc.
|
|
|
|
// if you specify those attributes
|
|
|
|
// See aso: FindFirstFile, FindNextFile
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::FindFirst(uint32_t dwAttributes /*= _A_NORMAL*/)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
m_dwFindFileAttributes =dwAttributes;
|
|
|
|
BOOL bGotFile;
|
|
|
|
BOOL bWantSubdirectory =(BOOL)(_A_SUBDIR & dwAttributes);
|
|
|
|
|
|
|
|
// Close handle to any previous enumeration
|
|
|
|
Exit();
|
|
|
|
|
|
|
|
// i.) Finding first candidate file
|
|
|
|
WIN32_FIND_DATA FindData;
|
|
|
|
m_hFindFile =FindFirstFile(m_strPath.c_str(),&FindData);
|
|
|
|
bGotFile =(m_hFindFile != INVALID_HANDLE_VALUE);
|
|
|
|
|
|
|
|
while(bGotFile)
|
|
|
|
{
|
|
|
|
// ii.) Compare candidate to attributes, and filter out the "." and ".." folders
|
|
|
|
if(!AttributesMatch(m_dwFindFileAttributes,FindData.dwFileAttributes))
|
|
|
|
goto LABEL_GetAnother;
|
|
|
|
if(bWantSubdirectory && (FindData.cFileName[0] == '.'))
|
|
|
|
goto LABEL_GetAnother;
|
|
|
|
|
|
|
|
// iii.) Found match, prepare result
|
|
|
|
if((_A_SUBDIR & FindData.dwFileAttributes) != 0)
|
|
|
|
StripTrailingBackslash(m_strPath);
|
|
|
|
|
|
|
|
SetNameExtension(FindData.cFileName);
|
|
|
|
|
|
|
|
if((_A_SUBDIR & FindData.dwFileAttributes) != 0)
|
|
|
|
EnsureTrailingBackslash(m_strPath);
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
// iv.) Not found match, get another
|
|
|
|
LABEL_GetAnother:
|
|
|
|
bGotFile =FindNextFile(m_hFindFile,&FindData);
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Post : Return TRUE if a new match found
|
|
|
|
// Task : Find the next file that meets the conditions specified
|
|
|
|
// in the last FindFirst call
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::FindNext()
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
if (m_hFindFile == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
WIN32_FIND_DATA FindData;
|
|
|
|
while(FindNextFile(m_hFindFile,&FindData) != FALSE)
|
|
|
|
{ // while(FindNext(...))
|
|
|
|
|
|
|
|
if(AttributesMatch(m_dwFindFileAttributes,FindData.dwFileAttributes))
|
|
|
|
{ // if(AttributesMatch(...)
|
|
|
|
if((_A_SUBDIR & FindData.dwFileAttributes) == _A_SUBDIR)
|
|
|
|
{
|
|
|
|
if (IsDirectory())
|
|
|
|
{
|
|
|
|
// Found a directory
|
|
|
|
UpDirectory();
|
2015-03-17 21:19:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-09-18 03:15:49 +00:00
|
|
|
SetNameExtension("");
|
|
|
|
}
|
|
|
|
AppendDirectory(FindData.cFileName);
|
2015-03-17 21:19:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-09-18 03:15:49 +00:00
|
|
|
// Found a file
|
|
|
|
if (IsDirectory())
|
|
|
|
{
|
|
|
|
// Found a directory
|
|
|
|
UpDirectory();
|
|
|
|
}
|
|
|
|
SetNameExtension(FindData.cFileName);
|
|
|
|
}
|
|
|
|
if((_A_SUBDIR & FindData.dwFileAttributes) == _A_SUBDIR)
|
|
|
|
EnsureTrailingBackslash(m_strPath);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Post : Return TRUE on success
|
|
|
|
// Task : Change current working directory of application 2 path
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::ChangeDirectory()
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string DriveDirectory;
|
2008-09-18 03:15:49 +00:00
|
|
|
GetDriveDirectory(DriveDirectory);
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
return SetCurrentDirectory(DriveDirectory.c_str()) != 0;
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
// Pre : If bCreateIntermediates is TRUE, create all eventually
|
|
|
|
// missing parent directories too
|
|
|
|
// Post : Return TRUE on success
|
|
|
|
// Task : Create new directory
|
|
|
|
//-------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
bool CPath::DirectoryCreate(bool bCreateIntermediates /*= TRUE*/)
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string PathText;
|
|
|
|
bool bSuccess;
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
GetDriveDirectory(PathText);
|
|
|
|
StripTrailingBackslash(PathText);
|
2015-10-25 11:10:54 +00:00
|
|
|
bSuccess =::CreateDirectory(PathText.c_str(),NULL) != 0;
|
2008-09-18 03:15:49 +00:00
|
|
|
if(!bSuccess)
|
2013-04-15 03:48:06 +00:00
|
|
|
{
|
|
|
|
CPath CurrentDir(CPath::CURRENT_DIRECTORY);
|
2015-10-25 11:10:54 +00:00
|
|
|
bSuccess = ChangeDirectory() != 0;
|
2013-04-15 03:48:06 +00:00
|
|
|
CurrentDir.ChangeDirectory();
|
|
|
|
}
|
|
|
|
|
2008-09-18 03:15:49 +00:00
|
|
|
if(!bSuccess && bCreateIntermediates)
|
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string::size_type nDelimiter =PathText.rfind(DIRECTORY_DELIMITER);
|
|
|
|
if(nDelimiter == std::string::npos)
|
2008-09-18 03:15:49 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
PathText.resize(nDelimiter + 1);
|
|
|
|
CPath SubPath(PathText);
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
if (SubPath.DirectoryCreate())
|
|
|
|
return DirectoryCreate(false);
|
2008-09-18 03:15:49 +00:00
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bSuccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Helpers
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Task : Remove first character (if any) if it's chLeading
|
|
|
|
//------------------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::cleanPathString(std::string& rDirectory) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2013-04-17 10:29:48 +00:00
|
|
|
LPCSTR const DIR_DOUBLEDELIM = "\\\\";
|
2009-12-28 22:22:50 +00:00
|
|
|
|
2013-04-17 10:29:48 +00:00
|
|
|
std::string::size_type pos = rDirectory.find( DIRECTORY_DELIMITER2 );
|
|
|
|
while ( pos != std::string::npos )
|
2009-12-28 22:22:50 +00:00
|
|
|
{
|
2013-04-17 10:29:48 +00:00
|
|
|
rDirectory.replace( pos, 1, &DIRECTORY_DELIMITER );
|
|
|
|
pos = rDirectory.find( DIRECTORY_DELIMITER2, pos + 1 );
|
|
|
|
}
|
2009-12-28 22:22:50 +00:00
|
|
|
|
2013-04-17 10:29:48 +00:00
|
|
|
bool AppendEnd = !_strnicmp(rDirectory.c_str(), "\\\\", 2);
|
|
|
|
pos = rDirectory.find( DIR_DOUBLEDELIM );
|
|
|
|
while ( pos != std::string::npos )
|
|
|
|
{
|
2015-08-10 07:02:44 +00:00
|
|
|
rDirectory.replace( pos, 2, &DIRECTORY_DELIMITER );
|
2013-04-17 10:29:48 +00:00
|
|
|
pos = rDirectory.find( DIR_DOUBLEDELIM, pos + 1 );
|
|
|
|
}
|
|
|
|
if (AppendEnd)
|
|
|
|
{
|
|
|
|
rDirectory.insert(0, "\\");
|
2009-12-28 22:22:50 +00:00
|
|
|
}
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::StripLeadingChar(std::string& rText, TCHAR chLeading) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string::size_type nLength =rText.length();
|
2008-09-18 03:15:49 +00:00
|
|
|
if(nLength == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(rText[0] == chLeading)
|
|
|
|
rText =rText.substr(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Task : Remove first character if \
|
|
|
|
//------------------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::StripLeadingBackslash(std::string& Directory) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string::size_type nLength =Directory.length();
|
2008-09-18 03:15:49 +00:00
|
|
|
|
|
|
|
// If Directory is of the form '\', don't do it
|
|
|
|
if(nLength <= 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(Directory[0] == DIRECTORY_DELIMITER)
|
|
|
|
Directory =Directory.substr(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Task : Remove last character (if any) if it's chTrailing
|
|
|
|
//------------------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::StripTrailingChar(std::string& rText, TCHAR chTrailing) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string::size_type nLength =rText.length();
|
2008-09-18 03:15:49 +00:00
|
|
|
if(nLength == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(rText[nLength-1] == chTrailing)
|
|
|
|
rText.resize(nLength-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Task : Remove last character if \
|
|
|
|
//------------------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::StripTrailingBackslash(std::string& rDirectory) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
for (;;)
|
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string::size_type nLength = rDirectory.length();
|
2008-09-18 03:15:49 +00:00
|
|
|
if(nLength <= 1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(rDirectory[nLength-1] == DIRECTORY_DELIMITER || rDirectory[nLength-1] == DIRECTORY_DELIMITER2)
|
|
|
|
{
|
|
|
|
rDirectory.resize(nLength-1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Task : Add a backslash to the end of Directory if there is
|
|
|
|
// not already one there
|
|
|
|
//------------------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::EnsureTrailingBackslash(std::string& Directory) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
std::string::size_type nLength = Directory.length();
|
2008-09-18 03:15:49 +00:00
|
|
|
|
2015-10-25 11:10:54 +00:00
|
|
|
if (Directory.empty() || (Directory[nLength - 1] != DIRECTORY_DELIMITER))
|
|
|
|
{
|
|
|
|
Directory += DIRECTORY_DELIMITER;
|
|
|
|
}
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
// Task : Add a backslash to the beginning of Directory if there
|
|
|
|
// is not already one there
|
|
|
|
//------------------------------------------------------------------------
|
2015-10-25 11:10:54 +00:00
|
|
|
void CPath::EnsureLeadingBackslash(std::string & Directory) const
|
2008-09-18 03:15:49 +00:00
|
|
|
{
|
|
|
|
if(Directory.empty() || (Directory[0] != DIRECTORY_DELIMITER))
|
|
|
|
{
|
2015-10-25 11:10:54 +00:00
|
|
|
Directory = stdstr_f("%c%s", DIRECTORY_DELIMITER, Directory.c_str());
|
2008-09-18 03:15:49 +00:00
|
|
|
}
|
2015-03-17 21:19:42 +00:00
|
|
|
}
|