⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fci.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
  UINT i;

  /* TODO compress the data of p_fci_internal->data_in */
  /* and write it to p_fci_internal->data_out */
  memcpy(p_fci_internal->data_out, p_fci_internal->data_in,
    p_fci_internal->cdata_in /* number of bytes to copy */);

  cfdata->csum=0; /* checksum has to be set later */
  /* TODO set realsize of compressed data */
  cfdata->cbData   = p_fci_internal->cdata_in;
  cfdata->cbUncomp = p_fci_internal->cdata_in;

  /* write cfdata to p_fci_internal->handleCFDATA1 */
  if( PFCI_WRITE(hfci, p_fci_internal->handleCFDATA1, /* file handle */
      cfdata, sizeof(*cfdata), err, p_fci_internal->pv)
      != sizeof(*cfdata) ) {
    fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE );
    return FALSE;
  }
  /* TODO error handling of err */

  p_fci_internal->sizeFileCFDATA1 += sizeof(*cfdata);

  /* add optional reserved area */

  /* This allocation and freeing at each CFData block is a bit */
  /* inefficent, but it's harder to forget about freeing the buffer :-). */
  /* Reserved areas are used seldom besides that... */
  if (cbReserveCFData!=0) {
    if(!(reserved = (char*)PFCI_ALLOC(hfci, cbReserveCFData))) {
      fci_set_error( FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY, TRUE );
      return FALSE;
    }
    for(i=0;i<cbReserveCFData;) {
      reserved[i++]='\0';
    }
    if( PFCI_WRITE(hfci, p_fci_internal->handleCFDATA1, /* file handle */
        reserved, /* memory buffer */
        cbReserveCFData, /* number of bytes to copy */
        err, p_fci_internal->pv) != cbReserveCFData ) {
      PFCI_FREE(hfci, reserved);
      fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE );
      return FALSE;
    }
    /* TODO error handling of err PFCI_FREE(hfci, reserved)*/

    p_fci_internal->sizeFileCFDATA1 += cbReserveCFData;
    PFCI_FREE(hfci, reserved);
  }

  /* write p_fci_internal->data_out to p_fci_internal->handleCFDATA1 */
  if( PFCI_WRITE(hfci, p_fci_internal->handleCFDATA1, /* file handle */
      p_fci_internal->data_out, /* memory buffer */
      cfdata->cbData, /* number of bytes to copy */
      err, p_fci_internal->pv) != cfdata->cbData) {
    fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE );
    return FALSE;
  }
  /* TODO error handling of err */

  p_fci_internal->sizeFileCFDATA1 += cfdata->cbData;

  /* reset the offset */
  p_fci_internal->cdata_in = 0;
  p_fci_internal->cCompressedBytesInFolder += cfdata->cbData;

  /* report status with pfnfcis about uncompressed and compressed file data */
  if( (*pfnfcis)(statusFile, cfdata->cbData, cfdata->cbUncomp,
      p_fci_internal->pv) == -1) {
    fci_set_error( FCIERR_USER_ABORT, 0, TRUE );
    return FALSE;
  }

  ++(p_fci_internal->cDataBlocks);

  return TRUE;
} /* end of fci_flush_data_block */





static cab_ULONG fci_get_checksum(void *pv, UINT cb, CHECKSUM seed)
{
  cab_ULONG csum;
  cab_ULONG ul;
  int       cUlong;
  BYTE      *pb;

  csum = seed;
  cUlong = cb / 4;
  pb = pv;

  while (cUlong-- > 0) {
    ul = *pb++;
    ul |= (((cab_ULONG)(*pb++)) <<  8);
    ul |= (((cab_ULONG)(*pb++)) << 16);
    ul |= (((cab_ULONG)(*pb++)) << 24);

    csum ^= ul;
  }

  ul = 0;
  switch (cb % 4) {
    case 3:
      ul |= (((ULONG)(*pb++)) << 16);
    case 2:
      ul |= (((ULONG)(*pb++)) <<  8);
    case 1:
      ul |= *pb++;
    default:
      break;
  }
  csum ^= ul;

  return csum;
} /* end of fci_get_checksum */



static BOOL fci_flushfolder_copy_cfdata(HFCI hfci, char* buffer, UINT cbReserveCFData,
  PFNFCISTATUS pfnfcis, int* err, int handleCFDATA1new,
  cab_ULONG* psizeFileCFDATA1new, cab_ULONG* payload)
{
  cab_ULONG read_result;
  CFDATA* pcfdata=(CFDATA*)buffer;
  BOOL split_block=FALSE;
  cab_UWORD savedUncomp=0;
  PFCI_Int p_fci_internal=((PFCI_Int)(hfci));

  *payload=0;

  /* while not all CFDATAs have been copied do */
  while(!FALSE) {
    if( p_fci_internal->fNextCab ) {
      if( split_block ) {
        /* internal error should never happen */
        fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE );
        return FALSE;
      }
    }
    /* REUSE the variable read_result */
    if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
        p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
        p_fci_internal->oldCCAB.cbReserveCFData   != 0 ) {
      read_result=4;
    } else {
      read_result=0;
    }
    if (p_fci_internal->fPrevCab) {
      read_result+=strlen(p_fci_internal->szPrevCab)+1 +
        strlen(p_fci_internal->szPrevDisk)+1;
    }
    /* No more CFDATA fits into the cabinet under construction */
    /* So don't try to store more data into it */
    if( p_fci_internal->fNextCab &&
        (p_fci_internal->oldCCAB.cb <= sizeof(CFDATA) + cbReserveCFData +
        p_fci_internal->sizeFileCFFILE1 + p_fci_internal->sizeFileCFDATA2 +
        p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER +
        sizeof(CFHEADER) +
        read_result +
        p_fci_internal->oldCCAB.cbReserveCFHeader +
        sizeof(CFFOLDER) +
        p_fci_internal->oldCCAB.cbReserveCFFolder +
        strlen(p_fci_internal->pccab->szCab)+1 +
        strlen(p_fci_internal->pccab->szDisk)+1
    )) {
      /* This may never be run for the first time the while loop is entered.
      Pray that the code that calls fci_flushfolder_copy_cfdata handles this.*/
      split_block=TRUE;  /* In this case split_block is abused to store */
      /* the complete data block into the next cabinet and not into the */
      /* current one. Originally split_block is the indicator that a */
      /* data block has been splitted across different cabinets. */
    } else {

      /* read CFDATA from p_fci_internal->handleCFDATA1 to cfdata*/
      read_result= PFCI_READ(hfci, p_fci_internal->handleCFDATA1,/*file handle*/
          buffer, /* memory buffer */
          sizeof(CFDATA)+cbReserveCFData, /* number of bytes to copy */
          err, p_fci_internal->pv);
      if (read_result!=sizeof(CFDATA)+cbReserveCFData) {
        if (read_result==0) break; /* ALL DATA has been copied */
        /* read error */
        fci_set_error( FCIERR_NONE, ERROR_READ_FAULT, TRUE );
        return FALSE;
      }
      /* TODO error handling of err */

      /* REUSE buffer p_fci_internal->data_out !!! */
      /* read data from p_fci_internal->handleCFDATA1 to */
      /*      p_fci_internal->data_out */
      if( PFCI_READ(hfci, p_fci_internal->handleCFDATA1 /* file handle */,
          p_fci_internal->data_out /* memory buffer */,
          pcfdata->cbData /* number of bytes to copy */,
          err, p_fci_internal->pv) != pcfdata->cbData ) {
        /* read error */
        fci_set_error( FCIERR_NONE, ERROR_READ_FAULT, TRUE );
        return FALSE;
      }
      /* TODO error handling of err */

      /* if cabinet size is too large */

      /* REUSE the variable read_result */
      if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
          p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
          p_fci_internal->oldCCAB.cbReserveCFData   != 0 ) {
        read_result=4;
      } else {
        read_result=0;
      }
      if (p_fci_internal->fPrevCab) {
        read_result+=strlen(p_fci_internal->szPrevCab)+1 +
          strlen(p_fci_internal->szPrevDisk)+1;
      }

      /* Is cabinet with new CFDATA too large? Then data block has to be split */
      if( p_fci_internal->fNextCab &&
          (p_fci_internal->oldCCAB.cb < sizeof(CFDATA) + cbReserveCFData +
          pcfdata->cbData +
          p_fci_internal->sizeFileCFFILE1 + p_fci_internal->sizeFileCFDATA2 +
          p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER +
          sizeof(CFHEADER) +
          read_result +
          p_fci_internal->oldCCAB.cbReserveCFHeader +
          sizeof(CFFOLDER) + /* size of new CFFolder entry */
          p_fci_internal->oldCCAB.cbReserveCFFolder +
          strlen(p_fci_internal->pccab->szCab)+1 + /* name of next cabinet */
          strlen(p_fci_internal->pccab->szDisk)+1  /* name of next disk */
      )) {
        /* REUSE read_result to save the size of the compressed data */
        read_result=pcfdata->cbData;
        /* Modify the size of the compressed data to store only a part of the */
        /* data block into the current cabinet. This is done to prevent */
        /* that the maximum cabinet size will be exceeded. The remainder */
        /* will be stored into the next following cabinet. */

        /* The cabinet will be of size "p_fci_internal->oldCCAB.cb". */
        /* Substract everything except the size of the block of data */
        /* to get it's actual size */
        pcfdata->cbData = p_fci_internal->oldCCAB.cb - (
          sizeof(CFDATA) + cbReserveCFData +
          p_fci_internal->sizeFileCFFILE1 + p_fci_internal->sizeFileCFDATA2 +
          p_fci_internal->sizeFileCFFILE2 + p_fci_internal->sizeFileCFFOLDER +
          sizeof(CFHEADER) +
          p_fci_internal->oldCCAB.cbReserveCFHeader +
          sizeof(CFFOLDER) + /* set size of new CFFolder entry */
          p_fci_internal->oldCCAB.cbReserveCFFolder );
        /* substract the size of special header fields */
        if ( p_fci_internal->oldCCAB.cbReserveCFHeader != 0 ||
            p_fci_internal->oldCCAB.cbReserveCFFolder != 0 ||
            p_fci_internal->oldCCAB.cbReserveCFData   != 0 ) {
          pcfdata->cbData-=4;
        }
        if (p_fci_internal->fPrevCab) {
          pcfdata->cbData-=strlen(p_fci_internal->szPrevCab)+1 +
            strlen(p_fci_internal->szPrevDisk)+1;
        }
        pcfdata->cbData-=strlen(p_fci_internal->pccab->szCab)+1 +
          strlen(p_fci_internal->pccab->szDisk)+1;

        savedUncomp = pcfdata->cbUncomp;
        pcfdata->cbUncomp = 0; /* on splitted blocks of data this is zero */

        /* if split_block==TRUE then the above while loop won't */
        /* be executed again */
        split_block=TRUE; /* split_block is the indicator that */
                          /* a data block has been splitted across */
                          /* diffentent cabinets.*/
      }

      /* This should never happen !!! */
      if (pcfdata->cbData==0) {
        /* set error */
        fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE );
        return FALSE;
      }

      /* set little endian */
      pcfdata->cbData=fci_endian_uword(pcfdata->cbData);
      pcfdata->cbUncomp=fci_endian_uword(pcfdata->cbUncomp);

      /* get checksum and write to cfdata.csum */
      pcfdata->csum = fci_get_checksum( &(pcfdata->cbData),
        sizeof(CFDATA)+cbReserveCFData -
        sizeof(pcfdata->csum), fci_get_checksum( p_fci_internal->data_out, /*buffer*/
        pcfdata->cbData, 0 ) );

      /* set little endian */
      pcfdata->csum=fci_endian_ulong(pcfdata->csum);

      /* write cfdata with checksum to p_fci_internal->handleCFDATA2 */
      if( PFCI_WRITE(hfci, p_fci_internal->handleCFDATA2, /* file handle */
          buffer, /* memory buffer */
          sizeof(CFDATA)+cbReserveCFData, /* number of bytes to copy */
          err, p_fci_internal->pv) != sizeof(CFDATA)+cbReserveCFData ) {
         fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE );
         return FALSE;
      }
      /* TODO error handling of err */

      p_fci_internal->sizeFileCFDATA2 += sizeof(CFDATA)+cbReserveCFData;

      /* reset little endian */
      pcfdata->cbData=fci_endian_uword(pcfdata->cbData);
      pcfdata->cbUncomp=fci_endian_uword(pcfdata->cbUncomp);
      pcfdata->csum=fci_endian_ulong(pcfdata->csum);

      /* write compressed data into p_fci_internal->handleCFDATA2 */
      if( PFCI_WRITE(hfci, p_fci_internal->handleCFDATA2, /* file handle */
          p_fci_internal->data_out, /* memory buffer */
          pcfdata->cbData, /* number of bytes to copy */
          err, p_fci_internal->pv) != pcfdata->cbData) {
        fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE );
        return FALSE;
      }
      /* TODO error handling of err */

      p_fci_internal->sizeFileCFDATA2 += pcfdata->cbData;
      ++(p_fci_internal->cDataBlocks);
      p_fci_internal->statusFolderCopied += pcfdata->cbData;
      (*payload)+=pcfdata->cbUncomp;
      /* if cabinet size too large and data has been split */
      /* write the remainder of the data block to the new CFDATA1 file */
      if( split_block  ) { /* This does not include the */
                                  /* abused one (just search for "abused" )*/
      /* copy all CFDATA structures from handleCFDATA1 to handleCFDATA1new */
        if (p_fci_internal->fNextCab==FALSE ) {
          /* internal error */
          fci_set_error( FCIERR_NONE, ERROR_GEN_FAILURE, TRUE );
          return FALSE;
        }

        /* set cbData to the size of the remainder of the data block */
        pcfdata->cbData = read_result - pcfdata->cbData;
        /*recover former value of cfdata.cbData; read_result will be the offset*/
        read_result -= pcfdata->cbData;
        pcfdata->cbUncomp = savedUncomp;

        /* reset checksum, it will be computed later */
        pcfdata->csum=0;

        /* write cfdata WITHOUT checksum to handleCFDATA1new */
        if( PFCI_WRITE(hfci, handleCFDATA1new, /* file handle */
            buffer, /* memory buffer */
            sizeof(CFDATA)+cbReserveCFData, /* number of bytes to copy */
            err, p_fci_internal->pv) != sizeof(CFDATA)+cbReserveCFData ) {
          fci_set_error( FCIERR_TEMP_FILE, ERROR_WRITE_FAULT, TRUE );
          return FALSE;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -