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

📄 cpgpdiskdiskimp.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	const char				*path,
	const CPGPdiskUser&		diskUser,
	const char				*root,
	PGPBoolean				readOnly)
{
	if (!diskUser.IsCipheringEnabled())
		THROW_PGPERROR(kPGPError_BadParams);

	// Get cipher context of user.
	CCipherContext	cipher;
	diskUser.GetCipherContext(cipher);

	Mount(pContext, path, cipher, root, readOnly || diskUser.IsReadOnly());
}

void
CPGPdiskDiskImp::Mount(
	const CPGPdiskContext	*pContext,
	const char				*path,
	const CCipherContext&	cipher,
	const char				*root,
	PGPBoolean				readOnly)
{
	pgpAssertAddrValid(pContext, CPGPdiskContext);
	pgpAssertStrValid(path);
	pgpAssertStrValid(root);

	if (IsMounted() || IsOpened())
		THROW_PGPERROR(kPGPError_FeatureNotAvailable);

	// Open the PGPdisk file.
	PGPUInt32	openFlags	= CFile::kNoFlags;

	if (readOnly)
		openFlags |= CFile::kReadOnlyFlag;

	mDiskFile.Open(path, openFlags);

	try
	{
		// Read in list of headers.
		mHeaders.ReadHeaders(pContext, mDiskFile);

		if (IsBeingReEncrypted())
			THROW_PGPERROR(kPGPClientError_DiskDiskIsBeingReEncrypted);

		// Perform filesystem compatibility checks (forcing RO if needed).
		CheckFilesystemCompatibility(cipher, readOnly);

		// Save some information.
		PGPUInt64	numHeaderBlocks	= mHeaders.NumHeaderBlocks();
		PGPUInt64	numDataBlocks	= mHeaders.NumDataBlocks();

		// Close the PGPdisk file in preparation for mounting.
		if (!readOnly)
		{
			mHeaders.SetDefaultRoot(root);
			mHeaders.WriteHeaders(mDiskFile);
		}

		mDiskFile.Close();

		// Get exported key data in locked memory.
		CArray<PGPUInt8>	exportedContext(cipher.GetSizeForExport());
		cipher.Export(exportedContext.Get(), exportedContext.Size());

		// Perform the mount.
		CEngineSubsystems::DriverComm().Mount(path, root,
			cipher.Algorithm(), exportedContext.Get(),
			exportedContext.Size(), numHeaderBlocks, numDataBlocks,
			mDeviceName, readOnly);

		// set timeout
		try
		{
			if (UsesCustomTimeout())
			{
				CEngineSubsystems::DriverComm().SetTimeout(root,
					CustomTimeout());
			}
			else
			{
				PGPBoolean	autoUnmount		= pContext->PGPclPrefs().
					GetBoolean(kPGPPrefDiskUnmountOnInactivity);
				PGPUInt32	unmountTimeout	= pContext->PGPclPrefs().
					GetNumber(kPGPPrefDiskAutoUnmountTimeout);

				if (autoUnmount)
				{
					CEngineSubsystems::DriverComm().SetTimeout(root,
						unmountTimeout);
				}
			}
		}
		catch (CComboError&) {}

		mPContext = pContext;
		mIsReadOnly = readOnly;
		mPath = path;
		mRoot = root;

		mDiskState = kDiskStateMounted;
	}
	catch (CComboError&)
	{
		if (IsOpened())
			Close();
		throw;
	}
}

void
CPGPdiskDiskImp::Unmount(PGPBoolean isForced)
{
	if (!IsMounted())
		THROW_PGPERROR(kPGPError_FeatureNotAvailable);

	if (IsLockedForFormat() || IsLockedForIO())
		UnlockVolume();

	// Perform the unmount.
	CString	savedRoot(Root());

	CEngineSubsystems::DriverComm().Unmount(Root(), isForced);

	// Clear headers.
	mHeaders.ClearHeaders();

	mPContext = NULL;
	mPath.Empty();
	mRoot.Empty();

	mDiskState = kDiskStateNone;
}

void
CPGPdiskDiskImp::Create(
	const CPGPdiskContext		*pContext,
	const char					*path,
	PGPUInt64					blocksDisk,
	PGPdiskEncryptionAlgorithm	algorithm,
	const char					*adminPassphrase,
	const char					*userName,
	const char					*defaultRoot,
	NewDiskStatusFuncType		statusFunc,
	void						*userValue)
{
	if (IsMounted() || IsOpened())
		THROW_PGPERROR(kPGPError_FeatureNotAvailable);

	CreateCommon(pContext, path, blocksDisk, algorithm, adminPassphrase,
		userName, NULL, defaultRoot, statusFunc, userValue);
}

void
CPGPdiskDiskImp::Create(
	const CPGPdiskContext		*pContext,
	const char					*path,
	PGPUInt64					blocksDisk,
	PGPdiskEncryptionAlgorithm	algorithm,
	const CPGPKey&				pubKey,
	const char					*defaultRoot,
	NewDiskStatusFuncType		statusFunc,
	void						*userValue)
{
	if (IsMounted() || IsOpened())
		THROW_PGPERROR(kPGPError_FeatureNotAvailable);

	CreateCommon(pContext, path, blocksDisk, algorithm, NULL, NULL, &pubKey,
		defaultRoot, statusFunc, userValue);
}

void
CPGPdiskDiskImp::EncryptNewPGPdiskFile(
	const CCipherContext&	cipher,
	NewDiskStatusFuncType	statusFunc,
	void					*userValue)
{
	pgpAssert(!IsMounted());
	pgpAssert(!IsOpened());
	pgpAssert(mDiskFile.IsOpened());
	pgpAssert(cipher.IsKeyAttached());

	// Get the memory for our data buffer.
	CArray<PGPUInt8>	dataBuf(kBlocksPerWrite * kPGPdiskBlockSize);

	// Calculate the starting and ending blocks.
	PGPUInt64	startBlock	= mHeaders.NumHeaderBlocks();
	PGPUInt64	endBlock	= startBlock + mHeaders.NumDataBlocks();

	// Calculate information used for progress updates.
	PGPUInt32	totalWrites	= static_cast<PGPUInt32>(
		UMath::CeilDiv<PGPUInt64>(endBlock - startBlock, kBlocksPerWrite));

	PGPUInt32	writesDone		= 0;
	PGPUInt32	writesPerUpdate	= static_cast<PGPUInt32>(
		UMath::CeilDiv<PGPUInt64>(totalWrites, 100));

	// Encrypt the PGPdisk.
	for (PGPUInt64 i = startBlock; i < endBlock; i += kBlocksPerWrite)
	{
		PGPUInt32	blocksThisTime	= static_cast<PGPUInt32>(
			pgpMin(kBlocksPerWrite, endBlock - i));

		dataBuf.Wipe();

		// Encrypt the blocks and output them.
		cipher.EncryptCFB(i - startBlock, blocksThisTime, dataBuf.Get(),
			dataBuf.Get());

		mDiskFile.Write(dataBuf.Get(), i * kPGPdiskBlockSize,
			blocksThisTime * kPGPdiskBlockSize);

		// Call the progress function.
		PGPBoolean	continueCreate	= TRUE;

		if (writesDone++ % writesPerUpdate == 0)
		{
			continueCreate = statusFunc(FALSE, writesDone*100/totalWrites,
				userValue);
		}

		if (!continueCreate)
			THROW_PGPERROR(kPGPError_UserAbort);
	}

	statusFunc(FALSE, 100, userValue);
}

void
CPGPdiskDiskImp::CreateCommon(
	const CPGPdiskContext		*pContext,
	const char					*path,
	PGPUInt64					blocksDisk,
	PGPdiskEncryptionAlgorithm	algorithm,
	const char					*adminPass,
	const char					*userName,
	const CPGPKey				*pPubKey,
	const char					*defaultRoot,
	NewDiskStatusFuncType		statusFunc,
	void						*userValue)
{
	pgpAssertAddrValid(pContext, CPGPdiskContext);
	pgpAssert(blocksDisk > 0);
	pgpAssertStrValid(defaultRoot);
	pgpAssertAddrValid(statusFunc, NewDiskStatusFuncType);

	if (IsMounted() || IsOpened())
		THROW_PGPERROR(kPGPError_FeatureNotAvailable);

	mPContext = pContext;

	// Private key of public key must be present and usable
	if (IsntNull(pPubKey))
	{
		pgpAssertAddrValid(pPubKey, CPGPKey);

		if (!pPubKey->GetBooleanProp(kPGPKeyProperty_CanDecrypt))
			THROW_PGPERROR(kPGPClientError_BadDiskPassphrase);
	}

	try
	{
		mDiskFile.Open(path, CFile::kCreateIfFlag);
		mDiskFile.SetLength(0);

		// It's important we don't write out the headers until we're done
		// encrypting all the new disk - else we wait ages for NTFS to zero
		// out the new disk file when we write the admin user header to the
		// end of the disk.

		CCipherContext	cipher;

		if (IsntNull(pPubKey))
		{
			mHeaders.CreateHeaders(Context(), mDiskFile, blocksDisk,
				algorithm, *pPubKey, defaultRoot, cipher);
		}
		else
		{
			mHeaders.CreateHeaders(Context(), mDiskFile, blocksDisk,
				algorithm, adminPass, userName, defaultRoot, cipher);
		}

		mDiskFile.SetLength(mHeaders.NumFileBlocks() * kPGPdiskBlockSize);
		EncryptNewPGPdiskFile(cipher, statusFunc, userValue);
		mHeaders.WriteHeaders(mDiskFile);

		mPContext = pContext;
		mIsReadOnly = FALSE;
		mPath = path;
		mRoot.Empty();

		mDiskFile.Close();

		// Mount the disk.
/*		PGPBoolean	oldBrowsePref;

		try
		{
			// gets around a spurious Win2k warning dialog
			oldBrowsePref = mPContext->PGPclPrefs().GetBoolean(
				kPGPPrefDiskBrowseAfterMount);
			mPContext->PGPclPrefs().SetBoolean(kPGPPrefDiskBrowseAfterMount, 
				FALSE);
		}
		catch (CComboError&) { }*/
		
		Mount(pContext, path, cipher, defaultRoot, FALSE);

/*		try
		{
			mPContext->PGPclPrefs().SetBoolean(kPGPPrefDiskBrowseAfterMount, 
				oldBrowsePref);
		}
		catch (CComboError&) { }*/
	}
	catch (CComboError&)
	{
		mHeaders.ClearHeaders();

		if (mDiskFile.IsOpened())
			mDiskFile.Close();

		// work around warn on delete
		CString temp(path);
		temp += "not";

		CFile	deleter;

		deleter.Move(path, temp);
		deleter.Delete(temp);
		throw;
	}
}

void
CPGPdiskDiskImp::ReEncryptBlocks(
	const CCipherContext&		oldCipher,
	const CCipherContext&		newCipher,
	ReEncryptDiskStatusFuncType	statusFunc,
	void						*userValue,
	PGPUInt64					numBlocksReEncrypted)
{
	pgpAssert(IsOpened());
	pgpAssert(oldCipher.IsInitialized());
	pgpAssert(newCipher.IsInitialized());
	pgpAssertAddrValid(statusFunc, ReEncryptDiskStatusFuncType);

	// Get the memory for our data buffer.
	CArray<PGPUInt8>	dataBuf(kBlocksPerWrite * kPGPdiskBlockSize);

	// Calculate the starting and ending blocks.
	PGPUInt64	firstBlock	= mHeaders.NumHeaderBlocks();
	PGPUInt64	startBlock	= firstBlock + numBlocksReEncrypted;
	PGPUInt64	endBlock	= firstBlock +mHeaders.NumDataBlocks();

	// Calculate information used for progress updates.
	PGPUInt32	totalWrites	= static_cast<PGPUInt32>(
		UMath::CeilDiv<PGPUInt64>(mHeaders.NumDataBlocks(),
		kBlocksPerWrite));

	PGPUInt32	writesDone	= static_cast<PGPUInt32>(
		(totalWrites * numBlocksReEncrypted) / mHeaders.NumDataBlocks());
	PGPUInt32	writesPerUpdate	= UMath::CeilDiv<PGPUInt32>(totalWrites,
		100);

	// Re-encrypt the PGPdisk.
	for (PGPUInt64 i = startBlock; i < endBlock; i += kBlocksPerWrite)
	{
		PGPUInt32	blocksThisTime	= static_cast<PGPUInt32>(
			pgpMin(kBlocksPerWrite, endBlock - i));

		dataBuf.Wipe();

		// Read in the old blocks.
		mDiskFile.Read(dataBuf.Get(), i * kPGPdiskBlockSize,
			blocksThisTime * kPGPdiskBlockSize);

		// Decrypt the blocks using the old algorithm.
		oldCipher.DecryptCFB(i - firstBlock, blocksThisTime, dataBuf.Get(),
			dataBuf.Get());

		// Encrypt the blocks using the new algorithm.
		newCipher.EncryptCFB(i - firstBlock, blocksThisTime, dataBuf.Get(),
			dataBuf.Get());

		// Write out the newly ReEncrypted blocks.
		mDiskFile.Write(dataBuf.Get(), i * kPGPdiskBlockSize,
			blocksThisTime * kPGPdiskBlockSize);

		// Write out now the # of the last ReEncrypted block.
		numBlocksReEncrypted += blocksThisTime;
		mHeaders.WriteReEncryptionProgress(mDiskFile, numBlocksReEncrypted);

		// Call the progress function.
		PGPBoolean	continueReEncrypt	= TRUE;

		if (writesDone++ % writesPerUpdate == 0)
		{
			continueReEncrypt = statusFunc(writesDone*100/totalWrites,
				userValue);
		}

		if (!continueReEncrypt)
			THROW_PGPERROR(kPGPError_UserAbort);
	}

	statusFunc(100, userValue);
}

⌨️ 快捷键说明

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