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