home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / SHSUCD11.ZIP / CDCACHER.C next >
Text File  |  1995-12-06  |  11KB  |  436 lines

  1. /*
  2.  *   CDCACHER  v 4.0
  3.  *
  4.  *     CDCACHER makes a hard disk cache image from a CD.  The CD ROM
  5.  *     Server program, SHSUSERV, can then read from this cache or
  6.  *     the pseudo CD ROM driver program, SHSUCDH, can make it appear
  7.  *     as a CD drive.  The cache image can be located on a local HD
  8.  *     or on a network file server.
  9.  *
  10.  *     A DOS program.  CDCACHER is a complete re-write in C (was ADA) and
  11.  *     uses the C/Windows Toolchest from MIX Software.  It reads and
  12.  *     writes multiple CD ROM blocks which makes it significantly faster
  13.  *     than the previous versions.  To re-compile you must have the Toolchest.
  14.  *
  15.  *
  16.  *  A copyright-reserved, free use program.  Use at your own risk.
  17.  *  (c)John H. McCoy, 1995 Sam Houston St. Univ., TX 77341-2206
  18.  *
  19.  */
  20.  
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <fcntl.h>
  24. #include <sys\types.h>
  25. #include <sys\stat.h>
  26. #include <dos.h>
  27. #include <string.h>
  28. #include <malloc.h>
  29. #include <signal.h>
  30.  
  31. #include "winlib.h"
  32.  
  33. #pragma pack(1)
  34.  
  35. #define cdRdLong 0x80
  36. #define canonicalize 0x60
  37. #define PriVolDescSector 16
  38. #define ISO_ID "CD001"
  39. #define HSF_ID "CDROM"
  40. #define CD_ISO 'I'
  41. #define CD_HSF 'H'
  42. #define CD_Unknown 'U'
  43.  
  44. #define OCTETS(from,to) (to - from +1)
  45.  
  46. typedef unsigned char BYTE;
  47. typedef unsigned int  WORD;
  48. typedef unsigned long DWORD;
  49.  
  50. struct ISO_CD {
  51.   BYTE     Fill      [OCTETS(1,1)];
  52.   char     cdID      [OCTETS(2,6)];
  53.   BYTE     Fill2     [OCTETS(7,40)];
  54.   char     volLabel  [OCTETS(41,72)];
  55.   BYTE     Fill3     [OCTETS(73,80)];
  56.   DWORD    volSize;
  57.   BYTE     Fill4     [OCTETS(89,2048)];
  58. } far *iso;
  59. struct HSF_CD {
  60.   BYTE     Fill      [OCTETS(1,9)];
  61.   char     cdID      [OCTETS(10,14)];
  62.   BYTE     Fill2     [OCTETS(15,48)];
  63.   char     volLabel  [OCTETS(49,80)];
  64.   BYTE     Fill3     [OCTETS(81,88)];
  65.   DWORD    volSize;
  66.   BYTE     Fill4     [OCTETS(97,2048)];
  67. } far * hsf;
  68.  
  69. struct RH{
  70.   BYTE   hdrLength;
  71.   BYTE   drvUnit;
  72.   BYTE   drvCmd;
  73.   WORD   drvStatus;
  74.   BYTE   x[9];
  75.   BYTE   far *pdta;
  76.   WORD   sectors;
  77.   DWORD  startSector;
  78.   BYTE   mode;
  79.   };
  80.  
  81. int GetValidDriver(void);
  82. int GetDriverAddress(char * cdDriver);
  83. void CanonCacheName(char *CacheName);
  84. int GetCDLabel(void);
  85. int GetCacheName(void);
  86. void CacheCD(BYTE Unit);
  87. void CallDev(struct RH far *);
  88. int  CDReadLong(BYTE Unit, WORD SectorCount, DWORD StartSector);
  89. int  ReadPVD(BYTE Unit);
  90. int  PauseContinue(void);
  91. void SetSigFlag(void);
  92. void (far *DevStrategy)();
  93. void (far *DevInterrupt)();
  94.  
  95. char   *copyrite = " CDCACHE v4.0, (c)1995, John H. McCoy, CSC_JHM@SHSU.EDU ";
  96. char   CD = CD_Unknown;
  97. char   *cdDriver = "MSCD001 ";
  98. char   far dta[30*2048];
  99. char   far *pdta=dta;
  100. char   CacheName[64]={".\\CD.IMG"};
  101. BYTE   LastUnit;
  102. int    SigFlag = 0;
  103.  
  104. int main (int argc, char **argv){
  105.     Window    wd;
  106.     int       col=5, row=1, width=68, height=1;
  107.     union REGS      regs;
  108.     struct SREGS    sregs;
  109.     BYTE            Unit;
  110.     int             rc;
  111.     int             handle;
  112.  
  113.     width= strlen( copyrite);
  114.     col = (80-width)/2;
  115.     wd = w_open(col, row, width, height);
  116.     w_print(wd,copyrite);
  117.  
  118.     if (argc > 1){
  119.       if ((((argv[1][0] == '-') ||(argv[1][0] == '/'))&& (argv[1][1] == '?'))
  120.          || (argv[1][0] == '?')){
  121.             printf ("CACHCECD [DriverName] \n");
  122.             goto done;
  123.       }
  124.       else cdDriver = argv[1];
  125.     }
  126.     iso = (struct ISO_CD *) pdta;
  127.     hsf = (struct HSF_CD *) pdta;
  128.     do {
  129.        if (GetValidDriver() == -1){
  130.           printf("No valid CD Driver.  Aborted.\n");
  131.           goto done;
  132.           }
  133.        rc = GetCDLabel();
  134.        }
  135.     while (rc < 0);
  136.     Unit = rc;
  137.     if (GetCacheName() == -1){
  138.           printf("User selected Quit.\n");
  139.           goto done;
  140.           }
  141.     CanonCacheName(CacheName);
  142.     handle = open(CacheName, O_BINARY);
  143.     if (handle != -1){
  144.        printf("%s already exists.\n",CacheName);
  145.        printf("Delete file and re-run or re-run with different cache name.\n");
  146.        close(handle);
  147.        }
  148.     else
  149.        CacheCD(Unit);
  150.  
  151.  done:
  152.     w_close(wd);
  153. }
  154.  
  155. void SetSigFlag(void){
  156.   ++SigFlag;
  157. }
  158.  
  159. int ValidateCacheName(Field fd, int lastkey){
  160.     Window    wd;
  161.     int       col=5, row=4, width=68, height=3;
  162.     char tempCache[64];
  163.  
  164.    if (lastkey == _ESC) return FD_OK;
  165.    f_getstring(fd,tempCache);
  166.    CanonCacheName(tempCache);
  167.  
  168.    if (open(tempCache, O_BINARY|O_RDONLY, S_IWRITE)!=-1){
  169.      close(tempCache);
  170.      wd = w_open(col, row, width, height);
  171.      w_umessage(wd,"Cache File Already Exists");
  172.      w_lmessage(wd,"Press a key to Continue");
  173.      w_print(wd,tempCache);
  174.      k_getkey();
  175.      w_close(wd);
  176.      return FD_ERR;
  177.      }
  178.    else
  179.      return FD_OK;
  180. }
  181.  
  182. int GetCacheName(){
  183.     Window    wd;
  184.     Field     fd;
  185.     char      *fdData
  186.           ="________________________________________________________________";
  187.     int       col=5, row=4, width=68, height=3;
  188.     int       field_col=1, field_row=1;
  189.     int       xkey;
  190.  
  191.     wd = w_open(col, row, width, height);
  192.     w_umessage(wd,"Cache File Name");
  193.     w_lmessage(wd,"ESC to Quit");
  194.     fd = f_create("", fdData);
  195.     f_startclear(fd,ENABLE);
  196.     f_return(fd,ENABLE);
  197.     f_setbuffer(fd,CacheName);
  198.     f_validate(fd,ValidateCacheName,DISABLE);
  199.     xkey = f_process(wd, field_col, field_row, fd);
  200.     f_getstring(fd,CacheName);
  201.     f_free(fd);
  202.     w_close(wd);
  203.     if (xkey == _ESC) return -1;
  204.     else return 0;
  205. }
  206.  
  207. void CanonCacheName(char *CacheName){
  208.    union REGS      regs;
  209.    struct SREGS    sregs;
  210.    char *pCacheName;
  211.  
  212.    pCacheName = CacheName;
  213.    regs.h.ah = canonicalize;
  214.    regs.x.di = FP_OFF(pCacheName);
  215.    regs.x.si = FP_OFF(pCacheName);
  216.    sregs.es = FP_SEG(pCacheName);
  217.    sregs.ds = FP_SEG(pCacheName);
  218.    int86x (0x21,®s,®s,&sregs);
  219. }
  220.  
  221. void CacheCD(BYTE Unit){
  222.    DWORD     i,n, volSize;
  223.    int       handle;
  224.    union REGS      regs;
  225.    struct SREGS    sregs;
  226.    Window    wd;
  227.    int       col=5, row=4, width=68, height=1;
  228.  
  229.    (void)ReadPVD(Unit);
  230.    if(CD==CD_ISO)
  231.       volSize = iso->volSize;
  232.    else if (CD==CD_HSF)
  233.       volSize = hsf->volSize;
  234.    else{
  235.       printf("Unkown CD Format.  Can't cache it.\n");
  236.       return;
  237.    }
  238.  
  239.    for (i=0;i<sizeof dta;i++){dta[i]=0;}
  240.  
  241.    wd = w_open(col, row, width, height);
  242.    w_umessage(wd,"Creating Cache File ");
  243.    w_lmessage(wd,"Control Break to interrupt");
  244.    handle = open(CacheName, O_BINARY|O_CREAT|O_WRONLY,S_IWRITE);
  245.    n = 15;
  246.    (void)write(handle,pdta, n*2048);
  247.    SigFlag = 0;
  248.    signal(SIGINT, SetSigFlag);
  249.    i = n+1;
  250.    while (i < volSize){
  251.      n = volSize - i;
  252.    w_printf(wd,"Writing block %ld of %ld to %s.\n",i,volSize,CacheName);
  253.      if (n>=30){
  254.         (void)CDReadLong(Unit,30,i);
  255.         (void)write(handle,pdta, 61440);
  256.         i += 30;
  257.         }
  258.      else {
  259.         (void)CDReadLong(Unit,n,i);
  260.         (void)write(handle,pdta, n*2048);
  261.         i += n;
  262.         }
  263.      if (SigFlag != 0){
  264.        if (PauseContinue() == -1) break;
  265.        else{
  266.           SigFlag=0;
  267.           signal(SIGINT, SetSigFlag);
  268.        }
  269.      }
  270.    }
  271.  
  272.    w_close(wd);
  273.    close (handle);
  274. }
  275.  
  276. int PauseContinue(void){
  277.    int       xkey;
  278.    Window    wd;
  279.    int       col=15, row=10, width=48, height=1;
  280.    wd = w_open(col, row, width, height);
  281.    w_umessage(wd,"Control Break ");
  282.    w_print(wd,"  Press ESC to Quit, any other key to continue.");
  283.    xkey=k_getkey();
  284.    w_close(wd);
  285.    if (xkey==_ESC)
  286.       return(-1);
  287.    else
  288.       return (0);
  289.  
  290. }
  291.  
  292. void CallDev(struct RH far * ptr){
  293.     _asm  push     bx
  294.     _asm  push     es
  295.     _asm  mov      bx, [bp+8]
  296.     _asm  mov      es, bx
  297.     _asm  mov      bx, [bp+6]
  298.     _asm  call     DevStrategy
  299.     _asm  call     DevInterrupt
  300.     _asm  pop      es
  301.     _asm  pop      bx
  302. }
  303.  
  304. int CDReadLong(BYTE Unit, WORD SectorCount, DWORD StartSector){
  305.    int i;
  306.    struct RH rh;
  307.    rh.hdrLength = sizeof (rh);
  308.    for (i=0;i<9;i++){rh.x[i]=0;}
  309.    rh.drvStatus = 0;
  310.    rh.mode = 0;
  311.    rh.drvCmd = cdRdLong;
  312.    rh.pdta = pdta;
  313.    rh.sectors = SectorCount;
  314.    rh.startSector = StartSector;
  315.    rh.drvUnit = Unit;
  316. /*   printf("Reading unit %d \n",Unit);*/
  317.    CallDev(&rh);
  318. }
  319. int ReadPVD(BYTE Unit){
  320.    (void)CDReadLong(Unit,1,PriVolDescSector);
  321.    if(strncmp(iso->cdID,ISO_ID,sizeof(iso->cdID))==0)
  322.       CD=CD_ISO;
  323.    else if (strncmp(hsf->cdID,HSF_ID,sizeof(hsf->cdID))==0)
  324.       CD=CD_HSF;
  325.    else
  326.       CD=CD_Unknown;
  327. }
  328.  
  329. int GetCDLabel(void){
  330.     Window    wd;
  331.     Field     fd;
  332.     char      cdLabel[15];
  333.     int       col=22, row=4, width=21, height=15;
  334.     int       i,xkey;
  335.     Control   lb;
  336.     BYTE      Unit;
  337.     strncpy(cdLabel,"    ",4);
  338.     wd = w_open(col, row, width, height);
  339.     w_umessage(wd,cdDriver);
  340.     w_lmessage(wd,"ESC for New Driver");
  341.     lb = c_add_listbox(wd," Drive  Label ",2,1,17,13,LISTBOX_SORT);
  342.     for (Unit=0; Unit<=LastUnit; Unit++){
  343.       (void)ReadPVD(Unit);
  344.       if (CD=='I')
  345.          strncpy(&cdLabel[4],iso->volLabel,11);
  346.       else if (CD=='H')
  347.          strncpy(&cdLabel[4],hsf->volLabel,11);
  348.       else
  349.          strncpy(&cdLabel[4],"Unknown Fmt",11);
  350.       i=Unit;
  351.       i/=10;
  352.       cdLabel[1] = '0'+i;
  353.       i=Unit;
  354.       i%=10;
  355.       cdLabel[2] = '0'+i;
  356.       c_add_item(lb,cdLabel,-1,ENABLE);
  357.  
  358.    }
  359.     xkey=c_dialog(wd);
  360.     if (xkey == _ESC){
  361.        w_close(wd);
  362.        return -1;
  363.     }
  364.     else{
  365.        Unit = c_read(lb,C_STATE);
  366.        w_close(wd);
  367.        return Unit;
  368.     }
  369. }
  370.  
  371. int ValidateDriverName(Field fd, int lastkey){
  372.    char tempDriver[12];
  373.    if (lastkey == _ESC) return FD_OK;
  374.    f_getstring(fd,tempDriver);
  375.    if (GetDriverAddress(tempDriver)==-1)
  376.      return FD_ERR;
  377.    else
  378.      return FD_OK;
  379. }
  380.  
  381. int GetValidDriver(){
  382.     Window    wd;
  383.     Field     fd;
  384.     char      *devName="________";
  385.     int       col=5, row=4, width=15, height=4;
  386.     int       field_col=3, field_row=1;
  387.     int       xkey; /* don't declare lastkey if using f_validate  */
  388.  
  389.     wd = w_open(col, row, width, height);
  390.     w_umessage(wd,"CD DRIVER");
  391.     w_lmessage(wd,"ESC to Quit");
  392.     fd = f_create("", devName);
  393.     f_validate(fd,ValidateDriverName,DISABLE);
  394.     f_startclear(fd,ENABLE);
  395.     f_return(fd,ENABLE);
  396.     f_setbuffer(fd,cdDriver);
  397.     xkey = f_process(wd, field_col, field_row, fd);
  398.     f_getstring(fd,cdDriver);
  399.     f_free(fd);
  400.     w_close(wd);
  401.     if (xkey == _ESC) return -1;
  402.     else return 0;
  403. }
  404.  
  405. int GetDriverAddress(char *cdDriver){
  406.     int   handle;
  407.     union REGS      regs;
  408.     struct SREGS    sregs;
  409.     struct DTA {
  410.        char         cmd;
  411.        char   far * pdevHdr;
  412.      } dta;
  413.     struct DTA far *pdta;
  414.  
  415.    handle = open( cdDriver, O_BINARY);
  416.    if (handle==-1) return(-1);
  417.    dta.cmd = 0;
  418.    pdta = &dta;
  419.    regs.h.ah = 0x44;
  420.    regs.h.al = 0x02;
  421.    regs.x.bx = handle;
  422.    regs.x.cx = 5;
  423.    sregs.ds = FP_SEG(pdta);
  424.    regs.x.dx = FP_OFF(pdta);
  425.    int86x (0x21,®s,®s,&sregs);
  426.    close(handle);
  427.    if (regs.x.cflag) return(-1);
  428.  
  429.    FP_SEG(DevStrategy) = FP_SEG(dta.pdevHdr);
  430.    FP_OFF(DevStrategy) = *(int far *)(dta.pdevHdr+6);
  431.    FP_SEG(DevInterrupt) = FP_SEG(dta.pdevHdr);
  432.    FP_OFF(DevInterrupt) = *(int far *)(dta.pdevHdr+8);
  433.    LastUnit = *(dta.pdevHdr+21) - 1;
  434.    return (0);
  435. }
  436.