📄 tc9x.c
字号:
sgd->BD_SG_Count = 0;
sgd++;
myior->IOR_sgd_lin_phys = (ULONG) sgd;
rstatus = myior->IOR_status;
myiop->IOP_timer = 40;
myiop->IOP_timer_orig = 40;
if (mydcb->DCB_cmn.DCB_Sstor_Host == FALSE)
{
if (IlbIntIoCriteria (myiop))
myior->IOR_flags |= IORF_DOUBLE_BUFFER;
IlbInternalRequest (myiop, mydcb, 0);
rstatus = myior->IOR_status;
if (iorop == IOR_READ)
{
/* checks for partion reads of simulated drives that
dont return either data or error.... */
if ((errnl[0] == 0xACE01DE4) &&
(errnl[1] == 0xEDB0CD01) &&
(errnl[2] == 0x4caf3321) &&
(errnl[3] == 0xa35a32c4))
rstatus = 16;
}
return rstatus;
}
return 16;
}
/* This routine finds partitions */
void
UsePartitionInfo (PDCB dcb, PIOP myiop, char *diskbuffer, unsigned int relative, int recursed, int *partnum,
MOUNT_STRUCT * mf, BOOL bVerifyOnly)
{
/* Note that this is recursive..... */
partitionrec *pr;
char *c;
char *ndb;
int flag = 0;
cryptvol *cv = NULL;
unsigned int ComputedStartSector;
unsigned int ComputedEndSector;
unsigned int cyl;
unsigned int cylsize;
unsigned int headsize;
#if EXTRA_INFO
_Debug_Printf_Service ("UsePartitionInfo\n");
#endif
c = diskbuffer;
ndb = c + 512; /* next disk buffer */
c += 0x1be;
headsize = dcb->DCB_bdd.DCB_apparent_spt;
cylsize = dcb->DCB_bdd.DCB_apparent_head_cnt;
cylsize = cylsize * headsize;
c = diskbuffer;
c += 0x1be;
pr = (partitionrec *) c;
cyl = (pr->ss) & (128 + 64);
cyl = cyl << 2;
cyl += pr->sc;
cyl *= cylsize; /* 16065; */
ComputedStartSector = pr->sh * headsize; /* 63; */
ComputedStartSector += (((pr->ss) & 63) - 1);
ComputedStartSector += cyl;
cyl = (pr->es) & (128 + 64);
cyl = cyl << 2;
cyl += pr->ec;
cyl *= cylsize; /* 16065; */
ComputedEndSector = pr->eh * headsize; /* 63 */
ComputedEndSector += (((pr->es) & 63) - 1);
ComputedEndSector += cyl;
ComputedEndSector = ComputedEndSector - ComputedStartSector;
ComputedEndSector += 1; /* allow for inclusive sectors... */
pr = (partitionrec *) c;
if (pr->boot == 0x80)
dcb_boot = dcb;
if ((pr->system == 5) || (pr->system == 0xF))
{
if (!recursed)
relative = pr->StartSector;
else
pr->StartSector += relative;
memset (ndb, 0, 512);
DiskRead (dcb, myiop, pr->StartSector, 1, ndb, IOR_READ);
UsePartitionInfo (dcb, myiop, ndb, relative, pr->StartSector, partnum, mf, bVerifyOnly); /* recursed, and also
offset */
}
else
{
if (recursed)
pr->StartSector += recursed;
if (--(*partnum) == 0)
{
if (bVerifyOnly == TRUE)
flag = 1;
else
flag = tryvol (dcb, myiop, pr, mf, &cv); /* partition 1 */
goto error;
}
}
pr++;
if (pr->boot == 0x80)
dcb_boot = dcb;
if ((pr->system == 5) || (pr->system == 0xF))
{
if (!recursed)
relative = pr->StartSector;
else
pr->StartSector += relative;
memset (ndb, 0, 512);
DiskRead (dcb, myiop, pr->StartSector, 1, ndb, IOR_READ);
UsePartitionInfo (dcb, myiop, ndb, relative, pr->StartSector, partnum, mf, bVerifyOnly); /* recursed, and also
offset */
}
else if (!recursed)
{
if (--(*partnum) == 0)
{
if (bVerifyOnly == TRUE)
flag = 1;
else
flag = tryvol (dcb, myiop, pr, mf, &cv); /* partition 2 */
goto error;
}
}
if (recursed)
goto error;
pr++;
if (pr->boot == 0x80)
dcb_boot = dcb;
if ((pr->system == 5) || (pr->system == 0xF))
{
if (!recursed)
relative = pr->StartSector;
else
pr->StartSector += relative;
memset (ndb, 0, 512);
DiskRead (dcb, myiop, pr->StartSector, 1, ndb, IOR_READ);
UsePartitionInfo (dcb, myiop, ndb, relative, pr->StartSector, partnum, mf, bVerifyOnly); /* recursed, and also
offset */
}
else if (!recursed)
{
if (--(*partnum) == 0)
{
if (bVerifyOnly == TRUE)
flag = 1;
else
flag = tryvol (dcb, myiop, pr, mf, &cv); /* partition 3 */
goto error;
}
}
pr++;
if (pr->boot == 0x80)
dcb_boot = dcb;
if ((pr->system == 5) || (pr->system == 0xF))
{
if (!recursed)
relative = pr->StartSector;
else
pr->StartSector += relative;
memset (ndb, 0, 512);
DiskRead (dcb, myiop, pr->StartSector, 1, ndb, IOR_READ);
UsePartitionInfo (dcb, myiop, ndb, relative, pr->StartSector, partnum, mf, bVerifyOnly); /* recursed, and also
offset */
}
else if (!recursed)
{
if (--(*partnum) == 0)
{
if (bVerifyOnly == TRUE)
flag = 1;
else
flag = tryvol (dcb, myiop, pr, mf, &cv); /* partition 4 */
goto error;
}
}
error:
#if EXTRA_INFO
_Debug_Printf_Service ("UsePartitionInfo end\n");
#endif
if (bVerifyOnly == TRUE)
{
if (flag == 1)
{
/* Return partition info in the 'diskbuffer' buffer */
char *peek = (char *) &pr->system;
unsigned long *tmp = (void *) partitiontestbuffer;
unsigned long secstart, seclast;
mf->nReturnCode = 0;
peek -= 4;
peek += 8; /* point at starting sector... */
secstart = *(unsigned long *) peek;
peek += 4;
seclast = (secstart + *(unsigned long *) peek);
if (pr->boot == 0x80)
{
/* For safety reasons we return 0 length for
the boot device */
seclast = secstart;
}
tmp[0] = secstart;
tmp[1] = seclast;
tmp[2] = (unsigned long) dcb; /* device */
}
}
else if (cv != NULL)
{
/* cv is only set by tryvol, flag is set only when cv is set */
switch (flag)
{
case 0:
mf->nReturnCode = ERR_VOL_MOUNT_FAILED;
break;
case 1:
mf->nReturnCode = 0;
mf->nDosDriveNo = cv->drive;
strcpy (cv->mounted_file_name, (char *) mf->wszVolume);
break;
case -1:
mf->nReturnCode = ERR_NO_FREE_DRIVES;
break;
}
}
}
int
tryvol (PDCB dcb, PIOP myiop, partitionrec * pr, MOUNT_STRUCT * mf, cryptvol ** pcv)
{
cryptvol *cv;
char *readBuffer;
int mounted = 0;
readBuffer = TCalloc (FIRST_READ_SIZE);
if (readBuffer == NULL)
goto error;
if (cv = checkpartition (myiop, pr))
{
if (cv->booted == 0)
{
int status;
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)
{
cv->filehostdcb = dcb;
lockdrive (cv->filehostdcb, myiop, 1);
mounted = 1;
}
else
{
/* No Drive letter available */
memset (cv, 0, sizeof (cryptvol));
cv->cryptsectorfirst = 0x7fffffff;
mounted = -1;
}
}
}
else
{
/* If the checkpartition fails it could be because the
partitions is already mounted or because there are no free
slots */
mounted = 0;
}
error:
if (readBuffer != NULL)
TCfree (readBuffer);
*pcv = cv;
return mounted;
}
struct cryptvol *
checkpartition (PIOP iop, partitionrec * pr)
{
cryptvol *flag = 0;
cryptvol *cv;
PDCB dcb = (PDCB) iop->IOP_physical_dcb;
char *peek = (char *) &pr->system;
pr->system = 0x74;
if (pr->system == 0x74)
{
if (cv = addcryptedpartition (iop, peek))
{
flag = cv;
}
}
return flag;
}
int
cmppart (PDCB dcb, unsigned int secstart, cryptvol * cv)
{
if (cv->physdevDCB != dcb)
return 0;
if (cv->cryptsectorfirst != secstart)
return 0;
return 1;
}
struct cryptvol *
addcryptedpartition (PIOP iop, char *peek)
{
unsigned int secstart;
unsigned int seclast;
PDCB device;
int d;
peek -= 4;
peek += 8; /* point at starting sector... */
secstart = *(unsigned long *) peek;
peek += 4;
seclast = (secstart + *(unsigned long *) peek);
device = (PDCB) iop->IOP_physical_dcb;
/* have we got it already ? */
if (cmppart (device, secstart, (cryptvol *) & cv1))
return NULL;
if (cmppart (device, secstart, (cryptvol *) & cv2))
return NULL;
if (cmppart (device, secstart, (cryptvol *) & cv3))
return NULL;
if (cmppart (device, secstart, (cryptvol *) & cv4))
return NULL;
if (cmppart (device, secstart, (cryptvol *) & cv5))
return NULL;
if (cmppart (device, secstart, (cryptvol *) & cv6))
return NULL;
if (cmppart (device, secstart, (cryptvol *) & cv7))
return NULL;
if (cmppart (device, secstart, (cryptvol *) & cv8))
return NULL;
d = tryaddpart ((cryptvol *) & cv1, secstart, seclast, device);
if (d == 1)
return &cv1;
if (d == 2)
return 0;
d = tryaddpart ((cryptvol *) & cv2, secstart, seclast, device);
if (d == 1)
return &cv2;
if (d == 2)
return 0;
d = tryaddpart ((cryptvol *) & cv3, secstart, seclast, device);
if (d == 1)
return &cv3;
if (d == 2)
return 0;
d = tryaddpart ((cryptvol *) & cv4, secstart, seclast, device);
if (d == 1)
return &cv4;
if (d == 2)
return 0;
d = tryaddpart ((cryptvol *) & cv5, secstart, seclast, device);
if (d == 1)
return &cv5;
if (d == 2)
return 0;
d = tryaddpart ((cryptvol *) & cv6, secstart, seclast, device);
if (d == 1)
return &cv6;
if (d == 2)
return 0;
d = tryaddpart ((cryptvol *) & cv7, secstart, seclast, device);
if (d == 1)
return &cv7;
if (d == 2)
return 0;
d = tryaddpart ((cryptvol *) & cv8, secstart, seclast, device);
if (d == 1)
return &cv8;
if (d == 2)
return 0;
return NULL;
}
int
tryaddpart (cryptvol * cv, unsigned int secstart, unsigned int seclast, PDCB device)
{
/* THIS if CAN NEVER BE TRUE because cmppart does this job before
this func is called */
if ((cv->physdevDCB == device) && (cv->cryptsectorfirst == secstart))
return (2);
if (cv->physdevDCB == 0)
{
cv->physdevDCB = device;
cv->cryptsectorfirst = secstart;
cv->cryptsectorlast = seclast;
return (1);
}
return (0);
}
int
unlockdrive (cryptvol * cv)
{
PDCB dcb = cv->filehostdcb; /* physdevDCB; */
PIOP myiop;
PIOR myior;
USHORT offset;
USHORT size;
if (!dcb)
return -1;
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;
lockdrive (dcb, myiop, 0); /* unlock it! */
IspDeallocMem ((PVOID) ((DWORD) myior - myior->IOR_private_client));
return 1;
}
int
lockdrive (PDCB mydcb, PIOP myiop, int lockmode)
{
PIOR myior;
int rstatus;
int iorop;
if (!mydcb)
return -1;
if (lockmode)
iorop = IOR_LOCK_MEDIA;
else
iorop = IOR_UNLOCK_MEDIA;
if ((mydcb->DCB_cmn.DCB_device_flags & DCB_DEV_REMOVABLE) == 0)
return -1;
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 = 0;
myior->IOR_vol_designtr = 0xff;
myior->IOR_func = iorop;
myior->IOR_flags |= IORF_BYPASS_VOLTRK | IORF_HIGH_PRIORITY | IORF_SYNC_COMMAND;
myior->IOR_start_addr[0] = 0;
myior->IOR_xfer_count = 0;
myior->IOR_buffer_ptr = 0;
myiop->IOP_timer = 40;
myiop->IOP_timer_orig = 40;
IlbInternalRequest (myiop, mydcb, 0);
rstatus = myior->IOR_status;
return rstatus;
}
/* the ring 0 code to allow win32 gui to access disk sectors */
int
AppAccessBlockDevice (unsigned int devicenum, unsigned int sectorstart, unsigned int sectorlen, char *buffer, int mode)
{
PDCB dcb;
USHORT offset;
USHORT size;
PIOP myiop;
PIOR myior;
int status;
USHORT diskop;
if (mode == 0)
diskop = IOR_READ;
else
diskop = IOR_WRITE;
if (devicenum < 128)
dcb = dcblist[devicenum + 1];
else
dcb = (PDCB) devicenum;
if (diskop == IOR_WRITE && dcb == dcb_boot)
{
if (sectorstart == 0)
{
return ERR_ACCESS_DENIED;
}
}
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;
if (diskop == IOR_WRITE)
memcpy (appaccessbuffer, buffer, sectorlen * 512);
status = DiskRead (dcb, myiop, sectorstart, sectorlen, appaccessbuffer, diskop); /* mode later...... */
if (diskop == IOR_READ)
memcpy (buffer, appaccessbuffer, sectorlen * 512);
IspDeallocMem ((PVOID) ((DWORD) myior - myior->IOR_private_client));
if (status != 0)
{
if (mode == 0)
status = ERR_VOL_READING;
else
status = ERR_VOL_WRITING;
}
return status;
}
/* This code informs Windows of a drives arrival, this code
crashes windows 95 for some cd's; so it's currently never called */
void
drivearrived (void)
{
cryptvol *cv;
int c;
for (c = 0; c < 8; c++)
{
cv = cryptvols[c];
if (cv->notifytime & 0x80000000)
{
cv->notifytime = 0;
IFSMgr_PNPEvent (DBT_DEVICEARRIVAL, cv->drive, PNPT_VOLUME | DBTF_MEDIA );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -