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

📄 tc9x.c

📁 加密硬盘、分区、虚拟盘的程序源码
💻 C
📖 第 1 页 / 共 4 页
字号:
			cv->mountfilehandle = hfile;
			cv->physdevDCB = &cv->logicaldcb;
			cv->cryptsectorfirst = 0x00000000;
			cv->cryptsectorlast = 0x7ffffff0;
			dcb = (PDCB) cv->physdevDCB;
			flag = 2;

			if (writeable != 0)
				dcb->DCB_cmn.DCB_device_flags = DCB_DEV_WRITEABLE;

			/* clears cv set above if failed.... */
			tmf = trymountfile (dcb, cv, mf);

			if (tmf)
			{
				_asm cli
				  flag = 3;

				mf->nReturnCode = flag;

				if (tmf > 0)	/* if tmg is -ve then no
						   drive letter (already had
						   blue screen..) */
				{
					mf->nReturnCode = flag;

					cv->booted = 2;
					strcpy ((char *) &cv->mounted_file_name, fname);

					goto done;
				}
			}	/* trymountfile */

		}		/* if cv->.... */

		if (flag)
			break;	/* out of for loop */
	}


	R0_CloseFile (hfile);

      done:

	switch (flag)
	{
	case 3 + 128:
		mf->nReturnCode = ERR_VOL_ALREADY_MOUNTED;
		break;
	case 1:
		mf->nReturnCode = ERR_FILE_OPEN_FAILED;
		break;
	case 2:
		mf->nReturnCode = ERR_VOL_MOUNT_FAILED;
		break;
	case 3:
		if (tmf > 0)
		{
			mf->nReturnCode = 0;
			mf->nDosDriveNo = cv->drive;
		}
		else
			mf->nReturnCode = ERR_NO_FREE_DRIVES;
		break;
	case 0:
		mf->nReturnCode = ERR_NO_FREE_SLOTS;
		break;
	}
}


void
outblock (PIOP iop, char *outbuffer, int sectorstart, int sectorcount, cryptvol * cv, char *workbuff)
{
	int logsec = sectorstart + 1;	/* get logical volume sector. */

	char *sendbuffer;

	if (!sectorcount)
		return;

	do
	{
		if (sectorcount <= MAXBLOCK)
		{
			sendbuffer = outbuffer;

			/* if copyflag 0, then buffer already set by caller. */
			ior.IOR_status = 0;
			if (workbuff)
			{
				sectorcopy (workbuff, outbuffer, sectorcount);
				sendbuffer = workbuff;
			}

			writelogical (iop, logsec, sectorcount, sendbuffer, cv);

			sectorcount = 0;
			return;
		}
		else
		{
			sendbuffer = outbuffer;
			if (workbuff)
			{
				sectorcopy (workbuff, outbuffer, MAXBLOCK);
				sendbuffer = workbuff;
			}

			writelogical (iop, logsec, MAXBLOCK, sendbuffer, cv);
			logsec += MAXBLOCK;
			sectorcount -= MAXBLOCK;
			outbuffer += (MAXBLOCK * 512);
		}
	}
	while ((sectorcount > 0) && (ior.IOR_status < 16));
}

void
inblock (PIOP iop, char *outbuffer, int sectorstart, int sectorcount, cryptvol * cv)
{
	int logsec = sectorstart + 1;	/* get logical volume sector. */

	do
	{
		ior.IOR_status = 0;
		if (sectorcount < MAXBLOCK)
		{
			readlogical (iop, logsec, sectorcount, (char *) transferbuffer, cv);
			memcpy (outbuffer, transferbuffer, sectorcount * 512);
			sectorcount = 0;
			return;
		}
		else
		{
			readlogical (iop, logsec, MAXBLOCK, (char *) transferbuffer, cv);
			memcpy (outbuffer, transferbuffer, MAXBLOCK * 512);
			logsec += MAXBLOCK;
			sectorcount -= MAXBLOCK;
			outbuffer += (MAXBLOCK * 512);
		}
	}
	while ((sectorcount > 0) && (ior.IOR_status < 16));
}

int
doR0fileio (int sector, int numsectors, char *buffer, cryptvol * cv, int iorop)
{
	CLIENT_STRUCT sregs;	/* static */
	PVRP v;

	int res;
	int bytes;		/* static */


	if (iorop == IOR_READ)
	{
		if (numsectors)
		{
			SaveClientState ((CLIENT_STRUCT *) & sregs);

			res = R0_ReadFile (FALSE, cv->mountfilehandle, numsectors << 9, sector << 9, buffer, &bytes);

			RestoreClientState ((CLIENT_STRUCT *) & sregs);
		}

		return res;
	}			/* IOR read */

	res = 0;
	if (iorop == IOR_WRITE)
	{
		if (numsectors)
		{
			SaveClientState ((CLIENT_STRUCT *) & sregs);

			res = R0_WriteFile (FALSE, cv->mountfilehandle, numsectors * 512, sector * 512, buffer, &bytes);

			RestoreClientState ((CLIENT_STRUCT *) & sregs);
		}

		if (res)
		{
			if (res == 5)
				res = 0x13;	/* WHY ARE WE GETTING ACCESS
						   DENIED 005 ON CD RATHER
						   THAN WP ? */

			if (res == 0x13)
			{
				if (cv->booted >= 2)
				{
					v = (PVRP) cv->ldcb->DCB_cmn.DCB_vrp_ptr;
					if (v)
					{
						if ((v->VRP_event_flags & VRP_ef_write_protected) == 0)
						{
							v->VRP_event_flags |= VRP_ef_write_protected | VRP_ef_media_uncertain;
						}
					}
				}	/* cv->booted */
			}	/* res=13 */
		}		/* res= something */

		return res;
	}			/* IOR write */

	return 0;
}

int
MapDosError (int error)
{
	int e;

	if (error == 0x13)
		return (IORS_WRITE_PROTECT);

	e = IORS_NOT_READY;	/* IORS_HW_FAILURE;      */
	return e;
}

char fileerrorstr[]=
{
	"TC has encountered an error reading a host file which\n"
	"it is using for a currently open scrambled disk volume.\n\n"
	"You should immediately dismount the file using the TC mount\n"
   "application, correct the error, and re mount the disk image file.\n\n\n"
      "The related disk will be unavailable, until you do, and you should\n"
	"save your work elsewhere."
};

int
dophysblock2 (PIOP iop, int sector, int numsectors, char *buffr, cryptvol * cv, USHORT iorop)
{
	int rstatus = 0;	/* status return value.... */
	PIOP myiop;
	PIOR myior;

	_BlockDev_Scatter_Gather *sgd;

	PDCB mydcb = cv->physdevDCB;	/* (PDCB) iop->IOP_physical_dcb; */
	USHORT offset;
	USHORT size;

	if (cv->mountfilehandle)
	{
		if (cv->booted <= 2)
			rstatus = doR0fileio (sector, numsectors, buffr, cv, iorop);
		else
			rstatus = 23;

		if ((rstatus) && (rstatus != 0x13))
		{
			iop->IOP_timer = iop->IOP_timer_orig = 32000;
			rstatus = MapDosError (rstatus);

			if (cv->booted <= 2 && (cv->booted))
			{
				Post_message (fileerrorstr, "TC: Mounted file error");
				cv->booted = 256;
			}
		}

		iop->IOP_ior.IOR_status = rstatus;
		return rstatus;
	}

	/* End up here, if we are handling a disk partition rather than
	   container file */
	offset = (USHORT) (mydcb->DCB_cmn.DCB_expansion_length + FIELDOFFSET (IOP, IOP_ior));
	size = offset + sizeof (IOR) + (8 * sizeof (SGD));
	iop->IOP_timer = iop->IOP_timer_orig = 160;

	myiop = IspCreateIop (size, offset, ISP_M_FL_SMART_ALLOC);

	if (myiop == NULL)
	{

		iop->IOP_ior.IOR_status = IORS_MEMORY_ERROR;
		return IORS_MEMORY_ERROR;
	}

	myior = &myiop->IOP_ior;

	/* Be aware that Criteria routine reads it's dmd bits from THIS dcb! */

	myiop->IOP_original_dcb = (ULONG) mydcb;	/* iop->IOP_original_dcb;
							   (ULONG) mydcb;        */
	myiop->IOP_physical_dcb = (ULONG) mydcb->DCB_cmn.DCB_physical_dcb;
	if (cv->booted == 1)
		cv->booted = 2;	/* Irrelevant here.....    */
	myior->IOR_next = 0;
	myior->IOR_start_addr[1] = 0;
	myior->IOR_flags = IORF_VERSION_002;
	myior->IOR_private_client = offset;
	myior->IOR_req_vol_handle = mydcb->DCB_cmn.DCB_vrp_ptr;
	myior->IOR_sgd_lin_phys = (ULONG) (myior + 1);
	myior->IOR_num_sgds = 0;
	myior->IOR_vol_designtr = mydcb->DCB_cmn.DCB_unit_number;
	myior->IOR_func = iorop;
	myior->IOR_flags |= IORF_BYPASS_VOLTRK | IORF_HIGH_PRIORITY | IORF_SCATTER_GATHER | IORF_SYNC_COMMAND | IORF_DONT_CACHE;
	if (iorop == IOR_READ)
		myior->IOR_flags |= IORF_DATA_IN;
	if (iorop == IOR_WRITE)
		myior->IOR_flags |= IORF_DATA_OUT;
	myior->IOR_start_addr[0] = sector;
	myior->IOR_xfer_count = numsectors;
	sgd = (_BlockDev_Scatter_Gather *) myior->IOR_sgd_lin_phys;	/* scatter gather
									   array... */
	sgd->BD_SG_Buffer_Ptr = (ULONG) buffr;	/* Buffer in LOCKED ram,
						   below 16mbyte, 4K
						   boundary.. */
	sgd->BD_SG_Count = numsectors;
	myior->IOR_buffer_ptr = (ULONG) sgd;	/* Implement as Scatter
						   gather, with One block */
	sgd++;
	sgd->BD_SG_Buffer_Ptr = 0;
	sgd->BD_SG_Count = 0;
	sgd++;
	myior->IOR_sgd_lin_phys = (ULONG) sgd;
	rstatus = myior->IOR_status;
	sgd->BD_SG_Buffer_Ptr = 0;
	sgd->BD_SG_Count = 0;
	sgd++;
	sgd->BD_SG_Buffer_Ptr = 0;
	sgd->BD_SG_Count = 0;
	sgd++;
	sgd->BD_SG_Buffer_Ptr = 0;
	sgd->BD_SG_Count = 0;
	myiop->IOP_timer = 40;
	myiop->IOP_timer_orig = 40;
	/* Call criteria, to set phys SGDs physical addresses if needed..... */
	if (IlbIntIoCriteria (myiop))
		myior->IOR_flags |= IORF_DOUBLE_BUFFER;	/* Double buffer, will
							   also make no
							   difference */
	IlbInternalRequest (myiop, mydcb, OnRequest);
	rstatus = myior->IOR_status;
	iop->IOP_ior.IOR_status = rstatus;	/* myior->IOR_status; */
	IspDeallocMem ((PVOID) ((DWORD) myior - myior->IOR_private_client));
	return rstatus;
}

int
dophysblock (PIOP iop, int sector, int numsectors, char *buffr, cryptvol * cv, USHORT iorop)
{
	int s, c;

	for (c = 0; c < 3; c++)
	{
		s = dophysblock2 (iop, sector, numsectors, buffr, cv, iorop);
		if (s == IORS_SUCCESS_WITH_RETRY)
			return 0;
		if (!s)
			return 0;
	}

	return s;
}

void
readlogical (PIOP iop, int temp_block, int num_sectors, char *buffer, cryptvol * cv)
{
	int secNum;

	secNum = temp_block;

#if EXTRA_INFO
	_Debug_Printf_Service ("secNum=%d,num_sectors=%d\n", secNum, num_sectors);
#endif

	dophysblock (iop, secNum + cv->cryptsectorfirst, num_sectors, buffer, cv, IOR_READ);

#if EXTRA_INFO
	_Debug_Printf_Service ("0x%08x\n", *((int *) buffer));
#endif

	cv->cryptoInfo->decrypt_sector ((unsigned long *) buffer,
					(unsigned __int64) secNum, num_sectors,
					&cv->cryptoInfo->ks[0],
					cv->cryptoInfo->iv,
					cv->cryptoInfo->cipher);

#if EXTRA_INFO
	_Debug_Printf_Service ("0x%08x\n", *((int *) buffer));
#endif

}

void
writelogical (PIOP iop, int temp_block, int num_sectors, char *buffer, cryptvol * cv)
{
	int secNum;
	
	secNum = temp_block;

#if EXTRA_INFO
	_Debug_Printf_Service ("0x%08x\n", *((int *) buffer));
#endif

	cv->cryptoInfo->encrypt_sector ((unsigned long *) buffer,
					(unsigned __int64) secNum, num_sectors,
					&cv->cryptoInfo->ks[0],
					cv->cryptoInfo->iv,
					cv->cryptoInfo->cipher);

#if EXTRA_INFO
	_Debug_Printf_Service ("0x%08x\n", *((int *) buffer));
#endif

	dophysblock (iop, secNum + cv->cryptsectorfirst, num_sectors, buffer, cv, IOR_WRITE);
}


BOOL
OnSystemExit (void)
{
	/* Called when Win32 is about to die. We must close down the files,
	   for any files mounted as encrypted disks. this call seems to be
	   the only chance we get. the system pukes amd hangsif we don't.
	   Corrupt screen etc. nd refuses to shut down..... */

	cryptvol *cv;
	int c;

	for (c = 0; c < NUMSLOTS; c++)
	{
		cv = cryptvols[c];
		unlockdrive (cv);
		if (cv->mountfilehandle)
			R0_CloseFile (cv->mountfilehandle);
	}

	killthread ();
	return AEP_SUCCESS;
}

void
Post_message (char *msg, char *header)
{
	MessageBox *m;
	int n;

	for (n = 0; n < MAX_MESSAGES - 1; n++)
	{
		m = &Msgs[n];
		if (m->PostPlease == 0)
			break;

	}

	m->PostPlease = 1;
	m->MessageHdr = header;
	m->MessageBody = msg;
}

void
ProcessWinMessagesBlueScreen (void)
{
	MessageBox *m;
	int n;

	for (n = 0; n < MAX_MESSAGES; n++)
	{
		m = &Msgs[n];
		if (m->PostPlease)
		{
			ShellMessageNCB (0, m->MessageBody, m->MessageHdr);
			m->PostPlease = 0;
		}
	}
}

/* The code below gets called by the IOS *every* 0.5 seconds... */
USHORT 
OnHalfSec (PAEP_boot_done aep) /* dummy param */
{
#if 0
	cryptvol *cv;
        int c;
	int notified = 0;
#endif

	halfseccount++;

	ProcessWinMessagesBlueScreen ();

#if 0
        for (c = 0; c < 8; c++)
	{
		cv = cryptvols[c];

		if (cv->notifytime)
		{
			cv->notifytime--;
			if (cv->notifytime == 0)
			{
				cv->notifytime = 0x8000ffff;
				if (!notified) /* prevent multiple notifications */
				{
					notified++;
					SHELL_CallAtAppyTime ((APPY_CALLBACK) & drivearrived, 0, 0);
				}
			}

		}
	}
#endif

	return AEP_SUCCESS;
}


/* ------------------------------------partition support
   ------------------------------------------- */

/* go round every drive reading all the partitions.... */
void
readallpartitions (MOUNT_STRUCT * mf, BOOL bVerifyOnly)
{
	int c = 0;
	PDCB dcb;
	USHORT offset;
	USHORT size;
	PIOP myiop;
	PIOR myior;
	int x, disks, z;
	char *vol = (char *) mf->wszVolume;

	mf->nReturnCode = ERR_INVALID_DEVICE;	/* Assume failure */

	if (strlen ((char *) mf->wszVolume) < 28)
		return;

	x = vol[16] - '0';	/* Disk number starting from 0 */
	z = vol[27] - '0';	/* Partition number start from 1 */
	disks = 0;		/* Count of disks */

	if (x < 0 || z < 1)
		return;

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

	while (dcb = dcblist[++c])
	{
		if ((dcb->DCB_cmn.DCB_device_type == 0) && (dcb->DCB_cmn.DCB_apparent_blk_shift == 9))
		{
			if (x != disks++)
				continue;

			offset = (USHORT) (dcb->DCB_cmn.DCB_expansion_length + FIELDOFFSET (IOP, IOP_ior));
			size = offset + sizeof (IOR) + dcb->DCB_max_sg_elements * sizeof (SGD);
			myiop = IspCreateIop (size, offset, ISP_M_FL_MUST_SUCCEED | ISP_M_FL_SMART_ALLOC | ISP_M_FL_INTERRUPT_TIME | ISP_M_FL_PERSISTENT_IOP);
			myior = &myiop->IOP_ior;
			myior->IOR_private_client = offset;

			DiskRead (dcb, myiop, 0, 1, partitiontestbuffer, IOR_READ);	/* ;single read in case
											   of media change... */
			memset (partitiontestbuffer, 0, 512);

			if (!DiskRead (dcb, myiop, 0, 1, partitiontestbuffer, IOR_READ))	/* +32768  */
			{
				UsePartitionInfo (dcb, myiop, partitiontestbuffer, 0, 0, &z, mf, bVerifyOnly);	/* +32768 */
			}

			IspDeallocMem ((PVOID) ((DWORD) myior - myior->IOR_private_client));

		}
	}

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

}


int
DiskRead (PDCB mydcb, PIOP myiop, unsigned int sector, unsigned int numsectors, char *buffr, USHORT iorop)
{
	int rstatus = 0;	/* status return value....  */
	unsigned long *errnl = (unsigned long *) buffr;	/* no load test... */
	PIOR myior;
	_BlockDev_Scatter_Gather *sgd;

	myior = &myiop->IOP_ior;
	myiop->IOP_original_dcb = (ULONG) mydcb;
	myiop->IOP_physical_dcb = (ULONG) mydcb->DCB_cmn.DCB_physical_dcb;
	myior->IOR_next = 0;
	myior->IOR_start_addr[1] = 0;
	myior->IOR_flags = IORF_VERSION_002;
	myior->IOR_req_vol_handle = mydcb->DCB_cmn.DCB_vrp_ptr;
	myior->IOR_sgd_lin_phys = (ULONG) (myior + 1);
	myior->IOR_num_sgds = 0;
	myior->IOR_vol_designtr = mydcb->DCB_cmn.DCB_unit_number;
	myior->IOR_func = iorop;
	myior->IOR_flags |= IORF_BYPASS_VOLTRK | IORF_HIGH_PRIORITY | IORF_SCATTER_GATHER | IORF_SYNC_COMMAND;
	if (iorop == IOR_READ)
	{
		myior->IOR_flags |= IORF_DATA_IN;
		memset (buffr, 0, numsectors * 512);
		errnl[0] = 0xACE01DE4;
		errnl[1] = 0xEDB0CD01;
		errnl[2] = 0x4caf3321;
		errnl[3] = 0xa35a32c4;
	}

	if (iorop == IOR_WRITE)
		myior->IOR_flags |= IORF_DATA_OUT;
	myior->IOR_start_addr[0] = sector;
	myior->IOR_xfer_count = numsectors;
	myior->IOR_buffer_ptr = (ULONG) buffr;

	sgd = (_BlockDev_Scatter_Gather *) myior->IOR_sgd_lin_phys;	/* scatter gather
									   array... */
	sgd->BD_SG_Buffer_Ptr = (ULONG) buffr;	/* Buffer in LOCKED ram,
						   below 16mbyte, 4K
						   boundary.. */
	sgd->BD_SG_Count = numsectors;
	myior->IOR_buffer_ptr = (ULONG) sgd;	/* Implement as Scatter
						   gather, with One block */
	sgd++;
	sgd->BD_SG_Buffer_Ptr = 0;

⌨️ 快捷键说明

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