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

📄 format.c

📁 一个提供档案及Partition作加解密的程式支援以下的加密演算法AESBlowfishCAST5SerpentTriple DESTwofishAES-BlowfishAES-TwofishAES-
💻 C
字号:
/* The source code contained in this file has been derived from the source code
   of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and
   additions to that source code contained in this file are Copyright (c) 2004-2005
   TrueCrypt Foundation and Copyright (c) 2004 TrueCrypt Team. Unmodified
   parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation
   release. Please see the file license.txt for full license details. */

#include "TCdefs.h"

#include "crypto.h"
#include "fat.h"
#include "format.h"
#include "volumes.h"
#include "progress.h"
#include "apidrvr.h"
#include "dlgcode.h"
#include "resource.h"
#include "common.h"
#include "random.h"

int
FormatVolume (char *lpszFilename,
	      BOOL bDevice,
		  char *volumePath,
	      unsigned __int64 size,
		  unsigned __int64 hiddenVolHostSize,
	      char *lpszPassword,
	      int cipher,
	      int pkcs5,
		  BOOL quickFormat,
		  int fileSystem,
		  int clusterSize,
		  char * summaryMsg,
	      HWND hwndDlg,
		  BOOL hiddenVol,
		  int *realClusterSize)
{
	int nStatus;
	PCRYPTO_INFO cryptoInfo;
	HANDLE dev = INVALID_HANDLE_VALUE;
	DWORD dwError, dwThen, dwNow;
	diskio_f write;
	char header[SECTOR_SIZE];
	unsigned __int64 num_sectors, startSector;
	fatparams ft;
	FILETIME ftCreationTime;
	FILETIME ftLastWriteTime;
	FILETIME ftLastAccessTime;
	BOOL bTimeStampValid = FALSE;
	
	if (!hiddenVol)
		size -= HEADER_SIZE;	

	num_sectors = size / SECTOR_SIZE;
	VirtualLock (header, sizeof (header));

	/* Copies any header structures into header, but does not do any
	   disk io */
	nStatus = VolumeWriteHeader (header,
				     cipher,
				     lpszPassword,
				     pkcs5,
					 0,
					 0,
				     &cryptoInfo,
					 hiddenVol ? size : 0);

	if (nStatus != 0)
	{
		burn (header, sizeof (header));
		VirtualUnlock (header, sizeof (header));
		return nStatus;
	}

	write = (diskio_f) _lwrite;

	if (bDevice == TRUE)
	{
		dev = CreateFile (lpszFilename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
		if (dev == INVALID_HANDLE_VALUE)
		{
			// Try opening device in shared mode
			dev = CreateFile (lpszFilename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
			if (dev != INVALID_HANDLE_VALUE)
			{
				if (IDNO == MessageBox (hwndDlg, getstr (IDS_DEVICE_IN_USE_FORMAT), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2))
				{
					CloseHandle (dev);
					dev = INVALID_HANDLE_VALUE;
				}
			}
		}
	}
	else
	{
		// We could support FILE_ATTRIBUTE_HIDDEN as an option
		// (Now if the container has hidden or system file attribute, the OS will not allow
		// overwritting it; so the user will have to delete it manually).
		dev = CreateFile (lpszFilename, GENERIC_WRITE,
			hiddenVol ? (FILE_SHARE_READ | FILE_SHARE_WRITE) : 0,
			NULL, hiddenVol ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);
	}

	if (dev == INVALID_HANDLE_VALUE)
	{
		handleWin32Error (hwndDlg);
		nStatus = ERR_OS_ERROR; goto error;
	}

	if (hiddenVol && !bDevice)
	{
		/* Remember the container timestamp (used to reset file date and time of file-hosted
		containers to preserve plausible deniability of hidden volume)  */
		if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
		{
			bTimeStampValid = FALSE;
			MessageBox (hwndDlg, getstr (IDS_GETFILETIME_FAILED_IMPLANT), "TrueCrypt", MB_OK | MB_ICONEXCLAMATION);
		}
		else
			bTimeStampValid = TRUE;
	}

	KillTimer (hwndDlg, 0xff);

	InitProgressBar (num_sectors);
	dwThen = GetTickCount ();


	//// Volume header

	// Hidden volume setup
	if (hiddenVol)
	{
		// Check hidden volume size
		if (hiddenVolHostSize < MIN_HIDDEN_VOLUME_HOST_SIZE || hiddenVolHostSize > MAX_HIDDEN_VOLUME_HOST_SIZE)
		{		
			nStatus = ERR_VOL_SIZE_WRONG; goto error;
		}

		// Seek to hidden volume header location
		if (!SeekHiddenVolHeader ((HFILE) dev, hiddenVolHostSize, bDevice))
		{
			nStatus = ERR_VOL_SEEKING; goto error;
		}

	}

	// Write the volume header
	if ((*write) ((HFILE) dev, header, HEADER_SIZE) == HFILE_ERROR)
		return ERR_OS_ERROR;


	//// Data area

	startSector = 1;	// Data area of normal volume starts right after volume header

	if (hiddenVol)
	{
		// Calculate data area position of hidden volume
		unsigned __int64 startOffset = hiddenVolHostSize - size - HIDDEN_VOL_HEADER_OFFSET;

		// Validate the offset
		if (startOffset % SECTOR_SIZE != 0)
		{
			nStatus = ERR_VOL_SIZE_WRONG; goto error;
		}

		startSector = startOffset / SECTOR_SIZE;	
		quickFormat = TRUE;		// To entirely format a hidden volume would be redundant
	}

	// Format filesystem

	switch (fileSystem)
	{
	case FILESYS_NONE:
	case FILESYS_NTFS: // NTFS volume is just prepared for quick format performed by system
		nStatus = FormatNoFs (startSector, num_sectors, (HFILE) dev, cryptoInfo, 1000, write, quickFormat);
		break;

	case FILESYS_FAT:
		if (num_sectors > 0xFFFFffff)
		{
			nStatus = ERR_VOL_SIZE_WRONG; goto error;
		}

		// Calculate the fats, root dir etc
		ft.num_sectors = (unsigned int) (num_sectors);
		ft.cluster_size = clusterSize;
		memcpy (ft.volume_name, "           ", 11);
		GetFatParams (&ft); 
		*realClusterSize = ft.cluster_size * SECTOR_SIZE;

		nStatus = FormatFat (startSector, &ft, (HFILE) dev, cryptoInfo, 1000, write, quickFormat);
		break;
	}

error:

	dwNow = GetTickCount ();

	burn (header, sizeof (header));
	VirtualUnlock (header, sizeof (header));

	crypto_close (cryptoInfo);

	if (bTimeStampValid)
	{
		// Restore the container timestamp (to preserve plausible deniability of the hidden volume) 
		if (SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
			MessageBox (hwndDlg, getstr (IDS_SETFILETIME_FAILED_IMPLANT), "TrueCrypt", MB_OK | MB_ICONEXCLAMATION);
	}

	CloseHandle (dev);

	dwError = GetLastError();

	if (nStatus!=0)
		SetLastError(dwError);
	else
	{
		switch (fileSystem)
		{
		case FILESYS_NONE:
			sprintf (summaryMsg, "Volume size:\t\t%I64d sectors (%I64d MB)\nFile system:\t\tNone"
				"\n\nFormatting took %lu seconds."
				, num_sectors, num_sectors*512/1024/1024
				, (dwNow - dwThen)/1000);
			break;

		case FILESYS_FAT:
			sprintf (summaryMsg, 
				"Volume size:\t\t%d sectors (%I64d MB)\nFile system:\t\tFAT%d\n"
				"FAT size:\t\t%d bytes\nCluster size:\t\t%d bytes\nClusters available:\t%d"
				"\n\nFormatting took %lu seconds."
				, ft.num_sectors, ((__int64) ft.num_sectors*512)/1024/1024, ft.size_fat
				, (int) (512*ft.fats*ft.fat_length),
				(int) (512*ft.cluster_size), ft.cluster_count,
				(dwNow - dwThen)/1000);
			break;

		case FILESYS_NTFS:
			{
				// NTFS format is performed by system so we first need to mount the volume
				int driveNo = GetLastAvailableDrive ();
				MountOptions mountOptions;
				
				if (driveNo == -1)
				{
					MessageBox (hwndDlg, "No free drive letter available. NTFS formatting cannot continue.", lpszTitle, ICON_HAND);
					return ERR_NO_FREE_DRIVES;
				}

				mountOptions.ReadOnly = FALSE;
				mountOptions.Removable = FALSE;

				if (MountVolume (hwndDlg, driveNo, volumePath, lpszPassword, FALSE, TRUE, &mountOptions, FALSE) < 1)
				{
					MessageBox (hwndDlg, "Cannot mount volume. NTFS formatting cannot continue.", lpszTitle, ICON_HAND);
					return ERR_VOL_MOUNT_FAILED;
				}

				// Quickformat volume as NTFS
				if (!FormatNtfs (driveNo, clusterSize))
				{
					MessageBox (hwndDlg, "NTFS formatting failed.\nTry using FAT file system instead.", lpszTitle, MB_ICONERROR);
				
					if (!UnmountVolume (hwndDlg, driveNo, FALSE))
						MessageBox (hwndDlg, "Volume dismount failed.", lpszTitle, MB_ICONERROR);

					return ERR_VOL_FORMAT_BAD;
				}

				if (!UnmountVolume (hwndDlg, driveNo, FALSE))
					MessageBox (hwndDlg, "Formatting succeeded but volume cannot be dismounted.", lpszTitle, MB_ICONEXCLAMATION);

				dwNow = GetTickCount ();

				sprintf (summaryMsg, "Volume size:\t\t%I64d sectors (%I64d MB)\nFile system:\t\tNTFS"
					"\n\nFormatting took %lu seconds."
					, num_sectors, num_sectors*512/1024/1024
					, (dwNow - dwThen)/1000);

				break;
			}
		}
	}

	return nStatus;
}


int FormatNoFs (unsigned __int64 startSector, __int64 num_sectors, HFILE dev, PCRYPTO_INFO cryptoInfo, int nFrequency, diskio_f write, BOOL quickFormat)
{
	int write_buf_cnt = 0;
	char sector[SECTOR_SIZE], *write_buf;
	int progress = 0;
	unsigned __int64 nSecNo = startSector;
	LARGE_INTEGER startOffset;
	LARGE_INTEGER newOffset;

	// Seek to start sector
	startOffset.QuadPart = startSector * SECTOR_SIZE;
	if (SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN) == 0
		|| newOffset.QuadPart != newOffset.QuadPart)
	{
		return ERR_VOL_SEEKING;
	}

	write_buf = TCalloc (WRITE_BUF_SIZE);
	memset (sector, 0, sizeof (sector));

	// Write sectors
	if(!quickFormat)
	{
		/* Generate a random key and IV to be used for "dummy" encryption that will fill the
		   free disk space (data area) with random data. That will reduce the amount of
		   predictable plaintext within the volume and also increase the level of plausible
		   deniability of hidden volumes. */
		char key[DISKKEY_SIZE];
		RandgetBytes (key, DISKKEY_SIZE, FALSE); 
		RandgetBytes (cryptoInfo->iv, sizeof cryptoInfo->iv, FALSE); 
		EAInit (cryptoInfo->ea, key, cryptoInfo->ks);
		RandgetBytes (sector, 256, FALSE); 
		RandgetBytes (sector + 256, 256, FALSE); 

		while (num_sectors--)
		{
			if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress,
				cryptoInfo, nFrequency, write) == FALSE)
				goto fail;
		}
		if (write_buf_cnt != 0 && (*write) (dev, write_buf, write_buf_cnt) == HFILE_ERROR)
			goto fail;
	}
	else
		nSecNo = num_sectors;

	UpdateProgressBar (nSecNo);

	TCfree (write_buf);
	return 0;

fail:

	TCfree (write_buf);
	return ERR_OS_ERROR;
}


volatile BOOLEAN FormatExResult;

BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID parameter)
{
	if (command == FMIFS_DONE)
		FormatExResult = *(BOOLEAN *) parameter;
	return TRUE;
}

BOOL FormatNtfs (int driveNo, int clusterSize)
{
	WCHAR dir[8] = { driveNo + 'A', 0 };
	PFORMATEX FormatEx;
	HMODULE hModule = LoadLibrary ("fmifs.dll");

	if (hModule == NULL)
		return FALSE;

	if (!(FormatEx = (void *) GetProcAddress (GetModuleHandle("fmifs.dll"), "FormatEx")))
	{
		FreeLibrary (hModule);
		return FALSE;
	}

	wcscat (dir, L":\\");

	FormatExResult = FALSE;

	if (*(char *)dir > 'C' && *(char *)dir <= 'Z')
		FormatEx (dir, FMIFS_HARDDISK, L"NTFS", L"", TRUE, clusterSize * 512, FormatExCallback);

	FreeLibrary (hModule);
	return FormatExResult;
}

BOOL
WriteSector (HFILE dev, char *sector,
	     char *write_buf, int *write_buf_cnt,
	     __int64 *nSecNo, int *progress, PCRYPTO_INFO cryptoInfo,
	     int nFrequency, diskio_f write)
{

	EncryptSectors ((unsigned long *) sector,
		(*nSecNo)++, 1, cryptoInfo->ks, cryptoInfo->iv, cryptoInfo->ea);

	memcpy (write_buf + *write_buf_cnt, sector, SECTOR_SIZE);
	(*write_buf_cnt) += SECTOR_SIZE;


	if (*write_buf_cnt == WRITE_BUF_SIZE)
	{
		if ((*write) (dev, write_buf, WRITE_BUF_SIZE) == HFILE_ERROR)
			return FALSE;
		else
			*write_buf_cnt = 0;
	}

	if (++(*progress) == nFrequency)
	{
		if (UpdateProgressBar (*nSecNo) == TRUE)
			return FALSE;
		*progress = 0;
	}

	return TRUE;

}

⌨️ 快捷键说明

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