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

📄 tc9x.c

📁 加密硬盘、分区、虚拟盘的程序源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Copyright (C) 2004 TrueCrypt Team, truecrypt.org
   This product uses components written by Paul Le Roux <pleroux@swprofessionals.com> 
   Majority of this code originally Copyright (C) 1998/9 by Aman. Used with
   permission. Other parts originally Copyright (C) 1995 by Walter Oney used
   with implied permission. */

#include "TCdefs.h"

#pragma VxD_LOCKED_CODE_SEG
#pragma VxD_LOCKED_DATA_SEG

#include "crypto.h"
#include "fat.h"
#include "volumes.h"
#include "cache.h"
#include "apidrvr.h"
#include "tc9x.h"
#include "queue.h"

#include "ifshook.h"
#include "ifsmgr.inc"


#define NUMSLOTS        8	/* Only up to 8 volumes at a time */
#define MAXBLOCK        128	/* 64k  was 256.... */

#define MAX_MESSAGES    8	/* Max number of queued driver messages */

#define DEVICE_TYPE     0	/* We are a fixed disk (even files on
				   removables) */

#ifdef DEBUG
#define EXTRA_INFO 1
#endif

int halfseccount=0xc9;

char *transferbuffer = NULL;	/* IO transfer buffer */
char *appaccessbuffer = NULL;	/* win32 GUI IO buffer */
char *partitiontestbuffer = NULL;	/* Buffer for the MBR */
int dcbcount = 0;		/* DCB hack */
PDCB dcblist[128];		/* DCB hack */

PDCB dcb_boot;			/* Boot device */

extern DRP theDRP;		/* Device registration packet */

int bAllowFastShutdown = 0;

cryptvol cv1 =
{0, 0, 0, 0, 0, 0, 0, 0};

cryptvol cv2 =
{0, 0, 0, 0, 0, 0, 0, 0};

cryptvol cv3 =
{0, 0, 0, 0, 0, 0, 0, 0};

cryptvol cv4 =
{0, 0, 0, 0, 0, 0, 0, 0};

cryptvol cv5 =
{0, 0, 0, 0, 0, 0, 0, 0};

cryptvol cv6 =
{0, 0, 0, 0, 0, 0, 0, 0};

cryptvol cv7 =
{0, 0, 0, 0, 0, 0, 0, 0};

cryptvol cv8 =
{0, 0, 0, 0, 0, 0, 0, 0};

cryptvol *cryptvols[]=
{
	&cv1,
	&cv2,
	&cv3,
	&cv4,
	&cv5,
	&cv6,
	&cv7,
	&cv8
};

typedef struct MessageBox_t
{
	char *MessageHdr;
	char *MessageBody;
	int PostPlease;
} MessageBox;

MessageBox Msgs[MAX_MESSAGES];


VOID
OnAsyncRequest (PAEP aep)
{
	typedef USHORT (*PEF) (PAEP);

	static PEF evproc[AEP_MAX_FUNC + 1] =
	{(PEF) OnInitialize	/* 0 AEP_INITIALIZE */
	 ,NULL			/* 1 AEP_SYSTEM_CRIT_SHUTDOWN */
	 ,(PEF) OnBootComplete	/* 2 AEP_BOOT_COMPLETE */
	 ,(PEF) OnConfigDcb	/* 3 AEP_CONFIG_DCB */
	 ,(PEF) OnUnconfigDcb	/* 4 AEP_UNCONFIG_DCB */
	 ,NULL			/* 5 AEP_IOP_TIMEOUT */
	 ,NULL			/* 6 AEP_DEVICE_INQUIRY */
	 ,(PEF) OnHalfSec	/* 7 AEP_HALF_SEC */
	 ,NULL			/* 8 AEP_1_SEC */
	 ,NULL			/* 9 AEP_2_SECS */
	 ,NULL			/* 10 AEP_4_SECS */
	 ,NULL			/* 11 AEP_DBG_DOT_CMD */
	 ,NULL			/* 12 AEP_ASSOCIATE_DCB */
	 ,NULL			/* 13 AEP_REAL_MODE_HANDOFF */
	 ,(PEF) OnSystemExit	/* 14 AEP_SYSTEM_SHUTDOWN */
	 ,(PEF) OnUninitialize	/* 15 AEP_UNINITIALIZE */
	 ,NULL			/* 16 AEP_DCB_LOCK */
	 ,NULL			/* 17 AEP_MOUNT_VERIFY */
	 ,NULL			/* 18 AEP_CREATE_VRP */
	 ,NULL			/* 19 AEP_DESTROY_VRP */
	 ,NULL			/* 20 AEP_REFRESH_DRIVE */
	 ,NULL			/* 21 AEP_PEND_UNCONFIG_DCB */
	 ,NULL			/* 22 AEP_1E_VEC_UPDATE */
	 ,NULL			/* 23 AEP_CHANGE_RPM */
	};
	PEF proc;

	if (aep->AEP_func < arraysize (evproc) && (proc = evproc[aep->AEP_func]))
		aep->AEP_result = proc (aep);
	else
		aep->AEP_result = (USHORT) AEP_FAILURE;
}


USHORT
OnInitialize (PAEP_bi_init aep)
{
	/* allocate our (smaller) memory buffer..... */

	static int initalready = 0;

	if (initalready)
		return AEP_SUCCESS;

	initalready++;

	transferbuffer = (char *) _PageAllocate (50, PG_SYS, 0, 0, 0, MBYTE16, NULL, PAGEZEROINIT | PAGEFIXED | PAGECONTIG | PAGEUSEALIGN);
	partitiontestbuffer = (char *) transferbuffer + (265 * 512);
	appaccessbuffer = transferbuffer + (265 * 512);


	if (transferbuffer)
		return AEP_SUCCESS;

	return (USHORT) AEP_FAILURE;
}

USHORT
OnUninitialize (PAEP_bi_uninit aep)
{
	return AEP_SUCCESS;
}

/* asks us if we want to stay loaded or not. */

USHORT
OnBootComplete (PAEP_boot_done aep)
{
	installhook ();
	return AEP_SUCCESS;
}

USHORT
OnConfigDcb (PAEP_dcb_config aep)
{
	PDCB dcb = (PDCB) aep->AEP_d_c_dcb;
	if (!(dcb->DCB_cmn.DCB_device_flags & DCB_DEV_PHYSICAL))
	{
		return AEP_SUCCESS;
	}

	/* Sadly for SCSI some port drivers have not set apparent_blk_shift
	   up at this point.. if  ((dcb->DCB_cmn.DCB_apparent_blk_shift!=9)
	   && (dcb->DCB_cmn.DCB_device_type!=DCB_type_cdrom) ) return
	   AEP_SUCCESS; */

	if (dcbcount < 100)
	{
		if ((dcb->DCB_cmn.DCB_device_type == 0) || (dcb->DCB_cmn.DCB_device_type == DCB_type_cdrom))
		{
			if (cmpvend ((char *) &dcb->DCB_vendor_id, "JETICO", 6) != 0)
			{
				if (CheckDcbAlready (dcb))
					return AEP_SUCCESS;
				dcblist[dcbcount] = dcb;
				dcblist[dcbcount + 1] = NULL;
				dcbcount++;
			}
		}
	}


	if (dcb->DCB_cmn.DCB_device_type == 0)
		((IspInsertCalldown (dcb, OnRequest, (PDDB) aep->AEP_d_c_hdr.AEP_ddb, 0,
		    dcb->DCB_cmn.DCB_dmd_flags, aep->AEP_d_c_hdr.AEP_lgn)));

	return AEP_SUCCESS;
}

/* AEP_UNCONFIG_DCB informs us that the physical device represented by a DCB
   is going away */

USHORT
OnUnconfigDcb (PAEP_dcb_unconfig aep)
{
	return AEP_SUCCESS;
}

VOID
OnRequest (PIOP iop)
{
	DoCallDown (iop);	/* do normal unencryped disk stuff... */
}

int
cmpvend (char *a, char *b, int len)
{
	int n;
	for (n = 0; n < len; n++)
		if (a[n] != b[n])
			return 1;
	return 0;
}


int
CheckDcbAlready (PDCB dcb)
{
	int n;
	/* sometimes the same dcb is passed more than once, on some drivers!! */
	if (!dcbcount)
		return 0;

	for (n = 0; n < dcbcount; n++)
		if (dcblist[n] == dcb)
			return 1;

	return 0;
}

/* DoCallDown passes a request to the next lower layer. Note that the
   documentation about how to do this is totally wrong: you don't just add
   sizeof(DCB_cd_entry) to the calldown pointer, you follow a linked list
   from one calldown entry to the next. */

void
DoCallDown (PIOP iop)
{
	_asm
	{			/* call down to next layer */
		pushfd
		pushad
		mov ecx,[iop]
		mov eax,[ecx] IOP.IOP_calldown_ptr
		  mov eax,[eax] DCB_cd_entry.DCB_cd_next
		  mov[ecx] IOP.IOP_calldown_ptr, eax
		  push ecx
		  call[eax] DCB_cd_entry.DCB_cd_io_address
		  add esp, 4
		  popad
		  popfd
	}
}

  BOOL
OnSysDynamicDeviceInit ()
{
	cv1.cryptsectorfirst = 0x7fffffff;
	cv1.cryptsectorlast = 0;

	cv2.cryptsectorfirst = 0x7fffffff;
	cv2.cryptsectorlast = 0;

	cv3.cryptsectorfirst = 0x7fffffff;
	cv3.cryptsectorlast = 0;

	cv4.cryptsectorfirst = 0x7fffffff;
	cv4.cryptsectorlast = 0;

	cv5.cryptsectorfirst = 0x7fffffff;
	cv5.cryptsectorlast = 0;

	cv6.cryptsectorfirst = 0x7fffffff;
	cv6.cryptsectorlast = 0;

	cv7.cryptsectorfirst = 0x7fffffff;
	cv7.cryptsectorlast = 0;

	cv8.cryptsectorfirst = 0x7fffffff;
	cv8.cryptsectorlast = 0;

	IOS_Register (&theDRP);
	return TRUE;		/* stay resident no matter what IOS says */
}

BOOL
OnSysDynamicDeviceExit ()
{
	return TRUE;
}

DWORD
OnDeviceIoControl (PDIOCPARAMETERS p)
{
	installhook ();		/* make sure hook is installed */
	InstallTCThread ();

	/* select on IOCTL code */
	switch (p->dwIoControlCode)
	{

	case 0:		/* VWIN32 pinging us during CreateFile */
	case -1:		/* CloseHandle */
		break;

	case ALLOW_FAST_SHUTDOWN:
		{
			bAllowFastShutdown = 1;
			break;
		}

	case DRIVER_VERSION:
		{
			LONG *tmp = (LONG *) p->lpvInBuffer;
			LONG tmp2 = VERSION_NUM;

			if (tmp == NULL)
				return ERROR_GEN_FAILURE;

			memcpy (tmp, &tmp2, 4);
			break;
		}

	case WIPE_CACHE:
		WipeCache ();
		break;

	case CACHE_STATUS:
		return cacheEmpty ? ERROR_GEN_FAILURE : 0;

	case DISKIO:		/* Call to read and write sectors from
				   application */
		{
			DISKIO_STRUCT *dio = (DISKIO_STRUCT *) p->lpvInBuffer;
			int s;

			if (dio == NULL)
				return ERROR_GEN_FAILURE;

			s = AppAccessBlockDevice (dio->devicenum, dio->sectorstart, dio->sectorlen, dio->bufferad, dio->mode);
			dio->nReturnCode = s;

			break;
		}

	case OPEN_TEST:
		{
			OPEN_TEST_STRUCT *item = (OPEN_TEST_STRUCT *) p->lpvInBuffer;
			unsigned long *tmp = (void *) partitiontestbuffer;
			MOUNT_STRUCT mount;

			if (item == NULL)
				return ERROR_GEN_FAILURE;

			strcpy ((char *) mount.wszVolume, (char *) item->wszFileName);

			item->nReturnCode = ERR_BAD_DRIVE_LETTER;

			readallpartitions (&mount, TRUE);

			item->nReturnCode = mount.nReturnCode;

			item->secstart = tmp[0];
			item->seclast = tmp[1];
			item->device = tmp[2];

			break;
		}

	case MOUNT_LIST_N:
		{
			MOUNT_LIST_N_STRUCT *item = (MOUNT_LIST_N_STRUCT *) p->lpvInBuffer;
			cryptvol *cv;
			int c;

			if (item == NULL)
				return ERROR_GEN_FAILURE;

			item->nReturnCode = ERR_BAD_DRIVE_LETTER;

			for (c = 0; c < NUMSLOTS; c++)
			{
				cv = cryptvols[c];

				if ((cv->booted == 0) && (cv->physdevDCB == 0))
					continue;

				if (item->nDosDriveNo == cv->drive)
				{
					/* 16/9/99 This is safe as
					   item->wszVolume is >
					   cv->mounted_file_name */
					strcpy ((char *) item->wszVolume, cv->mounted_file_name);
					item->nReturnCode = 0;
					break;
				}
			}

			break;
		}

	case RELEASE_TIME_SLICE:
		ReleaseTimeSlice ();
		break;

	case MOUNT:
		{
			MOUNT_STRUCT *mount = (MOUNT_STRUCT *) p->lpvInBuffer;
			char tmp[9];

			if (mount == NULL)
				return ERROR_GEN_FAILURE;

#if EXTRA_INFO
			_Debug_Printf_Service ("MOUNT\n");
#endif

			memcpy (tmp, (char *) mount->wszVolume, 8);
			tmp[8] = 0;

			if (strcmp (tmp, "\\Device\\") == 0)
				readallpartitions (mount, FALSE);
			else
				mountdiskfileR0 (mount);

            if (mount->nReturnCode == 0 &&  bAllowFastShutdown == 1)
            {
                IFSMgr_PNPEvent (DBT_DEVICEARRIVAL, mount->nDosDriveNo, PNPT_VOLUME | DBTF_MEDIA );
            }


#if EXTRA_INFO
			_Debug_Printf_Service ("MOUNT end\n");
#endif

			break;
		}

	case UNMOUNT:
	case UNMOUNT_PENDING:
		{
			UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) p->lpvInBuffer;
			cryptvol *cv;
			int c;

			if (unmount == NULL)
				return ERROR_GEN_FAILURE;

			unmount->nReturnCode = ERR_BAD_DRIVE_LETTER;

			for (c = 0; c < NUMSLOTS; c++)
			{
				cv = cryptvols[c];

				if ((cv->booted == 0) && (cv->physdevDCB == 0))
					continue;

				if (unmount->nDosDriveNo == cv->drive)
				{
					if (p->dwIoControlCode == UNMOUNT_PENDING)
					{
						if (closeCrDevice (cv, 0) != 0)
							unmount->nReturnCode = ERR_FILES_OPEN;
						else
							unmount->nReturnCode = 0;
					}
					else
					{
						if (closeCrDevice (cv, 1) != 0)
							unmount->nReturnCode = ERR_FILES_OPEN;
						else
							unmount->nReturnCode = 0;
					}

					break;
				}
			}

			break;
		}

	case MOUNT_LIST:
		{
			MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) p->lpvInBuffer;
			cryptvol *cv;
			int c;

			if (list == NULL)
				return ERROR_GEN_FAILURE;

			list->ulMountedDrives = 0;

			for (c = 0; c < NUMSLOTS; c++)
			{
				int nDosDriveNo;

				cv = cryptvols[c];

				if ((cv->booted == 0) && (cv->physdevDCB == 0))
					continue;

				nDosDriveNo = cv->drive;

				list->ulMountedDrives |= 1 << nDosDriveNo;

				if (strlen (cv->mounted_file_name) < 64)
				{
					strcpy ((char *) list->wszVolume[nDosDriveNo], cv->mounted_file_name);
				}
				else
				{
					memcpy ((char *) list->wszVolume[nDosDriveNo], cv->mounted_file_name, 60);
					((char *) list->wszVolume[nDosDriveNo])[60] = '.';
					((char *) list->wszVolume[nDosDriveNo])[61] = '.';
					((char *) list->wszVolume[nDosDriveNo])[62] = '.';
					((char *) list->wszVolume[nDosDriveNo])[63] = 0;
				}

				list->cipher[nDosDriveNo] = cv->cryptoInfo->cipher;

				if(!cv->mountfilehandle)
					list->diskLength[nDosDriveNo] = (cv->cryptsectorlast - cv->cryptsectorfirst) * 512I64;
				else
					list->diskLength[nDosDriveNo] = 0;

				list->cipher[nDosDriveNo] = cv->cryptoInfo->cipher;

			}

			break;
		}

	case VOLUME_PROPERTIES:
		{
			VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) p->lpvInBuffer;
			cryptvol *cv;
			int c;

			if (prop == NULL)
				return ERROR_GEN_FAILURE;

			for (c = 0; c < NUMSLOTS; c++)
			{
				int nDosDriveNo;

				cv = cryptvols[c];

				if ((cv->booted == 0) && (cv->physdevDCB == 0))
					continue;

				nDosDriveNo = cv->drive;

				if (nDosDriveNo != prop->driveNo)
					continue;

				if (strlen (cv->mounted_file_name) < 64)
				{
					strcpy ((char *) prop->wszVolume, cv->mounted_file_name);
				}
				else
				{
					memcpy ((char *) prop->wszVolume, cv->mounted_file_name, 60);
					((char *) prop->wszVolume)[60] = '.';
					((char *) prop->wszVolume)[61] = '.';
					((char *) prop->wszVolume)[62] = '.';
					((char *) prop->wszVolume)[63] = 0;
				}

				prop->cipher = cv->cryptoInfo->cipher;

				if(!cv->mountfilehandle)
					prop->diskLength = (cv->cryptsectorlast - cv->cryptsectorfirst) * 512I64;
				else
					prop->diskLength = 0;

				prop->cipher = cv->cryptoInfo->cipher;
				prop->pkcs5 = cv->cryptoInfo->pkcs5;
				prop->pkcs5Iterations = cv->cryptoInfo->noIterations;
				prop->volumeCreationTime = cv->cryptoInfo->volume_creation_time;
				prop->headerCreationTime = cv->cryptoInfo->header_creation_time;

				return 0;
			}

			return ERROR_GEN_FAILURE;
		}


	default:
		return ERROR_INVALID_FUNCTION;

	}

	return 0;
}

BOOL
Kill_Drive (cryptvol * cv)
{
	BOOL result = FALSE;

	if (cv->booted != 0 || cv->physdevDCB != 0)
	{
		if ((cv->drive >= 0) && (cv->drive < 26))
		{

⌨️ 快捷键说明

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