📄 tc9x.c
字号:
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 + -