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

📄 cpath.cpp

📁 可以实现对邮件的加密解密以及签名
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
		Copyright (C) 2002 PGP Corporation
        All rights reserved.

        $Id: CPath.cpp,v 1.14 2002/08/06 20:10:46 dallen Exp $
____________________________________________________________________________*/

#include "pgpClassesConfig.h"

#include <commdlg.h>
#include <dbt.h>
#include <shellapi.h>
#include <shlobj.h>

#include "CFile.h"

#include "CComLibrary.h"
#include "CComObject.h"
#include "CPath.h"
#include "CRegistryKey.h"
#include "UDynLink.h"
#include "UUnicode.h"
#include "UWinVersion.h"

_USING_PGP

_UNNAMED_BEGIN

// Constants

const HKEY	kRegistryMappedDriveRoot		= HKEY_CURRENT_USER;
const char	*kRegistryMappedDrive98Section	= "Network\\Persistent";
const char	*kRegistryMappedDriveNTSection	= "Network";

const char	*kInvalidPathChars		= "<>:\"|";
const char	*k83InvalidPathChars	= "<>:\"|,;*? ";
const char	*kShortCutExtension		= ".lnk";

_UNNAMED_END


// Class CPath member functions

CPath::CPath() : mFindHandle(INVALID_HANDLE_VALUE)
{
}

CPath::CPath(const char *str) : 
	CString(str), mFindHandle(INVALID_HANDLE_VALUE)
{
}

CPath::CPath(const CPath& path) : 
	CString(path.Get()), mFindHandle(INVALID_HANDLE_VALUE)
{
}

CPath& 
CPath::operator=(const char *str)
{
	CString::operator=(str);
	return *this;
}

CPath::~CPath()
{
	try
	{
		if (FindInProgress())
			FindClose();
	}
	catch (CComboError&) { }
}

CPath& 
CPath::operator=(const CPath& path)
{
	return operator=(path.Get());
}

PGPBoolean 
CPath::HasPlainLocalRoot() const
{
	return ((Length() >= 3) && 
		(UString::LetterToNumber(GetAt(0)) < kMaxDrives) && 
		(GetAt(1) == ':') && (IsSlashChar(GetAt(2))));
}

PGPBoolean 
CPath::IsPlainLocalRoot() const
{
	return ((Length() == 3) && HasPlainLocalRoot());
}

PGPBoolean 
CPath::IsNetworkedPath() const
{
	if (IsUNCPath())
		return TRUE;

	CPath	root;
	GetRootPart(root);

	return (GetDriveType(root) == DRIVE_REMOTE);
}

PGPBoolean 
CPath::IsShortCut() const
{
	if (Length() < 4)
		return FALSE;

	CPath	ext;
	GetExtensionPart(ext);

	return ext.CompareNoCase(kShortCutExtension);
}

PGPBoolean 
CPath::IsUNCPath() const
{
	if (!IsSlashChar(GetAt(0)) || !IsSlashChar(GetAt(1)))
		return FALSE;

	PGPUInt32	length		= Length();
	PGPUInt32	numSlashes	= 0;

	for (PGPUInt32	i = 0; i < length; i++)
	{
		if (IsSlashChar(GetAt(i)))
			numSlashes++;

		if (numSlashes >= 3)
			return TRUE;
	}

	return FALSE;
}

PGPBoolean 
CPath::EndsInExtension() const
{
	for (PGPInt32 i = Length(); i > 0; i--)
	{
		char	c	= GetAt(i);

		if (IsSlashChar(c))
			return FALSE;
		else if (c == '.')
			return TRUE;
	}

	return FALSE;
}

PGPBoolean 
CPath::IsLegalPath() const
{
	if (IsEmpty())
		return FALSE;

	PGPBoolean	supportsLong	= SupportsLongFilenames();
	PGPUInt32	i, startChar;

	if (HasPlainLocalRoot())
		startChar = 3;
	else if (IsUNCPath())
		startChar = 0;
	else
		return FALSE;

	PGPUInt32	lengthPath	= Length();

	if (supportsLong)
	{
		PGPUInt32	lengthInv	= strlen(kInvalidPathChars);

		for (i = startChar; i < lengthPath; i++)
		{
			for (PGPUInt32 j = 0; j < lengthInv; j++)
			{
				if (GetAt(i) == kInvalidPathChars[j])
					return FALSE;
			}
		}
	}
	else
	{
		PGPUInt32	lengthInv	= strlen(k83InvalidPathChars);

		for (i = startChar; i < lengthPath; i++)
		{
			for (PGPUInt32 j = 0; j < lengthInv; j++)
			{
				if (GetAt(i) == k83InvalidPathChars[j])
					return FALSE;
			}
		}
	}

	if (!supportsLong)
	{
		PGPInt32	chunkSize	= 0;

		for (i = lengthPath - 1; i >= 0; i--)
		{
			char	c	= GetAt(i);

			if (c == '.')
			{
				if (chunkSize > 3)
					return FALSE;

				chunkSize = 0;
			}

			if (IsSlashChar(c))
				break;

			chunkSize++;
		}

		if (chunkSize > 8)
			return FALSE;
	}

	return TRUE;
}

PGPBoolean 
CPath::IsValidDirectory() const
{
	PGPUInt32	attribs	= GetFileAttributes(Get());

	if (attribs == 0xFFFFFFFF)
		return FALSE;
	else
		return (attribs & FILE_ATTRIBUTE_DIRECTORY ? TRUE : FALSE);
}

PGPBoolean 
CPath::IsValidFile() const
{
	PGPUInt32	attribs	= GetFileAttributes(Get());

	if (attribs == 0xFFFFFFFF)
		return FALSE;
	else
		return (attribs & FILE_ATTRIBUTE_DIRECTORY ? FALSE : TRUE);
}

PGPBoolean 
CPath::IsCompressed() const
{
	return (GetFileAttributes(Get()) & FILE_ATTRIBUTE_COMPRESSED ? TRUE : 
		FALSE);
}

PGPBoolean 
CPath::IsDriveNetworkMapped() const
{
	pgpAssert(HasPlainLocalRoot());

	CString		keyName;
	keyName.Format("%c", GetAt(0));

	CString		regPathToMapped;

	if (UWinVersion::IsWin95Compatible())
		regPathToMapped = kRegistryMappedDrive98Section;
	else
		regPathToMapped = kRegistryMappedDriveNTSection;

	regPathToMapped.Append(kBackSlash);
	regPathToMapped.Append(keyName);

	// If key exists, drive is claimed.
	PGPBoolean	isMapped	 = FALSE;

	try
	{
		CRegistryKey	mappedDriveKey;
	
		mappedDriveKey.Open(kRegistryMappedDriveRoot, regPathToMapped, 
			KEY_READ);

		isMapped = TRUE;
	}
	catch (CComboError&) { }

	return isMapped;
}

PGPBoolean 
CPath::IsReadOnly() const
{
	PGPBoolean	isReadOnly;

	try
	{
		if (IsValidDirectory())
		{
			// Attempt to create a temporary file in the directory.
			CFile	theFile;
			CPath	tempName;

			if (!GetTempFileName(Get(), "pgp", 0, 
				tempName.GetBuffer(PFLConstants::kMaxPathLength)))
			{
				THROW_PGPERROR(kPGPError_FileOpFailed);
			}

			tempName.ReleaseBuffer();
			theFile.Delete(tempName);

			isReadOnly = FALSE;
		}
		else
		{
			// Try to write a byte to the file.
			CFile		theFile;
			PGPByte		firstByte;

			theFile.Open(Get());

			PGPUInt64	length	= theFile.GetLength();

			if (length > 0)
				theFile.Read(&firstByte, 0, 1);

			theFile.Write(&firstByte, 0, 1);

			if (length == 0)
				theFile.SetLength(0);

			isReadOnly = FALSE;
		}
	}
	catch (CComboError&)
	{
		isReadOnly = TRUE;
	}

	return isReadOnly;
}

PGPBoolean 
CPath::IsDirectoryEmpty() const
{
	CPath	allFiles(*this);

	allFiles.EndInSlash();
	allFiles.Append("*");

	CPath	curFile;

	if (!allFiles.FindFirstFile(curFile))
		THROW_ERRORS(kPGPError_FileOpFailed, GetLastError());

	PGPBoolean	foundFiles	= FALSE;

	do
	{
		if ((curFile == ".") || (curFile == ".."))
			continue;

		foundFiles = TRUE;
	}
	while (allFiles.FindNextFile(curFile));

	allFiles.FindClose();

	return !foundFiles;
}

PGPUInt64 
CPath::GetFreeVolumeSpace() const
{
	// We must pass the root, not the path, to the system.
	CPath	root;
	GetRootPart(root);

	ULARGE_INTEGER	freeAvail;

	// There are two different functions - for OSR1 and for everything else.
	if (UWinVersion::IsWin95OSR2Compatible() || 
		UWinVersion::IsWinNT4Compatible())
	{
		PGPUInt32		result;
		ULARGE_INTEGER	totalBytes, totalFreeBytes;

		result = UDynLink::GetDiskFreeSpaceEx(root, &freeAvail, 
			&totalBytes, &totalFreeBytes);

		if (!result)
			THROW_ERRORS(kPGPError_FileOpFailed, GetLastError());
	}
	else
	{
		unsigned long	spc, bps, freeClust, totalClust;

		if (!GetDiskFreeSpace(root, &spc, &bps, &freeClust, &totalClust))
			THROW_ERRORS(kPGPError_FileOpFailed, GetLastError());

		freeAvail.QuadPart = bps * spc * freeClust;
	}

	return freeAvail.QuadPart;
}

PGPBoolean 
CPath::TestFreeVolumeSpace(PGPUInt64 bytes) const
{
	CPath	dir;
	GetDirPart(dir);

	// Open a temporary file in the directory.
	CPath	tempPath;

	try
	{
		GetTempFileName(dir, "pgp", 0, 
			tempPath.GetBuffer(PFLConstants::kMaxPathLength));
		tempPath.ReleaseBuffer();

		CFile	tempFile;
		tempFile.Open(tempPath, CFile::kCreateIfFlag);

		// Set the file to the desired length.
		tempFile.SetLength(bytes);

		// Make absolutely sure by closing and re-opening file.
		tempFile.Close();
		tempFile.Open(tempPath);

		if (tempFile.GetLength() != bytes)
			return FALSE;

		tempFile.Close();
		tempFile.Delete(tempPath);

		return TRUE;
	}
	catch (CComboError&)
	{
		return FALSE;
	}
}

PGPBoolean 
CPath::SupportsLongFilenames() const
{
	try
	{
		CPath	volRoot;
		GetVolumeRoot(volRoot);

		if (UWinVersion::IsWin2000Compatible())
		{
			CPath	realRoot;

			PGPBoolean	succeeded	= 
				UDynLink::Win2k_GetVolumeNameForVolumeMountPoint(volRoot, 
				realRoot.GetBuffer(PFLConstants::kMaxPathLength), 
				PFLConstants::kMaxPathLength);
			realRoot.ReleaseBuffer();

			if (succeeded)
			{
				volRoot = realRoot;
				volRoot.EndInSlash();
			}
		}

		DWORD	maxLength;

		if (!GetVolumeInformation(volRoot, NULL, 0, NULL, &maxLength, NULL, 
			NULL, 0))
		{
			THROW_ERRORS(kPGPError_VolumeOpFailed, GetLastError());
		}

		return (maxLength >= 255);
	}
	catch (CComboError&)
	{
		return TRUE;
	}
}

void 
CPath::GetVolumeFileSys(CString& fileSys) const
{
	CPath	volRoot;
	GetVolumeRoot(volRoot);

	if (UWinVersion::IsWin2000Compatible())
	{
		CPath	realRoot;

		PGPBoolean	succeeded	= 
			UDynLink::Win2k_GetVolumeNameForVolumeMountPoint(volRoot, 
			realRoot.GetBuffer(PFLConstants::kMaxPathLength), 
			PFLConstants::kMaxPathLength);
		realRoot.ReleaseBuffer();

		if (succeeded)
		{
			volRoot = realRoot;
			volRoot.EndInSlash();
		}
	}

	if (!GetVolumeInformation(volRoot, NULL, 0, NULL, NULL, NULL, 
		fileSys.GetBuffer(32), 32))
	{
		fileSys.ReleaseBuffer();
		THROW_ERRORS(kPGPError_VolumeOpFailed, GetLastError());
	}

	fileSys.ReleaseBuffer();
}

void 
CPath::GetVolumeRoot(CPath& volRoot) const
{
	if (UWinVersion::IsWin2000Compatible())
	{
		PGPBoolean	succeeded	= 
			UDynLink::Win2k_GetVolumePathName(Get(), 
			volRoot.GetBuffer(PFLConstants::kMaxPathLength), 
			PFLConstants::kMaxPathLength);
		volRoot.ReleaseBuffer();

		if (succeeded)
		{
			volRoot.EndInSlash();
			return;
		}
	}

	GetRootPart(volRoot);
}

void 
CPath::GetRootPart(CPath& root) const
{
	if (HasPlainLocalRoot())
	{
		Left(3, root);
	}
	else if (IsUNCPath())
	{
		PGPUInt32	length		= Length();
		PGPUInt32	numSlashes	= 0;

		for (PGPUInt32 i = 0; i < length; i++)
		{
			if (IsSlashChar(GetAt(i)))
				numSlashes++;

			root.Append(GetAt(i));

			if (numSlashes == 4)
				break;
		}
	}
}

void 
CPath::GetDirPart(CPath& dir) const
{
	CPath	fileName;
	GetFileNamePart(fileName);

	Left(Length() - fileName.Length(), dir);

	if (!dir.IsEmpty())
		dir.EndInSlash();
}

// GetDirPartSmart is like GetDirPart except it tacks on a working 
// directory path to incomplete directories.

void 
CPath::GetDirPartSmart(CPath& dir) const

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -