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

📄 cpath.cpp

📁 可以实现对邮件的加密解密以及签名
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
	CPath	tempDir;

	if (!HasPlainLocalRoot() && !IsUNCPath())
	{
		tempDir.AssignCurrentDirectory();

		if (IsSlashChar(GetAt(0)))
			tempDir.DontEndInSlash();
		else
			tempDir.EndInSlash();

		tempDir.Append(Get());

		if (tempDir.IsValidDirectory())
			tempDir.EndInSlash();
	}
	else
	{
		tempDir = Get();
	}

	tempDir.GetDirPart(dir);
}

void 
CPath::GetExtensionPart(CPath& extension) const
{
	extension.Empty();
	PGPUInt32	length	= Length();

	for (PGPInt32 i = length; i > 0; i--)
	{
		char	c	= GetAt(i);

		if (IsSlashChar(c))
			break;

		extension.Prepend(c);

		if (c == '.')
			break;
	}
}

void 
CPath::GetFileNamePart(CPath& fileName) const
{
	fileName.Empty();
	PGPUInt32	length	= Length();

	for (PGPInt32 i = length; i > 0; i--)
	{
		char	c	= GetAt(i);

		if (IsSlashChar(c))
			break;

		fileName.Prepend(c);
	}
}

void 
CPath::GetServerPart(CPath& server) const
{
	pgpAssert(IsUNCPath());
	Mid(2, Find(kBackSlash, 3) - 1, server);
}

void 
CPath::GetSharePart(CPath& share) const
{
	pgpAssert(IsUNCPath());

	PGPUInt32	firstChar	= Find(kBackSlash, 3) + 1;
	PGPUInt32	lastChar	= Find(kBackSlash, 4);

	if (lastChar == -1)
		lastChar = Length();
	else
		lastChar--;

	Mid(firstChar, lastChar, share);
}

PGPUInt32 
CPath::GetFreeDrives(PGPBoolean ignoreAB)
{
	PGPUInt8	i;
	PGPUInt32	drives		= GetLogicalDrives();
	PGPUInt32	freeDrives	= 0;

	// Return array of drives we can actually use.	
	PGPUInt32	startDrive	= (ignoreAB ? 2 : 0);

	for (i = startDrive; i < kMaxDrives; i++)
	{
		if (!(drives & (1 << i)))
		{
			CPath	root;
			root.MakePlainLocalRoot(i);
			
			if (!root.IsDriveNetworkMapped())
				freeDrives |= (1 << i);
		}
	}

	return freeDrives;
}

void 
CPath::AddExtension(const char *ext)
{
	pgpAssertStrValid(ext);

	if (!IsEmpty() && !EndsInExtension())
		Append(ext);
}

void 
CPath::RemoveExtension()
{
	for (PGPInt32 i = Length(); i > 0; i--)
	{
		char	c	= GetAt(i);

		if (IsSlashChar(c))
		{
			break;
		}
		else if (c == '.')
		{
			Resize(i);
			break;
		}
	}
}

void 
CPath::GetDisplayFileName(CPath& displayName) const
{
	GetFileTitle(Get(), displayName.GetBuffer(PFLConstants::kMaxPathLength), 
		PFLConstants::kMaxPathLength);
	displayName.ReleaseBuffer();
}

void 
CPath::ConvertPathToLong()
{
	CPath	prefix;
	GetRootPart(prefix);

	CPath	postfix;

	Right(Length() - prefix.Length(), postfix);
	postfix.DontEndInSlash();

	Empty();

	while (!postfix.IsEmpty())
	{
		CPath	fullPath	= prefix;
		fullPath.Append(postfix);

		CPath	fileName;

		if (!fullPath.FindFirstFile(fileName))
			THROW_ERRORS(kPGPError_FileOpFailed, GetLastError());

		fullPath.FindClose();

		int	lastSlash	= postfix.ReverseFind(kBackSlash);

		if (lastSlash == -1)
			postfix.Empty();
		else
			postfix.Resize(lastSlash);

		if (!IsEmpty())
			Prepend(kBackSlash);

		Prepend(fileName);
	}

	Prepend(prefix);

	if (IsValidDirectory())
		EndInSlash();
	else
		DontEndInSlash();
}

void 
CPath::ConvertPathToShort()
{
	CPath	temp;

	GetShortPathName(Get(), temp.GetBuffer(PFLConstants::kMaxPathLength), 
		PFLConstants::kMaxPathLength);

	Assign(temp);
}

void 
CPath::EndInSlash()
{
	if (!EndsInSlash())
		Append(kBackSlash);
}

void 
CPath::DontEndInSlash()
{
	if (EndsInSlash())
		Resize(Length() - 1);
}

void 
CPath::FixSlashes()
{
	for (PGPUInt16 i = 0; i < Length(); i++)
	{
		if (GetAt(i) == kForwardSlash)
			SetAt(i, kBackSlash);
	}
}

void 
CPath::ResolveLocalToUNC()
{
	using namespace UDynLink;

	if (UWinVersion::IsWin95Compatible())
	{
		CPath	tempPath	= Get();

		PGPBoolean	result	= Win95_WNetGetUniversalName(tempPath, 
			GetBuffer(PFLConstants::kMaxPathLength));
		ReleaseBuffer();

		if (!result)
			THROW_ERRORS(kPGPError_NetworkOpFailed, GetLastError());
	}
	else if (UWinVersion::IsWinNT4Compatible())
	{
		unsigned long	bufSize	= sizeof(UNIVERSAL_NAME_INFO) + 
			PFLConstants::kMaxPathLength * sizeof(WCHAR);

		CArray<PGPByte>	uniInfoBuf(bufSize);

		UNIVERSAL_NAME_INFO	*pUNI	= 
			reinterpret_cast<UNIVERSAL_NAME_INFO *>(uniInfoBuf.Get());

		PGPUInt32	result	= WinNT_WNetGetUniversalName(Get(), 
			UNIVERSAL_NAME_INFO_LEVEL, pUNI, &bufSize);

		if (result != NO_ERROR)
			THROW_ERRORS(kPGPError_NetworkOpFailed, result);

		Assign(pUNI->lpUniversalName);
	}
	else
	{
		pgpAssert(FALSE);
	}
}

void 
CPath::ResolveUNCToLocal()
{
	using namespace UDynLink;

	// extract strings we will use
	CPath	root;
	GetRootPart(root);

	CPath	notRoot;
	Right(Length() - root.Length(), notRoot);

	CPath	server;
	GetServerPart(server);

	CPath	share;
	GetSharePart(share);

	CPath	newRoot;

	// check equality of computer name manually, NetShareGetInfo is flaky
	CString	computerName;
	DWORD	maxCNSize	= MAX_COMPUTERNAME_LENGTH + 1;

	GetComputerName(computerName.GetBuffer(maxCNSize), &maxCNSize);

	if (!server.CompareNoCase(computerName))
		return;
		
	if (UWinVersion::IsWin95Compatible())
	{
		share.Uppercase();	// must be uppercase

		PGPUInt32	bufSize	= sizeof(share_info_50) + MAX_PATH + 
			MAXCOMMENTSZ + 2;

		CArray<PGPByte>	shareInfoBuf(bufSize);
		share_info_50	*pSI50	= reinterpret_cast<share_info_50 *>(
			shareInfoBuf.Get());

		unsigned short	cbTotalAvail;
		PGPUInt32		result	= Win95_NetShareGetInfo(NULL, share, 50, 
			reinterpret_cast<char *>(pSI50), bufSize, &cbTotalAvail);

		if (result != NERR_Success)
			THROW_ERRORS(kPGPError_NetworkOpFailed, result);

		newRoot = pSI50->shi50_path;
	}
	else if (UWinVersion::IsWinNT4Compatible())
	{

		CArray<WCHAR>	uniServer;
		UUnicode::AsciiToUni(server, uniServer);

		CArray<WCHAR>	uniSharePath;
		UUnicode::AsciiToUni(share, uniSharePath);

		SHARE_INFO_2	*pSI2;
		PGPUInt32		result	= WinNT_NetShareGetInfo(uniServer.Get(), 
			uniSharePath.Get(), 2, reinterpret_cast<LPBYTE *>(&pSI2));

		if (result != NERR_Success)
			THROW_ERRORS(kPGPError_NetworkOpFailed, result);

		UUnicode::UniToAscii(pSI2->shi2_path, newRoot);
		WinNT_NetApiBufferFree(pSI2);
	}

	Assign(newRoot);
	EndInSlash();
	Append(notRoot);
}

void 
CPath::ResolveLoopBackPath()
{
	try
	{
		if (IsNetworkedPath())
		{
			if (!IsUNCPath())
				ResolveLocalToUNC();

			ResolveUNCToLocal();
		}
	}
	catch (CComboError&) { }
}

void 
CPath::ResolveShortCut()
{
	pgpAssert(IsShortCut());

	PGPUInt32	result;
 
	// Load COM.
	CComLibrary	comLibrary;

	// Get a pointer to the IShellLink interface.
	CComObject<IShellLink>	pShellLink(CLSID_ShellLink, NULL, 
		CLSCTX_INPROC_SERVER, IID_IShellLink);

	// Get a pointer to the IPersistFile interface.
	CComObject<IPersistFile>	pIPF(static_cast<IPersistFile *>(
		pShellLink.QueryInterface(IID_IPersistFile)));

	// Ensure that the string is Unicode.
	CArray<WCHAR>	uniSCPath;
	UUnicode::AsciiToUni(Get(), uniSCPath);

	// Load the shortcut.
	result = pIPF->Load(uniSCPath.Get(), STGM_READ);

	if (result != S_OK)
		THROW_ERRORS(kPGPError_Win32COMOpFailed, result);

	// Resolve the link.
	result = pShellLink->Resolve(GetDesktopWindow(), SLR_ANY_MATCH);

	if (result != NOERROR)
		THROW_ERRORS(kPGPError_Win32COMOpFailed, result);

	// Get the path to the link target.
	WIN32_FIND_DATA	WFD;

	result = pShellLink->GetPath(GetBuffer(PFLConstants::kMaxPathLength), 
		PFLConstants::kMaxPathLength, &WFD, SLGP_SHORTPATH);
	ReleaseBuffer();

	if (result != NOERROR)
		THROW_ERRORS(kPGPError_Win32COMOpFailed, result);
}

void 
CPath::Canonicalize(const char *extension)
{
	FixSlashes();

	if (IsShortCut())
		ResolveShortCut();

	if (IsValidDirectory())
		EndInSlash();

	// If looped back, resolve it a to local path. This check WILL fail
	// under non-Admin accounts under NT, we take care of that later.

	ResolveLoopBackPath();

	// Fill out filename if this is a file.
	if (!IsValidDirectory())
	{
		CPath	dir;
		GetDirPartSmart(dir);

		CPath	bareName;
		GetFileNamePart(bareName);

		char *pFilePart;

		if (!::SearchPath(dir, bareName, extension, 
			PFLConstants::kMaxPathLength, 
			GetBuffer(PFLConstants::kMaxPathLength), &pFilePart))
		{
			ReleaseBuffer();
			THROW_PGPERROR(kPGPError_FileNotFound);
		}

		ReleaseBuffer();
	}

	// Convert to long pathname form.
	ConvertPathToLong();
}

PGPBoolean 
CPath::FindFirstFile(CPath& fileName)
{
	pgpAssert(!FindInProgress());

	WIN32_FIND_DATA	findData;
	mFindHandle	= ::FindFirstFile(Get(), &findData);

	if (mFindHandle == INVALID_HANDLE_VALUE)
		return FALSE;

	fileName = findData.cFileName;
	return TRUE;
}

PGPBoolean 
CPath::FindNextFile(CPath& fileName)
{
	pgpAssert(FindInProgress());

	WIN32_FIND_DATA	findData;

	if (!::FindNextFile(mFindHandle, &findData))
		return FALSE;

	fileName = findData.cFileName;
	return TRUE;
}

void 
CPath::FindClose()
{
	pgpAssert(FindInProgress());

	::FindClose(mFindHandle);
	mFindHandle = INVALID_HANDLE_VALUE;
}

void 
CPath::AssignCurrentDirectory()
{
	PGPUInt32	result	= GetCurrentDirectory(PFLConstants::kMaxPathLength, 
		GetBuffer(PFLConstants::kMaxPathLength));
	ReleaseBuffer();

	if (result == 0)
		THROW_ERRORS(kPGPError_FileOpFailed, result);
}

void 
CPath::BroadcastDriveMessage(WPARAM msg) const
{
	pgpAssert(HasPlainLocalRoot());

	DEV_BROADCAST_VOLUME	DBV;
	PGPInt32				result;

	DBV.dbcv_size		= sizeof(DBV); 
	DBV.dbcv_devicetype = DBT_DEVTYP_VOLUME; 
	DBV.dbcv_reserved	= 0;
	DBV.dbcv_unitmask	= 1 << GetDriveNum();
	DBV.dbcv_flags		= 0; // MS says this should be zero instead of DBTF_MEDIA; wjb

	result = UDynLink::BroadcastSystemMessage(
		BSF_IGNORECURRENTTASK | BSF_POSTMESSAGE, NULL, WM_DEVICECHANGE, msg, 
		reinterpret_cast<LPARAM>(&DBV));

	if (result < 1)
		THROW_PGPERROR(kPGPError_Win32WindowOpFailed);
}

void 
CPath::MakePlainLocalRoot(PGPUInt8 drive)
{
	Format("%c:\\", UString::NumberToLetter(drive));
}

void 
CPath::RecurseCreateDir()
{
	CPath	prefix;
	GetRootPart(prefix);

	CPath	postfix;
	Right(Length() - prefix.Length(), postfix);

	postfix.EndInSlash();

	CPath	fullDir	= prefix;

	while (!postfix.IsEmpty())
	{
		PGPInt32	nextSlash	= postfix.Find(kBackSlash);

		CPath	curDir;
		postfix.Left(nextSlash + 1, curDir);

		fullDir += curDir;

		if (!fullDir.IsValidDirectory() && !CreateDirectory(fullDir, NULL))
			THROW_ERRORS(kPGPError_FileOpFailed, GetLastError());

		CPath	temp;

		postfix.Right(postfix.Length() - nextSlash - 1, temp);
		postfix = temp;
	}
}

void 
CPath::Browse() const
{
	SHELLEXECUTEINFO	sei;
	pgpClearMemory(&sei, sizeof(sei));

	sei.cbSize = sizeof(sei);
	sei.fMask = SEE_MASK_FLAG_NO_UI;
	sei.lpVerb = "explore";
	sei.lpFile = Get();
	sei.nShow = SW_SHOWNORMAL;

	ShellExecuteEx(&sei);
}

PGPBoolean 
CPath::AreShowingExtensions()
{
	CPath	appPath;

	// Get the pathname of the application.
	PGPUInt32	result	= GetModuleFileName(NULL, appPath.GetBuffer(
		PFLConstants::kMaxPathLength), PFLConstants::kMaxPathLength);
	appPath.ReleaseBuffer();

	// Get the display name.
	CPath	displayName;
	appPath.GetDisplayFileName(displayName);

	// Return whether it has an extension.
	return displayName.EndsInExtension();
}

⌨️ 快捷键说明

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