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

📄 tc9x.c

📁 加密硬盘、分区、虚拟盘的程序源码
💻 C
📖 第 1 页 / 共 4 页
字号:
			result = IspDisassociateDcb (cv->drive);
			if (cv->mountfilehandle)
				R0_CloseFile (cv->mountfilehandle);

			if (result == TRUE)
			{
				PDCB dcb;

				if (!cv->mountfilehandle)
					unlockdrive (cv);	/* files to be handled
								   by win32 app. */

				crypto_close (cv->cryptoInfo);

				dcb = cv->ldcb;
				dcb->DCB_Port_Specific = 0;
				memset (cv, 0, sizeof (cryptvol));
				cv->cryptsectorfirst = 0x7fffffff;
			}
		}
	}

	return result;
}

int
closeCrDevice (cryptvol * cv, int mode)
{
	if (mode == 0)		/* pre flush volume call..... */
	{
		if (cv->drive != 0)
		{
			if (cv->booted <= 2)
			{
				_VolFlush (cv->drive, 0);	/* flush stuff out
								   before the
								   dismount... */
				//%% NotifyVolumeRemoval (cv->drive);
			}
			return 0;
		}
		else
			return 1;
	}
	else
	{
		if (Kill_Drive (cv) == TRUE)
			return 0;
		else
			return 0x42424242;
	}
}

int
installthread (void *t)
{
	int id;
	_asm
	{
		mov ecx, 4096
		  mov edi, 0
		  mov ebx,[t];
		xor esi, esi
	}

	  VxDCall (_VWIN32_CreateRing0Thread)
	_asm mov[id], eax
	  return id;
}

void
sectorcopy (char *dest, char *source, int num)
{
	_asm
	{
		pushad
		mov edi,[dest]
		mov esi,[source]
		mov ecx,[num]
		shl ecx, 9	/* *512 */
		  sar ecx, 4	/* 16 in pass... */
		  cpylp:
		  mov eax,[esi]
		mov ebx,[esi + 4]
		  mov[edi], eax
		  mov[edi + 4], ebx
		  mov eax,[esi + 8]
		mov ebx,[esi + 12]
		  mov[edi + 8], eax
		  mov[edi + 12], ebx
		  add edi, 16
		  add esi, 16
		  dec ecx
		  jnz cpylp
		  popad
	}
}

void
cryptproc (PIOP iop, cryptvol * cv)
{
	PDCB dcbx;
	unsigned int buffernum, totalsectors;
	unsigned int sectorstart, sectorcount;
	char *outbuffer, *bufadr, *buffercopy;
	_BlockDev_Scatter_Gather *sgd;

	dcbx = (PDCB) iop->IOP_physical_dcb;
	ior.IOR_status = 0;
	if (ior.IOR_func == IOR_WRITEV)
	{
		ior.IOR_status = IORS_INVALID_COMMAND;
		return;
	}

	sectorcount = ior.IOR_xfer_count;

	if (!sectorcount)
	{
		ior.IOR_status = 0;
		return;
	}

	if ((ior.IOR_func == IOR_READ) || (ior.IOR_func == IOR_WRITE))
	{
		if (iop->IOP_ior.IOR_flags & IORF_CHAR_COMMAND)
		{
			ior.IOR_status = IORS_INVALID_COMMAND;
			return;	/* Char command NOT supported or needed.... */
		}
	}
	else
	{
		ior.IOR_status = 0;
		if (!cv->mountfilehandle)
			DoCallDown (iop);
		return;
	}

	if (ior.IOR_func == IOR_READ)
	{
		sectorstart = ior.IOR_start_addr[0];
		sectorcount = ior.IOR_xfer_count;
		outbuffer = (char *) ior.IOR_buffer_ptr;	/* may be scatter gather
								   pointer... */
		if (ior.IOR_flags & IORF_SCATTER_GATHER)
		{
			sgd = (_BlockDev_Scatter_Gather *) outbuffer;
			while ((sectorcount = sgd->BD_SG_Count))
			{
				outbuffer = (char *) sgd->BD_SG_Buffer_Ptr;
				inblock (iop, outbuffer, sectorstart, sectorcount, cv);

				if (sectorstart == 0)
				{
					(unsigned char) outbuffer[0] = 0xeb;
					outbuffer[1] = 0x3c;
					(unsigned char) outbuffer[2] = 0x90;

					outbuffer[510] = 0x55;	/* boot sector
								   bodge...... */
					(unsigned char) outbuffer[511] = 0xAA;
				}

				sectorstart += sectorcount;
				++sgd;
			}
		}
		else
			/* linear buffer     */
		{
			inblock (iop, outbuffer, sectorstart, sectorcount, cv);

			/* The following code LIES to win98, who won't
			   otherwise mount disks created by earlier versions,
			   because the boot sector had stuff missing.  (fixed
			   now...) */
			if (sectorstart == 0)
			{
				(unsigned char) outbuffer[0] = 0xeb;
				outbuffer[1] = 0x3c;
				(unsigned char) outbuffer[2] = 0x90;
				outbuffer[510] = 0x55;
				(unsigned char) outbuffer[511] = 0xAA;
			}
		}
	}			/* end read op */
	else if (ior.IOR_func == IOR_WRITE)
	{
		if (cv->booted == 0)
		{
			ior.IOR_status = 0;
			return;
		}

		buffernum = 0;

		bufadr = transferbuffer;
		bufadr += (buffernum * (MAXBLOCK * 512));
		sectorstart = ior.IOR_start_addr[0];
		sectorcount = ior.IOR_xfer_count;
		outbuffer = (char *) ior.IOR_buffer_ptr;	/* may be scatter gather
								   pointer...; */
		totalsectors = 0;
		buffercopy = bufadr;

		if (ior.IOR_flags & IORF_SCATTER_GATHER)
		{
			sgd = (_BlockDev_Scatter_Gather *) outbuffer;
			while ((sectorcount = sgd->BD_SG_Count))
			{
				outbuffer = (char *) sgd->BD_SG_Buffer_Ptr;
				if ((totalsectors + sectorcount) <= MAXBLOCK)
				{
					sectorcopy (buffercopy, outbuffer, sectorcount);
					totalsectors += sectorcount;
					buffercopy += sectorcount * 512;
				}
				else
					/* write any previous buffer..... */
				{
					if (totalsectors)	/* was it too big to
								   start with ? */
					{
						outblock (iop, bufadr, sectorstart, totalsectors, cv, NULL);

						buffernum = 0;

						bufadr = transferbuffer;
						bufadr += (buffernum * (MAXBLOCK * 512));
						sectorstart += totalsectors;
						totalsectors = 0;
						buffercopy = bufadr;
						--sgd;	/* back to previous for
							   next pass..... */
					}
					else
					{	/* initial buffer was too
						   big, to start with! */
						outblock (iop, outbuffer, sectorstart, sectorcount, cv, bufadr);

						buffernum = 0;

						bufadr = transferbuffer;
						bufadr += (buffernum * (MAXBLOCK * 512));
						sectorstart += sectorcount;
						buffercopy = bufadr;
					}

				}
				++sgd;
			}	/* end while  */

			if (totalsectors)
				outblock (iop, bufadr, sectorstart, totalsectors, cv, NULL);	/* last one ? */
		}		/* end if scatter gather */
		else
			/* not scatter gather but is linear buffer */
		{

			outblock (iop, outbuffer, sectorstart, sectorcount, cv, bufadr);	/* get it to copy and do
												   large bit... */
		}
	}			/* end write op */

}

/* DoCallBack handles completion of an I/O request by calling the previous
   level's callback routine. */

void
DoCallBack (PIOP iop)
{
	_asm
	{			/* call back to previous layer */
		pushfd
		pushad
		mov ecx,[iop]
		sub[ecx] IOP.IOP_callback_ptr, size IOP_callback_entry
		mov eax,[ecx] IOP.IOP_callback_ptr
		push ecx
		call[eax] IOP_callback_entry.IOP_CB_address
		add esp, 4
		popad
		popfd

	}
}

VOID
partfilerequest (PIOP iop)
{
	PDCB dcb;
	cryptvol *cv;

	dcb = (PDCB) iop->IOP_physical_dcb;
	cv = (cryptvol *) dcb->DCB_Port_Specific;


	if ((cv != &cv1) && (cv != &cv2) && (cv != &cv3) && (cv != &cv4) && (cv != &cv5) && (cv != &cv6) && (cv != &cv7) && (cv != &cv8))
	{
		DoCallDown (iop);
		return;
	}

	if (cv->booted > 2)
	{
		ior.IOR_status = IORS_NOT_READY;	/* HW_FAILURE; */
		DoCallBack (iop);
		return;
	}

	if (ior.IOR_func == IOR_COMPUTE_GEOM)
	{
		dcb->DCB_actual_sector_cnt[0] = cv->cryptsectorlast - cv->cryptsectorfirst;
		dcb->DCB_actual_sector_cnt[0]++;
		dcb->DCB_actual_sector_cnt[1] = 0;
		dcb->DCB_actual_blk_size = 512;
		dcb->DCB_actual_head_cnt = 1;	/* number of heads */
		dcb->DCB_actual_cyl_cnt = 1;	/* number of cylinders */
		dcb->DCB_cmn.DCB_apparent_blk_shift = 9;
		dcb->DCB_cmn.DCB_TSD_Flags |= DCB_TSD_ACTUAL_PRE_SET;
		ior.IOR_status = IORS_SUCCESS;
		DoCallBack (iop);
		return;
	}

	if (ior.IOR_func == IOR_GEN_IOCTL)
	{
		iop->IOP_ior.IOR_ioctl_return = 01;
		ior.IOR_status = IORS_INVALID_PARM;	/* All the time now....  */
		DoCallBack (iop);
		return;
	}

	if ((ior.IOR_func == IOR_READ) || (ior.IOR_func == IOR_WRITE))
	{
		dcb = (PDCB) iop->IOP_physical_dcb;
		ior.IOR_status = IORS_CMD_IN_PROGRESS;	/* 0     */

		dcb->DCB_cmn.DCB_device_flags |= DCB_DEV_IO_ACTIVE;
		QueueMyIop (iop);
		return;
	}

	if ((ior.IOR_func == IOR_MEDIA_CHECK) || (ior.IOR_func == IOR_MEDIA_CHECK_RESET))
	{
		dcb = (PDCB) iop->IOP_original_dcb;

		ior.IOR_status = IORS_UNCERTAIN_MEDIA;	/* IORS_SUCCESS; */
		DoCallBack (iop);
		return;
	}

	ior.IOR_status = IORS_INVALID_COMMAND;
	DoCallBack (iop);
	return;
}

int
Add_Drive (PDCB dcb, cryptvol * cv, int prefdrive)
{
	int md = 0;
	PDCB ldcb;
	unsigned int flags;
	unsigned int dmdbits;
	ldcb = &cv->logicaldcb;
	cv->ldcb = ldcb;

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

	if (1)
	{
		ldcb = &cv->logicaldcb;
		flags = ldcb->DCB_cmn.DCB_device_flags;

		if (dcb)
			memcpy ((char *) ldcb, (char *) dcb, sizeof (DCB));

		ldcb->DCB_cmn.DCB_device_flags = flags;
		flags = dcb->DCB_cmn.DCB_device_flags;
		dmdbits = dcb->DCB_cmn.DCB_dmd_flags;
		dmdbits &= ~DCB_dmd_phys_sgd;
		cv->ldcb = ldcb;
		if (!cv->mountfilehandle)
			IspInsertCalldown (ldcb, partfilerequest, (PDDB) & cv->addb,
				 (USHORT) dcb->DCB_cmn.DCB_expansion_length,
					   dmdbits, (UCHAR) DRP_VSD_3);
		else
			IspInsertCalldown (ldcb, partfilerequest, (PDDB) & cv->addb, 0,
					   0, (UCHAR) DRP_VSD_3);

		ldcb->DCB_Port_Specific = (ULONG) cv;
		ldcb->DCB_cmn.DCB_physical_dcb = (ULONG) ldcb;
		ldcb->DCB_max_xfer_len = MAXBLOCK * 512;	/* 256*512 */

		if ((dcb->DCB_max_xfer_len < MAXBLOCK * 512) && (cv->mountfilehandle == 0))
			ldcb->DCB_max_xfer_len = dcb->DCB_max_xfer_len;

		if (!cv->mountfilehandle)
		{
			ldcb->DCB_max_sg_elements = dcb->DCB_max_sg_elements;	/* 1; */
			ldcb->DCB_cmn.DCB_expansion_length = dcb->DCB_cmn.DCB_expansion_length;
			ldcb->DCB_cmn.DCB_dmd_flags = dmdbits;
		}
		else
			ldcb->DCB_max_sg_elements = 17;

		ldcb->DCB_cmn.DCB_device_flags |= DCB_DEV_PHYSICAL;
		ldcb->DCB_cmn.DCB_device_flags2 = 0;
		ldcb->DCB_cmn.DCB_device_flags &= ~DCB_DEV_REMOVABLE;	/* support removable as
									   fixed... */
		ldcb->DCB_cmn.DCB_device_type = DEVICE_TYPE;
		ldcb->DCB_cmn.DCB_user_drvlet = (USHORT) md;
		ldcb->DCB_cmn.DCB_partition_type = 0;
		ldcb->DCB_cmn.DCB_Sstor_Host = 0;
		ldcb->DCB_actual_sector_cnt[0] = 0;
		ldcb->DCB_actual_sector_cnt[0]++;
		ldcb->DCB_actual_sector_cnt[1] = 0;
		ldcb->DCB_actual_blk_size = 512;
		ldcb->DCB_actual_head_cnt = 1;	/* number of heads */
		ldcb->DCB_actual_cyl_cnt = 1;	/* number of cylinders */
		ldcb->DCB_cmn.DCB_apparent_blk_shift = 9;
		ldcb->DCB_actual_spt = ldcb->DCB_actual_sector_cnt[0];
		ldcb->DCB_bdd.DCB_apparent_sector_cnt[0] = ldcb->DCB_actual_sector_cnt[0];
		ldcb->DCB_bdd.DCB_apparent_sector_cnt[1] = 0;
		ldcb->DCB_bdd.DCB_apparent_head_cnt = 1;
		ldcb->DCB_bdd.DCB_apparent_blk_size = 512;
		ldcb->DCB_bdd.DCB_apparent_cyl_cnt = 1;
		ldcb->DCB_bdd.DCB_apparent_spt = ldcb->DCB_actual_sector_cnt[0];
	}

	ldcb->DCB_cmn.DCB_drive_lttr_equiv = 0;
	ldcb->DCB_cmn.DCB_user_drvlet = 0;
	ldcb->DCB_cmn.DCB_device_type = DEVICE_TYPE;

	if (prefdrive != -1)
		md = IspDriveLetterPickPref (ldcb, (UCHAR) ISP_PDL_FL_USE_RANGE, (UCHAR) prefdrive);
	else
		md = (unsigned char) 255;


	if (md == 255)
		md = IspDriveLetterPick (ldcb, 0);

	ldcb->DCB_cmn.DCB_unit_number = (UCHAR) md;
	ldcb->DCB_cmn.DCB_vrp_ptr = 0;	/* clear the copied VRP pointer...... */
	ldcb->DCB_cmn.DCB_device_flags |= DCB_DEV_WRITEABLE;

	if (!(flags & DCB_DEV_WRITEABLE))
		ldcb->DCB_cmn.DCB_device_flags &= ~DCB_DEV_WRITEABLE;

	ldcb->DCB_cmn.DCB_drive_lttr_equiv = md;
	ldcb->DCB_cmn.DCB_user_drvlet = (UCHAR) md;
	ldcb->DCB_cmn.DCB_unit_number = (UCHAR) md;	/* 0;  */

	cv->drive = (ULONG) md;
	ldcb->DCB_cmn.DCB_TSD_Flags = DCB_TSD_APPARENT_PRE_SET | DCB_TSD_MBPB_PBR;
	ldcb->DCB_cmn.DCB_partition_type = 0;
	ldcb->DCB_cmn.DCB_device_flags &= ~DCB_DEV_TSD_PROCESSED;
	ldcb->DCB_cmn.DCB_Partition_Start = 0;
	ldcb->DCB_cmn.DCB_device_flags |= DCB_DEV_LOGICAL | DCB_DEV_MEDIA_CHANGED | DCB_DEV_UNCERTAIN_MEDIA;

	ldcb->DCB_cmn.DCB_cAssoc = 1;

	ldcb->DCB_cmn.DCB_user_drvlet = 0xFF;

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

	if ((md <= 26) && (md > 1))
	{
		IspAssociateDcb (ldcb, (char) md, ISP_D_A_FL_NOSHELLMSG);

		cv->notifytime = 2;	/* 2 second to notify arrival of disk */

		return 0;
	}

	return 1;
}

#define FIRST_READ_SIZE SECTOR_SIZE

int
trymountfile (PDCB dcb, cryptvol * cv, MOUNT_STRUCT * mf)
{
	USHORT offset;
	USHORT size;
	PIOP myiop;
	PIOR myior;
	int mounted = 0;
	char *readBuffer = NULL;

	if (dcb->DCB_cmn.DCB_device_type == DCB_type_disk)
	{
		int status;

		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;

		readBuffer = TCalloc (FIRST_READ_SIZE);
		if (readBuffer == NULL)
			goto error;

		dophysblock (myiop, cv->cryptsectorfirst, FIRST_READ_SIZE / 512, readBuffer, cv, IOR_READ);

		status = VolumeReadHeaderCache (mf->bCache, readBuffer, mf->szPassword,
					 mf->nPasswordLen, &cv->cryptoInfo);

		if (status != 0)
		{
			memset (cv, 0, sizeof (cryptvol));
			cv->cryptsectorfirst = 0x7fffffff;
			mounted = 0;
			goto error;
		}
		else
			cv->booted = 1;

		if (Add_Drive (dcb, cv, mf->nDosDriveNo) == 0)
		{
			mounted = 1;
		}
		else
		{
			/* No Drive letter available */
			memset (cv, 0, sizeof (cryptvol));
			cv->cryptsectorfirst = 0x7fffffff;
			mounted = -1;
		}

	      error:
		if (readBuffer != NULL)
			TCfree (readBuffer);

		IspDeallocMem ((PVOID) ((DWORD) myior - myior->IOR_private_client));
		return mounted;
	}

	return mounted;
}

void
readnullfilesize (int hand)
{
	int bytes;
	char buffer[512];
	R0_ReadFile (FALSE, hand, 0, 0, buffer, &bytes);
}

void
mountdiskfileR0 (MOUNT_STRUCT * mf)
{
	DWORD hfile;
	DWORD action;
	int tmf;
	int code;
	cryptvol *cv;
	int c;
	int writeable = 1;
	PDCB dcb;
	int flag = 0;
	unsigned char openflag = 0x81;

	char *fname = (char *) mf->wszVolume;


	installhook ();		/* only installs if not done already... */

	for (c = 0; c < NUMSLOTS; c++)
	{
		cv = cryptvols[c];
		if (strcmp (fname, (char *) &cv->mounted_file_name) == 0)
		{
			flag = 3 + 128;	/* already present */
			goto done;
		}
	}

	if (writeable)
	{
		code = R0_OpenCreateFile (FALSE, ACCESS_READWRITE | SHARE_DENYREADWRITE,
		      0, ACTION_OPENEXISTING, 0x81, fname, &hfile, &action);	/* R0_NO_CACHE(UBYTE)
										   ((R0_NO_CACHE)>>8) */

		if (code != 0)
		{
			writeable = 0;
			code = R0_OpenCreateFile (FALSE, ACCESS_READONLY | SHARE_DENYREAD,
						  0, ACTION_OPENEXISTING, 0x81, fname, &hfile, &action);	/* R0_NO_CACHE(UBYTE)
														   ((R0_NO_CACHE)>>8) */
		}

		if (code == 0)
			readnullfilesize (hfile);
	}
	else
	{
		code = R0_OpenCreateFile (FALSE, ACCESS_READONLY | SHARE_DENYREAD,
		      0, ACTION_OPENEXISTING, 0x81, fname, &hfile, &action);	/* R0_NO_CACHE(UBYTE)
										   ((R0_NO_CACHE)>>8) */

		if (code == 0)
			readnullfilesize (hfile);
	}

	if (code != 0)
	{
		flag = 1;
		goto done;
	}

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

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

⌨️ 快捷键说明

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