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

📄 inplace.c

📁 使用visual studio 2005 开发的开源文件、磁盘加密软件。这是6.1a版。加密自己资料的好工具。也是学习的优秀范本。结成了众多加密算法。
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x54525545)
	{
		nStatus = ERR_PARAMETER_INCORRECT;
		goto closing_seq;
	}

	mputInt64 (fieldPos, (masterCryptoInfo->EncryptedAreaStart.Value));
	mputInt64 (fieldPos, (masterCryptoInfo->EncryptedAreaLength.Value));


	headerCrc32 = GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
	fieldPos = (byte *) header + TC_HEADER_OFFSET_HEADER_CRC;
	mputLong (fieldPos, headerCrc32);

	EncryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);


	if (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0
		|| WriteFile (dev, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE, &n, NULL) == 0)
	{
		nStatus = ERR_OS_ERROR;
		goto closing_seq;
	}


closing_seq:

	dwError = GetLastError();

	burn (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
	VirtualUnlock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
	TCfree (header);

	if (nStatus != ERR_SUCCESS)
		SetLastError (dwError);

	return nStatus;
}


static HANDLE OpenPartitionVolume (const char *devName,
							 BOOL bExclusiveRequired,
							 BOOL bSharedRequired,
							 BOOL bSharedRequiresConfirmation,
							 BOOL bShowAlternativeSteps,
							 BOOL bSilent)
{
	HANDLE dev = INVALID_HANDLE_VALUE;
	int retryCount = 0;

	if (bExclusiveRequired)
		bSharedRequired = FALSE;

	if (bExclusiveRequired || !bSharedRequired)
	{
		// Exclusive access
		// Note that when exclusive access is denied, it is worth retrying (usually succeeds after a few tries).
		while (dev == INVALID_HANDLE_VALUE && retryCount++ < EXCL_ACCESS_MAX_AUTO_RETRIES)
		{
			dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL);

			if (retryCount > 1)
				Sleep (EXCL_ACCESS_AUTO_RETRY_DELAY);
		}
	}

	if (dev == INVALID_HANDLE_VALUE)
	{
		if (bExclusiveRequired)
		{
			if (!bSilent)
			{
				handleWin32Error (MainDlg);

				if (bShowAlternativeSteps)
					ShowInPlaceEncErrMsgWAltSteps ("INPLACE_ENC_CANT_ACCESS_OR_GET_INFO_ON_VOL_ALT", TRUE);
				else
					Error ("INPLACE_ENC_CANT_ACCESS_OR_GET_INFO_ON_VOL");
			}
			return INVALID_HANDLE_VALUE;
		}

		// Shared mode
		dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL);
		if (dev != INVALID_HANDLE_VALUE)
		{
			if (bSharedRequiresConfirmation 
				&& !bSilent
				&& AskWarnNoYes ("DEVICE_IN_USE_INPLACE_ENC") == IDNO)
			{
				CloseHandle (dev);
				return INVALID_HANDLE_VALUE;
			}
		}
		else
		{
			if (!bSilent)
			{
				handleWin32Error (MainDlg);

				if (bShowAlternativeSteps)
					ShowInPlaceEncErrMsgWAltSteps ("INPLACE_ENC_CANT_ACCESS_OR_GET_INFO_ON_VOL_ALT", TRUE);
				else
					Error ("INPLACE_ENC_CANT_ACCESS_OR_GET_INFO_ON_VOL");
			}
			return INVALID_HANDLE_VALUE;
		}
	}

	return dev;
}


static int DismountFileSystem (HANDLE dev,
					int driveLetter,
					BOOL bForcedAllowed,
					BOOL bForcedRequiresConfirmation,
					BOOL bSilent)
{
	int attempt;
	BOOL bResult;
	DWORD dwResult;

	CloseVolumeExplorerWindows (MainDlg, driveLetter);

	attempt = UNMOUNT_MAX_AUTO_RETRIES * 10;

	while (!(bResult = DeviceIoControl (dev, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwResult, NULL)) 
		&& attempt > 0)
	{
		Sleep (UNMOUNT_AUTO_RETRY_DELAY);
		attempt--;
	}

	if (!bResult)
	{
		if (!bForcedAllowed)
		{
			if (!bSilent)
				ShowInPlaceEncErrMsgWAltSteps ("INPLACE_ENC_CANT_LOCK_OR_DISMOUNT_FILESYS", TRUE);

			return ERR_DONT_REPORT;
		}

		if (bForcedRequiresConfirmation
			&& !bSilent
			&& AskWarnYesNo ("VOL_LOCK_FAILED_OFFER_FORCED_DISMOUNT") == IDNO)
		{
			return ERR_DONT_REPORT;
		}
	}

	// Dismount the volume

	attempt = UNMOUNT_MAX_AUTO_RETRIES * 10;

	while (!(bResult = DeviceIoControl (dev, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwResult, NULL)) 
		&& attempt > 0)
	{
		Sleep (UNMOUNT_AUTO_RETRY_DELAY);
		attempt--;
	}

	if (!bResult)
	{
		if (!bSilent)
			ShowInPlaceEncErrMsgWAltSteps ("INPLACE_ENC_CANT_LOCK_OR_DISMOUNT_FILESYS", TRUE);

		return ERR_DONT_REPORT; 
	}

	return ERR_SUCCESS; 
}


// Easy-to-undo modification applied to conceal the NTFS filesystem (to prevent Windows and apps from 
// interfering with it until the volume has been fully encrypted). Note that this function will precisely
// undo any modifications it made to the filesystem automatically if an error occurs when writing (including
// physical drive defects).
static int ConcealNTFS (HANDLE dev)
{
	char buf [TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE];
	DWORD nbrBytesProcessed, nbrBytesProcessed2;
	int i;
	LARGE_INTEGER offset;
	DWORD dwError;

	offset.QuadPart = 0;
 
	if (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0)
		return ERR_OS_ERROR;

	if (ReadFile (dev, buf, TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE, &nbrBytesProcessed, NULL) == 0)
		return ERR_OS_ERROR;

	for (i = 0; i < TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE; i++)
		buf[i] ^= TC_NTFS_CONCEAL_CONSTANT;

	offset.QuadPart = 0;

	if (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0)
		return ERR_OS_ERROR;

	if (WriteFile (dev, buf, TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE, &nbrBytesProcessed, NULL) == 0)
	{
		// One or more of the sectors is/are probably damaged and cause write errors.
		// We must undo the modifications we made.

		dwError = GetLastError();

		for (i = 0; i < TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE; i++)
			buf[i] ^= TC_NTFS_CONCEAL_CONSTANT;

		offset.QuadPart = 0;

		do
		{
			Sleep (1);
		}
		while (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0
			|| WriteFile (dev, buf, TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE, &nbrBytesProcessed2, NULL) == 0);

		SetLastError (dwError);

		return ERR_OS_ERROR;
	}

	return ERR_SUCCESS;
}


void ShowInPlaceEncErrMsgWAltSteps (char *iniStrId, BOOL bErr)
{
	wchar_t msg[30000];

	wcscpy (msg, GetString (iniStrId));

	wcscat (msg, L"\n\n\n");
	wcscat (msg, GetString ("INPLACE_ENC_ALTERNATIVE_STEPS"));

	if (bErr)
		ErrorDirect (msg);
	else
		WarningDirect (msg);
}


static void ExportProgressStats (__int64 bytesDone, __int64 totalSectors)
{
	NonSysInplaceEncBytesDone = bytesDone;
	NonSysInplaceEncTotalSectors = totalSectors;
}


void SetNonSysInplaceEncUIStatus (int nonSysInplaceEncStatus)
{
	NonSysInplaceEncStatus = nonSysInplaceEncStatus;
}


BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId newWipeAlgorithm)
{
	int count;
	char str[32];
	WipeAlgorithmId savedWipeAlgorithm = TC_WIPE_NONE;

	if (delta == 0)
		return TRUE;

	count = LoadNonSysInPlaceEncSettings (&savedWipeAlgorithm) + delta;

	if (count < 1)
	{
		if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC)))
			remove (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC));

		if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE)))
			remove (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE));

		if (!IsNonInstallMode () && SystemEncryptionStatus == SYSENC_STATUS_NONE)
			ManageStartupSeqWiz (TRUE, "");

		return TRUE;
	}
	else
	{
		if (newWipeAlgorithm != TC_WIPE_NONE)
		{
			sprintf (str, "%d", (int) newWipeAlgorithm);

			SaveBufferToFile (str, GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE), strlen(str), FALSE);
		} 
		else if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE)))
		{
			remove (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE));
		}

		sprintf (str, "%d", count);

		return SaveBufferToFile (str, GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC), strlen(str), FALSE);
	}
}


// Repairs damaged sectors (i.e. those with read errors) by zeroing them. 
// Note that this operating fails if there are any write errors.
int ZeroUnreadableSectors (HANDLE dev, LARGE_INTEGER startOffset, int64 size, int sectorSize, uint64 *zeroedSectorCount)
{
	int nStatus;
	DWORD n;
	int64 sectorCount;
	LARGE_INTEGER workOffset;
	byte *sectorBuffer = NULL;
	DWORD dwError;

	workOffset.QuadPart = startOffset.QuadPart;

	sectorBuffer = (byte *) TCalloc (sectorSize);

	if (!sectorBuffer)
		return ERR_OUTOFMEMORY;

	if (SetFilePointerEx (dev, startOffset, NULL, FILE_BEGIN) == 0)
	{
		nStatus = ERR_OS_ERROR;
		goto closing_seq;
	}


	for (sectorCount = size / sectorSize; sectorCount > 0; --sectorCount)
	{
		if (ReadFile (dev, sectorBuffer, sectorSize, &n, NULL) == 0)
		{
			memset (sectorBuffer, 0, sectorSize);

			if (SetFilePointerEx (dev, workOffset, NULL, FILE_BEGIN) == 0)
			{
				nStatus = ERR_OS_ERROR;
				goto closing_seq;
			}

			if (WriteFile (dev, sectorBuffer, sectorSize, &n, NULL) == 0)
			{
				nStatus = ERR_OS_ERROR;
				goto closing_seq;
			}
			++(*zeroedSectorCount);
		}

		workOffset.QuadPart += n;
	}

	nStatus = ERR_SUCCESS;

closing_seq:

	dwError = GetLastError();

	if (sectorBuffer != NULL)
		TCfree (sectorBuffer);

	if (nStatus != ERR_SUCCESS)
		SetLastError (dwError);

	return nStatus;
}


static int OpenBackupHeader (HANDLE dev, const char *devicePath, Password *password, PCRYPTO_INFO *retMasterCryptoInfo, CRYPTO_INFO *headerCryptoInfo, __int64 deviceSize)
{
	LARGE_INTEGER offset;
	DWORD n;
	int nStatus = ERR_SUCCESS;
	char *header;
	DWORD dwError;

	header = (char *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE);
	if (!header)
		return ERR_OUTOFMEMORY;

	VirtualLock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);



	offset.QuadPart = deviceSize - TC_VOLUME_HEADER_GROUP_SIZE;

	if (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0
		|| ReadFile (dev, header, TC_VOLUME_HEADER_EFFECTIVE_SIZE, &n, NULL) == 0)
	{
		nStatus = ERR_OS_ERROR;
		goto closing_seq;
	}


	nStatus = ReadVolumeHeader (FALSE, header, password, retMasterCryptoInfo, headerCryptoInfo);
	if (nStatus != ERR_SUCCESS)
		goto closing_seq;


closing_seq:

	dwError = GetLastError();

	burn (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
	VirtualUnlock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
	TCfree (header);

	dwError = GetLastError();

	if (nStatus != ERR_SUCCESS)
		SetLastError (dwError);

	return nStatus;
}


static BOOL GetFreeClusterBeforeThreshold (HANDLE volumeHandle, int64 *freeCluster, int64 clusterThreshold)
{
	const int bitmapSize = 65536;
	byte bitmapBuffer[bitmapSize + sizeof (VOLUME_BITMAP_BUFFER)];
	VOLUME_BITMAP_BUFFER *bitmap = (VOLUME_BITMAP_BUFFER *) bitmapBuffer;
	STARTING_LCN_INPUT_BUFFER startLcn;
	startLcn.StartingLcn.QuadPart = 0;

	DWORD bytesReturned;
	while (DeviceIoControl (volumeHandle, FSCTL_GET_VOLUME_BITMAP, &startLcn, sizeof (startLcn), &bitmapBuffer, sizeof (bitmapBuffer), &bytesReturned, NULL)
		|| GetLastError() == ERROR_MORE_DATA)
	{
		for (int64 bitmapIndex = 0; bitmapIndex < min (bitmapSize, (bitmap->BitmapSize.QuadPart / 8)); ++bitmapIndex)
		{
			if (bitmap->StartingLcn.QuadPart + bitmapIndex * 8 >= clusterThreshold)
				goto err;

			if (bitmap->Buffer[bitmapIndex] != 0xff)
			{
				for (int bit = 0; bit < 8; ++bit)
				{
					if ((bitmap->Buffer[bitmapIndex] & (1 << bit)) == 0)
					{
						*freeCluster = bitmap->StartingLcn.QuadPart + bitmapIndex * 8 + bit;

						if (*freeCluster >= clusterThreshold)
							goto err;

						return TRUE;
					}
				}
			}
		}

		startLcn.StartingLcn.QuadPart += min (bitmapSize * 8, bitmap->BitmapSize.QuadPart);
	}
	
err:
	SetLastError (ERROR_DISK_FULL);
	return FALSE;
}


static BOOL MoveClustersBeforeThresholdInDir (HANDLE volumeHandle, const wstring &directory, int64 clusterThreshold)
{
	WIN32_FIND_DATAW findData;

	HANDLE findHandle = FindFirstFileW (((directory.size() <= 3 ? L"" : L"\\\\?\\") + directory + L"\\*").c_str(), &findData);
	if (findHandle == INVALID_HANDLE_VALUE)
		return TRUE;	// Error ignored

	finally_do_arg (HANDLE, findHandle, { FindClose (finally_arg); });

	// Find all files and directories
	do
	{
		if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			wstring subDir = findData.cFileName;

			if (subDir == L"." || subDir == L"..")
				continue;

			if (!MoveClustersBeforeThresholdInDir (volumeHandle, directory + L"\\" + subDir, clusterThreshold))
				return FALSE;
		}

		DWORD access = FILE_READ_ATTRIBUTES;

		if (findData.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED)
			access = FILE_READ_DATA;

		HANDLE fsObject = CreateFileW ((directory + L"\\" + findData.cFileName).c_str(), access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
		if (fsObject == INVALID_HANDLE_VALUE)
			continue;

		finally_do_arg (HANDLE, fsObject, { CloseHandle (finally_arg); });

		STARTING_VCN_INPUT_BUFFER startVcn;
		startVcn.StartingVcn.QuadPart = 0;
		RETRIEVAL_POINTERS_BUFFER retPointers;
		DWORD bytesReturned;

		// Find clusters allocated beyond the threshold
		while (DeviceIoControl (fsObject, FSCTL_GET_RETRIEVAL_POINTERS, &startVcn, sizeof (startVcn), &retPointers, sizeof (retPointers), &bytesReturned, NULL)
			|| GetLastError() == ERROR_MORE_DATA)
		{
			if (retPointers.ExtentCount == 0)
				break;

			if (retPointers.Extents[0].Lcn.QuadPart != -1)
			{
				int64 extentStartCluster = retPointers.Extents[0].Lcn.QuadPart;
				int64 extentLen = retPointers.Extents[0].NextVcn.QuadPart - retPointers.StartingVcn.QuadPart;
				int64 extentEndCluster = extentStartCluster + extentLen - 1;

				if (extentEndCluster >= clusterThreshold)
				{
					// Move clusters before the threshold
					for (int64 movedCluster = max (extentStartCluster, clusterThreshold); movedCluster <= extentEndCluster; ++movedCluster)
					{
						for (int retry = 0; ; ++retry)
						{
							MOVE_FILE_DATA moveData;

							if (GetFreeClusterBeforeThreshold (volumeHandle, &moveData.StartingLcn.QuadPart, clusterThreshold))
							{
								moveData.FileHandle = fsObject;
								moveData.StartingVcn.QuadPart = movedCluster - extentStartCluster + retPointers.StartingVcn.QuadPart;
								moveData.ClusterCount = 1;

								if (DeviceIoControl (volumeHandle, FSCTL_MOVE_FILE, &moveData, sizeof (moveData), NULL, 0, &bytesReturned, NULL))
									break;
							}

							if (retry > 200)
								return FALSE;

							// There are possible race conditions as we work on a live filesystem
							Sleep (100);
						}
					}
				}
			}

			startVcn.StartingVcn = retPointers.Extents[0].NextVcn;
		}

	} while (FindNextFileW (findHandle, &findData));

	return TRUE;
}


BOOL MoveClustersBeforeThreshold (HANDLE volumeHandle, PWSTR volumeDevicePath, int64 clusterThreshold)
{
	int drive = GetDiskDeviceDriveLetter (volumeDevicePath);
	if (drive == -1)
	{
		SetLastError (ERROR_INVALID_PARAMETER);
		return FALSE;
	}

	wstring volumeRoot = L"X:";
	volumeRoot[0] = L'A' + drive;

	return MoveClustersBeforeThresholdInDir (volumeHandle, volumeRoot, clusterThreshold);
}

⌨️ 快捷键说明

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