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

📄 inplace.c

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

	if (nStatus != ERR_SUCCESS)
		goto closing_seq;



	// /* If a drive letter is assigned to the device, remove it (so that users do not try to open it, which
	//would cause Windows to ask them if they want to format the volume and other dangerous things). */

	//if (driveLetter >= 0) 
	//{
	//	char rootPath[] = { driveLetter + 'A', ':', '\\', 0 };

	//	// Try to remove the assigned drive letter
	//	if (DeleteVolumeMountPoint (rootPath))
	//		driveLetter = -1;
	//}



	/* Update config files and app data */

	// In the config file, increase the number of partitions where in-place encryption is in progress

	SaveNonSysInPlaceEncSettings (1, wipeAlgorithm);


	// Add the wizard to the system startup sequence if appropriate

	if (!IsNonInstallMode ())
		ManageStartupSeqWiz (FALSE, "/prinplace");


	nStatus = ERR_SUCCESS;


closing_seq:

	dwError = GetLastError();

	if (cryptoInfo != NULL)
	{
		crypto_close (cryptoInfo);
		cryptoInfo = NULL;
	}

	if (cryptoInfo2 != NULL)
	{
		crypto_close (cryptoInfo2);
		cryptoInfo2 = NULL;
	}

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

	if (dosDev[0])
		RemoveFakeDosName (volParams->volumePath, dosDev);

	*outHandle = dev;

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

	return nStatus;
}


int EncryptPartitionInPlaceResume (HANDLE dev,
								   volatile FORMAT_VOL_PARAMETERS *volParams,
								   WipeAlgorithmId wipeAlgorithm,
								   volatile BOOL *bTryToCorrectReadErrors)
{
	PCRYPTO_INFO masterCryptoInfo = NULL, headerCryptoInfo = NULL, tmpCryptoInfo = NULL;
	UINT64_STRUCT unitNo;
	char *buf = NULL, *header = NULL;
	byte *wipeBuffer = NULL;
	byte wipeRandChars [TC_WIPE_RAND_CHAR_COUNT];
	byte wipeRandCharsUpdate [TC_WIPE_RAND_CHAR_COUNT];
	char dosDev[TC_MAX_PATH] = {0};
	char devName[MAX_PATH] = {0};
	WCHAR deviceName[MAX_PATH];
	int nStatus = ERR_SUCCESS;
	__int64 deviceSize;
	uint64 remainingBytes, lastHeaderUpdateDistance = 0, zeroedSectorCount = 0;
	uint32 workChunkSize;
	DWORD dwError, dwResult;
	BOOL bPause = FALSE, bEncryptedAreaSizeChanged = FALSE;
	LARGE_INTEGER offset;
	int sectorSize;
	int i;
	DWORD n;
	char *devicePath = volParams->volumePath;
	Password *password = volParams->password;
	DISK_GEOMETRY driveGeometry;


	bInPlaceEncNonSysResumed = TRUE;

	buf = (char *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE);
	if (!buf)
	{
		nStatus = ERR_OUTOFMEMORY;
		goto closing_seq;
	}

	header = (char *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE);
	if (!header)
	{
		nStatus = ERR_OUTOFMEMORY;
		goto closing_seq;
	}

	VirtualLock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);

	if (wipeAlgorithm != TC_WIPE_NONE)
	{
		wipeBuffer = (byte *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE);
		if (!wipeBuffer)
		{
			nStatus = ERR_OUTOFMEMORY;
			goto closing_seq;
		}
	}

	headerCryptoInfo = crypto_open();

	if (headerCryptoInfo == NULL)
	{
		nStatus = ERR_OUTOFMEMORY;
		goto closing_seq;
	}

	deviceSize = GetDeviceSize (devicePath);
	if (deviceSize < 0)
	{
		// Cannot determine the size of the partition
		nStatus = ERR_OS_ERROR;
		goto closing_seq;
	}

	if (dev == INVALID_HANDLE_VALUE)
	{
		strcpy ((char *)deviceName, devicePath);
		ToUNICODE ((char *)deviceName);

		if (FakeDosNameForDevice (devicePath, dosDev, devName, FALSE) != 0)
		{
			nStatus = ERR_OS_ERROR;
			goto closing_seq;
		}

		dev = OpenPartitionVolume (devName,
			FALSE,	// Do not require exclusive access
			FALSE,	// Do not require shared access
			TRUE,	// Ask the user to confirm shared access (if exclusive fails)
			FALSE,	// Do not append alternative instructions how to encrypt the data (to applicable error messages)
			FALSE);	// Non-silent mode

		if (dev == INVALID_HANDLE_VALUE)
		{
			nStatus = ERR_DONT_REPORT; 
			goto closing_seq;
		}
	}

	// This should never be needed, but is still performed for extra safety (without checking the result)
	DeviceIoControl (dev,
		FSCTL_ALLOW_EXTENDED_DASD_IO,
		NULL,
		0,   
		NULL,
		0,
		&dwResult,
		NULL);


	if (!DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveGeometry, sizeof (driveGeometry), &dwResult, NULL))
	{
		nStatus = ERR_OS_ERROR;
		goto closing_seq;
	}

	sectorSize = driveGeometry.BytesPerSector;


	nStatus = OpenBackupHeader (dev, devicePath, password, &masterCryptoInfo, headerCryptoInfo, deviceSize);

	if (nStatus != ERR_SUCCESS)
		goto closing_seq;



    remainingBytes = masterCryptoInfo->VolumeSize.Value - masterCryptoInfo->EncryptedAreaLength.Value;

	lastHeaderUpdateDistance = 0;


	ExportProgressStats (masterCryptoInfo->EncryptedAreaLength.Value, masterCryptoInfo->VolumeSize.Value / SECTOR_SIZE);

	SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_ENCRYPTING);

	bFirstNonSysInPlaceEncResumeDone = TRUE;


	/* The in-place encryption core */

	while (remainingBytes > 0)
	{
		workChunkSize = (uint32) min (remainingBytes, TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE);

		if (workChunkSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
		{
			nStatus = ERR_PARAMETER_INCORRECT;
			goto closing_seq;
		}

		unitNo.Value = (remainingBytes - workChunkSize + TC_VOLUME_DATA_OFFSET) / ENCRYPTION_DATA_UNIT_SIZE;


		// Read the plaintext into RAM

inplace_enc_read:

		offset.QuadPart = masterCryptoInfo->EncryptedAreaStart.Value - workChunkSize - TC_VOLUME_DATA_OFFSET;

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

		if (ReadFile (dev, buf, workChunkSize, &n, NULL) == 0)
		{
			// Read error

			DWORD dwTmpErr = GetLastError ();

			if (dwTmpErr == ERROR_CRC || dwTmpErr == ERROR_IO_DEVICE)	
			{
				// Physical defect or data corruption

				if (!*bTryToCorrectReadErrors)
				{
					*bTryToCorrectReadErrors = (AskWarnYesNo ("ENABLE_BAD_SECTOR_ZEROING") == IDYES);
				}

				if (*bTryToCorrectReadErrors)
				{
					// Try to correct the read errors physically

					offset.QuadPart = masterCryptoInfo->EncryptedAreaStart.Value - workChunkSize - TC_VOLUME_DATA_OFFSET;

					nStatus = ZeroUnreadableSectors (dev, offset, workChunkSize, sectorSize, &zeroedSectorCount);

					if (nStatus != ERR_SUCCESS)
					{
						// Due to write errors, we can't correct the read errors
						nStatus = ERR_OS_ERROR;
						goto closing_seq;
					}

					goto inplace_enc_read;
				}
			}

			SetLastError (dwTmpErr);		// Preserve the original error code

			nStatus = ERR_OS_ERROR;
			goto closing_seq;
		}

		if (remainingBytes - workChunkSize < TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE)
		{
			// We reached the inital portion of the filesystem, which we had concealed (in order to prevent
			// Windows from interfering with the volume). Now we need to undo that modification. 

			for (i = 0; i < TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE - (remainingBytes - workChunkSize); i++)
				buf[i] ^= TC_NTFS_CONCEAL_CONSTANT;
		}


		// Encrypt the plaintext in RAM

		EncryptDataUnits ((byte *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo);


		// If enabled, wipe the area to which we will write the ciphertext

		if (wipeAlgorithm != TC_WIPE_NONE)
		{
			byte wipePass;

			offset.QuadPart = masterCryptoInfo->EncryptedAreaStart.Value - workChunkSize;

			for (wipePass = 1; wipePass <= GetWipePassCount (wipeAlgorithm); ++wipePass)
			{
				if (!WipeBuffer (wipeAlgorithm, wipeRandChars, wipePass, wipeBuffer, workChunkSize))
				{
					ULONG i;
					for (i = 0; i < workChunkSize; ++i)
					{
						wipeBuffer[i] = buf[i] + wipePass;
					}

					EncryptDataUnits (wipeBuffer, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo);
					memcpy (wipeRandCharsUpdate, wipeBuffer, sizeof (wipeRandCharsUpdate)); 
				}

				if (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0
					|| WriteFile (dev, wipeBuffer, workChunkSize, &n, NULL) == 0)
				{
					// Write error
					dwError = GetLastError();

					// Undo failed write operation
					if (workChunkSize > TC_VOLUME_DATA_OFFSET && SetFilePointerEx (dev, offset, NULL, FILE_BEGIN))
					{
						DecryptDataUnits ((byte *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo);
						WriteFile (dev, buf + TC_VOLUME_DATA_OFFSET, workChunkSize - TC_VOLUME_DATA_OFFSET, &n, NULL);
					}

					SetLastError (dwError);
					nStatus = ERR_OS_ERROR;
					goto closing_seq;
				}
			}

			memcpy (wipeRandChars, wipeRandCharsUpdate, sizeof (wipeRandCharsUpdate)); 
		}


		// Write the ciphertext

		offset.QuadPart = masterCryptoInfo->EncryptedAreaStart.Value - workChunkSize;

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

		if (WriteFile (dev, buf, workChunkSize, &n, NULL) == 0)
		{
			// Write error
			dwError = GetLastError();

			// Undo failed write operation
			if (workChunkSize > TC_VOLUME_DATA_OFFSET && SetFilePointerEx (dev, offset, NULL, FILE_BEGIN))
			{
				DecryptDataUnits ((byte *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo);
				WriteFile (dev, buf + TC_VOLUME_DATA_OFFSET, workChunkSize - TC_VOLUME_DATA_OFFSET, &n, NULL);
			}

			SetLastError (dwError);
			nStatus = ERR_OS_ERROR;
			goto closing_seq;
		}


		masterCryptoInfo->EncryptedAreaStart.Value -= workChunkSize;
		masterCryptoInfo->EncryptedAreaLength.Value += workChunkSize;

		remainingBytes -= workChunkSize;
		lastHeaderUpdateDistance += workChunkSize;

		bEncryptedAreaSizeChanged = TRUE;

		if (lastHeaderUpdateDistance >= TC_NONSYS_INPLACE_ENC_HEADER_UPDATE_INTERVAL)
		{
			nStatus = FastVolumeHeaderUpdate (dev, headerCryptoInfo, masterCryptoInfo, deviceSize);

			if (nStatus != ERR_SUCCESS)
				goto closing_seq;

			lastHeaderUpdateDistance = 0;
		}

		ExportProgressStats (masterCryptoInfo->EncryptedAreaLength.Value, masterCryptoInfo->VolumeSize.Value / SECTOR_SIZE);

		if (bVolTransformThreadCancel)
		{
			bPause = TRUE;
			break;
		}
	}

	nStatus = FastVolumeHeaderUpdate (dev, headerCryptoInfo, masterCryptoInfo, deviceSize);


	if (nStatus != ERR_SUCCESS)
		goto closing_seq;


	if (!bPause)
	{
		/* The data area has been fully encrypted; create and write the primary volume header */

		SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_FINALIZING);

		nStatus = CreateVolumeHeaderInMemory (FALSE,
			header,
			headerCryptoInfo->ea,
			headerCryptoInfo->mode,
			password,
			masterCryptoInfo->pkcs5,
			(char *) masterCryptoInfo->master_keydata,
			&tmpCryptoInfo,
			masterCryptoInfo->VolumeSize.Value,
			0,
			masterCryptoInfo->EncryptedAreaStart.Value,
			masterCryptoInfo->EncryptedAreaLength.Value,
			masterCryptoInfo->RequiredProgramVersion,
			masterCryptoInfo->HeaderFlags | TC_HEADER_FLAG_NONSYS_INPLACE_ENC,
			FALSE);

		if (nStatus != ERR_SUCCESS)
			goto closing_seq;


		offset.QuadPart = TC_VOLUME_HEADER_OFFSET;

		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;
		}

		// Fill the reserved sectors of the header area with random data
		nStatus = WriteRandomDataToReservedHeaderAreas (dev, headerCryptoInfo, masterCryptoInfo->VolumeSize.Value, TRUE, FALSE);

		if (nStatus != ERR_SUCCESS)
			goto closing_seq;


		// Update the configuration files

		SaveNonSysInPlaceEncSettings (-1, wipeAlgorithm);



		SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_FINISHED);

		nStatus = ERR_SUCCESS;
	}
	else
	{
		// The process has been paused by the user or aborted by the wizard (e.g. on app exit)

		nStatus = ERR_USER_ABORT;

		SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_PAUSED);
	}


closing_seq:

	dwError = GetLastError();

	if (bEncryptedAreaSizeChanged
		&& dev != INVALID_HANDLE_VALUE
		&& masterCryptoInfo != NULL
		&& headerCryptoInfo != NULL
		&& deviceSize > 0)
	{
		// Execution of the core loop may have been interrupted due to an error or user action without updating the header
		FastVolumeHeaderUpdate (dev, headerCryptoInfo, masterCryptoInfo, deviceSize);
	}

	if (masterCryptoInfo != NULL)
	{
		crypto_close (masterCryptoInfo);
		masterCryptoInfo = NULL;
	}

	if (headerCryptoInfo != NULL)
	{
		crypto_close (headerCryptoInfo);
		headerCryptoInfo = NULL;
	}

	if (tmpCryptoInfo != NULL)
	{
		crypto_close (tmpCryptoInfo);
		tmpCryptoInfo = NULL;
	}

	if (dosDev[0])
		RemoveFakeDosName (devicePath, dosDev);

	if (dev != INVALID_HANDLE_VALUE)
	{
		CloseHandle (dev);
		dev = INVALID_HANDLE_VALUE;
	}

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

	if (header != NULL)
	{
		burn (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
		VirtualUnlock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
		TCfree (header);
	}

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

	if (zeroedSectorCount > 0)
	{
		wchar_t msg[30000] = {0};
		wchar_t sizeStr[500] = {0};

		GetSizeString (zeroedSectorCount * sectorSize, sizeStr);

		wsprintfW (msg, 
			GetString ("ZEROED_BAD_SECTOR_COUNT"),
			zeroedSectorCount,
			sizeStr);

		WarningDirect (msg);
	}

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

	return nStatus;
}


int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_INFO *masterCryptoInfo, __int64 deviceSize)
{
	LARGE_INTEGER offset;
	DWORD n;
	int nStatus = ERR_SUCCESS;
	byte *header;
	DWORD dwError;
	uint32 headerCrc32;
	byte *fieldPos;

	header = (byte *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE);

	if (!header)
		return ERR_OUTOFMEMORY;

	VirtualLock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE);


	fieldPos = (byte *) header + TC_HEADER_OFFSET_ENCRYPTED_AREA_START;

	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;
	}


	DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);

⌨️ 快捷键说明

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