home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Beijing Paradise BBS Backup
/
PARADISE.ISO
/
software
/
BBSDOORW
/
SHSUCD11.ZIP
/
CDCACHER.C
next >
Wrap
Text File
|
1995-12-06
|
11KB
|
436 lines
/*
* CDCACHER v 4.0
*
* CDCACHER makes a hard disk cache image from a CD. The CD ROM
* Server program, SHSUSERV, can then read from this cache or
* the pseudo CD ROM driver program, SHSUCDH, can make it appear
* as a CD drive. The cache image can be located on a local HD
* or on a network file server.
*
* A DOS program. CDCACHER is a complete re-write in C (was ADA) and
* uses the C/Windows Toolchest from MIX Software. It reads and
* writes multiple CD ROM blocks which makes it significantly faster
* than the previous versions. To re-compile you must have the Toolchest.
*
*
* A copyright-reserved, free use program. Use at your own risk.
* (c)John H. McCoy, 1995 Sam Houston St. Univ., TX 77341-2206
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <dos.h>
#include <string.h>
#include <malloc.h>
#include <signal.h>
#include "winlib.h"
#pragma pack(1)
#define cdRdLong 0x80
#define canonicalize 0x60
#define PriVolDescSector 16
#define ISO_ID "CD001"
#define HSF_ID "CDROM"
#define CD_ISO 'I'
#define CD_HSF 'H'
#define CD_Unknown 'U'
#define OCTETS(from,to) (to - from +1)
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;
struct ISO_CD {
BYTE Fill [OCTETS(1,1)];
char cdID [OCTETS(2,6)];
BYTE Fill2 [OCTETS(7,40)];
char volLabel [OCTETS(41,72)];
BYTE Fill3 [OCTETS(73,80)];
DWORD volSize;
BYTE Fill4 [OCTETS(89,2048)];
} far *iso;
struct HSF_CD {
BYTE Fill [OCTETS(1,9)];
char cdID [OCTETS(10,14)];
BYTE Fill2 [OCTETS(15,48)];
char volLabel [OCTETS(49,80)];
BYTE Fill3 [OCTETS(81,88)];
DWORD volSize;
BYTE Fill4 [OCTETS(97,2048)];
} far * hsf;
struct RH{
BYTE hdrLength;
BYTE drvUnit;
BYTE drvCmd;
WORD drvStatus;
BYTE x[9];
BYTE far *pdta;
WORD sectors;
DWORD startSector;
BYTE mode;
};
int GetValidDriver(void);
int GetDriverAddress(char * cdDriver);
void CanonCacheName(char *CacheName);
int GetCDLabel(void);
int GetCacheName(void);
void CacheCD(BYTE Unit);
void CallDev(struct RH far *);
int CDReadLong(BYTE Unit, WORD SectorCount, DWORD StartSector);
int ReadPVD(BYTE Unit);
int PauseContinue(void);
void SetSigFlag(void);
void (far *DevStrategy)();
void (far *DevInterrupt)();
char *copyrite = " CDCACHE v4.0, (c)1995, John H. McCoy, CSC_JHM@SHSU.EDU ";
char CD = CD_Unknown;
char *cdDriver = "MSCD001 ";
char far dta[30*2048];
char far *pdta=dta;
char CacheName[64]={".\\CD.IMG"};
BYTE LastUnit;
int SigFlag = 0;
int main (int argc, char **argv){
Window wd;
int col=5, row=1, width=68, height=1;
union REGS regs;
struct SREGS sregs;
BYTE Unit;
int rc;
int handle;
width= strlen( copyrite);
col = (80-width)/2;
wd = w_open(col, row, width, height);
w_print(wd,copyrite);
if (argc > 1){
if ((((argv[1][0] == '-') ||(argv[1][0] == '/'))&& (argv[1][1] == '?'))
|| (argv[1][0] == '?')){
printf ("CACHCECD [DriverName] \n");
goto done;
}
else cdDriver = argv[1];
}
iso = (struct ISO_CD *) pdta;
hsf = (struct HSF_CD *) pdta;
do {
if (GetValidDriver() == -1){
printf("No valid CD Driver. Aborted.\n");
goto done;
}
rc = GetCDLabel();
}
while (rc < 0);
Unit = rc;
if (GetCacheName() == -1){
printf("User selected Quit.\n");
goto done;
}
CanonCacheName(CacheName);
handle = open(CacheName, O_BINARY);
if (handle != -1){
printf("%s already exists.\n",CacheName);
printf("Delete file and re-run or re-run with different cache name.\n");
close(handle);
}
else
CacheCD(Unit);
done:
w_close(wd);
}
void SetSigFlag(void){
++SigFlag;
}
int ValidateCacheName(Field fd, int lastkey){
Window wd;
int col=5, row=4, width=68, height=3;
char tempCache[64];
if (lastkey == _ESC) return FD_OK;
f_getstring(fd,tempCache);
CanonCacheName(tempCache);
if (open(tempCache, O_BINARY|O_RDONLY, S_IWRITE)!=-1){
close(tempCache);
wd = w_open(col, row, width, height);
w_umessage(wd,"Cache File Already Exists");
w_lmessage(wd,"Press a key to Continue");
w_print(wd,tempCache);
k_getkey();
w_close(wd);
return FD_ERR;
}
else
return FD_OK;
}
int GetCacheName(){
Window wd;
Field fd;
char *fdData
="________________________________________________________________";
int col=5, row=4, width=68, height=3;
int field_col=1, field_row=1;
int xkey;
wd = w_open(col, row, width, height);
w_umessage(wd,"Cache File Name");
w_lmessage(wd,"ESC to Quit");
fd = f_create("", fdData);
f_startclear(fd,ENABLE);
f_return(fd,ENABLE);
f_setbuffer(fd,CacheName);
f_validate(fd,ValidateCacheName,DISABLE);
xkey = f_process(wd, field_col, field_row, fd);
f_getstring(fd,CacheName);
f_free(fd);
w_close(wd);
if (xkey == _ESC) return -1;
else return 0;
}
void CanonCacheName(char *CacheName){
union REGS regs;
struct SREGS sregs;
char *pCacheName;
pCacheName = CacheName;
regs.h.ah = canonicalize;
regs.x.di = FP_OFF(pCacheName);
regs.x.si = FP_OFF(pCacheName);
sregs.es = FP_SEG(pCacheName);
sregs.ds = FP_SEG(pCacheName);
int86x (0x21,®s,®s,&sregs);
}
void CacheCD(BYTE Unit){
DWORD i,n, volSize;
int handle;
union REGS regs;
struct SREGS sregs;
Window wd;
int col=5, row=4, width=68, height=1;
(void)ReadPVD(Unit);
if(CD==CD_ISO)
volSize = iso->volSize;
else if (CD==CD_HSF)
volSize = hsf->volSize;
else{
printf("Unkown CD Format. Can't cache it.\n");
return;
}
for (i=0;i<sizeof dta;i++){dta[i]=0;}
wd = w_open(col, row, width, height);
w_umessage(wd,"Creating Cache File ");
w_lmessage(wd,"Control Break to interrupt");
handle = open(CacheName, O_BINARY|O_CREAT|O_WRONLY,S_IWRITE);
n = 15;
(void)write(handle,pdta, n*2048);
SigFlag = 0;
signal(SIGINT, SetSigFlag);
i = n+1;
while (i < volSize){
n = volSize - i;
w_printf(wd,"Writing block %ld of %ld to %s.\n",i,volSize,CacheName);
if (n>=30){
(void)CDReadLong(Unit,30,i);
(void)write(handle,pdta, 61440);
i += 30;
}
else {
(void)CDReadLong(Unit,n,i);
(void)write(handle,pdta, n*2048);
i += n;
}
if (SigFlag != 0){
if (PauseContinue() == -1) break;
else{
SigFlag=0;
signal(SIGINT, SetSigFlag);
}
}
}
w_close(wd);
close (handle);
}
int PauseContinue(void){
int xkey;
Window wd;
int col=15, row=10, width=48, height=1;
wd = w_open(col, row, width, height);
w_umessage(wd,"Control Break ");
w_print(wd," Press ESC to Quit, any other key to continue.");
xkey=k_getkey();
w_close(wd);
if (xkey==_ESC)
return(-1);
else
return (0);
}
void CallDev(struct RH far * ptr){
_asm push bx
_asm push es
_asm mov bx, [bp+8]
_asm mov es, bx
_asm mov bx, [bp+6]
_asm call DevStrategy
_asm call DevInterrupt
_asm pop es
_asm pop bx
}
int CDReadLong(BYTE Unit, WORD SectorCount, DWORD StartSector){
int i;
struct RH rh;
rh.hdrLength = sizeof (rh);
for (i=0;i<9;i++){rh.x[i]=0;}
rh.drvStatus = 0;
rh.mode = 0;
rh.drvCmd = cdRdLong;
rh.pdta = pdta;
rh.sectors = SectorCount;
rh.startSector = StartSector;
rh.drvUnit = Unit;
/* printf("Reading unit %d \n",Unit);*/
CallDev(&rh);
}
int ReadPVD(BYTE Unit){
(void)CDReadLong(Unit,1,PriVolDescSector);
if(strncmp(iso->cdID,ISO_ID,sizeof(iso->cdID))==0)
CD=CD_ISO;
else if (strncmp(hsf->cdID,HSF_ID,sizeof(hsf->cdID))==0)
CD=CD_HSF;
else
CD=CD_Unknown;
}
int GetCDLabel(void){
Window wd;
Field fd;
char cdLabel[15];
int col=22, row=4, width=21, height=15;
int i,xkey;
Control lb;
BYTE Unit;
strncpy(cdLabel," ",4);
wd = w_open(col, row, width, height);
w_umessage(wd,cdDriver);
w_lmessage(wd,"ESC for New Driver");
lb = c_add_listbox(wd," Drive Label ",2,1,17,13,LISTBOX_SORT);
for (Unit=0; Unit<=LastUnit; Unit++){
(void)ReadPVD(Unit);
if (CD=='I')
strncpy(&cdLabel[4],iso->volLabel,11);
else if (CD=='H')
strncpy(&cdLabel[4],hsf->volLabel,11);
else
strncpy(&cdLabel[4],"Unknown Fmt",11);
i=Unit;
i/=10;
cdLabel[1] = '0'+i;
i=Unit;
i%=10;
cdLabel[2] = '0'+i;
c_add_item(lb,cdLabel,-1,ENABLE);
}
xkey=c_dialog(wd);
if (xkey == _ESC){
w_close(wd);
return -1;
}
else{
Unit = c_read(lb,C_STATE);
w_close(wd);
return Unit;
}
}
int ValidateDriverName(Field fd, int lastkey){
char tempDriver[12];
if (lastkey == _ESC) return FD_OK;
f_getstring(fd,tempDriver);
if (GetDriverAddress(tempDriver)==-1)
return FD_ERR;
else
return FD_OK;
}
int GetValidDriver(){
Window wd;
Field fd;
char *devName="________";
int col=5, row=4, width=15, height=4;
int field_col=3, field_row=1;
int xkey; /* don't declare lastkey if using f_validate */
wd = w_open(col, row, width, height);
w_umessage(wd,"CD DRIVER");
w_lmessage(wd,"ESC to Quit");
fd = f_create("", devName);
f_validate(fd,ValidateDriverName,DISABLE);
f_startclear(fd,ENABLE);
f_return(fd,ENABLE);
f_setbuffer(fd,cdDriver);
xkey = f_process(wd, field_col, field_row, fd);
f_getstring(fd,cdDriver);
f_free(fd);
w_close(wd);
if (xkey == _ESC) return -1;
else return 0;
}
int GetDriverAddress(char *cdDriver){
int handle;
union REGS regs;
struct SREGS sregs;
struct DTA {
char cmd;
char far * pdevHdr;
} dta;
struct DTA far *pdta;
handle = open( cdDriver, O_BINARY);
if (handle==-1) return(-1);
dta.cmd = 0;
pdta = &dta;
regs.h.ah = 0x44;
regs.h.al = 0x02;
regs.x.bx = handle;
regs.x.cx = 5;
sregs.ds = FP_SEG(pdta);
regs.x.dx = FP_OFF(pdta);
int86x (0x21,®s,®s,&sregs);
close(handle);
if (regs.x.cflag) return(-1);
FP_SEG(DevStrategy) = FP_SEG(dta.pdevHdr);
FP_OFF(DevStrategy) = *(int far *)(dta.pdevHdr+6);
FP_SEG(DevInterrupt) = FP_SEG(dta.pdevHdr);
FP_OFF(DevInterrupt) = *(int far *)(dta.pdevHdr+8);
LastUnit = *(dta.pdevHdr+21) - 1;
return (0);
}