Logo Search packages:      
Sourcecode: catdoc version File versions  Download package

FILE* ole_init ( FILE *  f,
void *  buffer,
size_t  bufSize 
)

Initializes ole structure

Parameters:
f (FILE *) compound document file, positioned at bufSize byte. Might be pipe or socket
buffer (void *) bytes already read from f
bufSize number of bytes already read from f should be less than 512
Returns:

Definition at line 54 of file ole.c.

References ole_close(), and ole_readdir().

                                                       {
      unsigned char oleBuf[BBD_BLOCK_SIZE];
      unsigned char *tmpBuf;
      FILE *newfile;
      int ret=0, i;
      long int sbdMaxLen, sbdCurrent, propMaxLen, propCurrent, mblock, msat_size;
      oleEntry *tEntry;

      /* deleting old data (if it was allocated) */
      ole_finish();
      
      if (fseek(f,0,SEEK_SET) == -1) {
            if ( errno == ESPIPE ) {
                  /* We got non-seekable file, create temp file */
                  if((newfile=tmpfile()) == NULL) {
                        perror("Can't create tmp file");
                        return NULL;
                  }
                  if (bufSize > 0)
                        fwrite(buffer, 1, bufSize, newfile);
                  while(!feof(f)){
                        ret=fread(oleBuf,1,BBD_BLOCK_SIZE,f);
                        fwrite(oleBuf, 1, ret, newfile);
                  }
                  fseek(newfile,0,SEEK_SET);
            } else {
                  perror("Can't seek in file");
                  return NULL;
            }
      } else {
            newfile=f;
      }     
      fseek(newfile,0,SEEK_END);
      fileLength=ftell(newfile);
/*    fprintf(stderr, "fileLength=%ld\n", fileLength);    */
      fseek(newfile,0,SEEK_SET);
      ret=fread(oleBuf,1,BBD_BLOCK_SIZE,newfile);
      if ( ret != BBD_BLOCK_SIZE ) {
            return NULL;
      }
      if (strncmp(oleBuf,ole_sign,8) != 0) {
            return NULL;
      }
      sectorSize = 1<<getshort(oleBuf,0x1e);
      shortSectorSize=1<<getshort(oleBuf,0x20);
      
/* Read BBD into memory */
      bbdStart=getlong(oleBuf,0x4c);
      bbdNumBlocks = getulong(oleBuf,0x2c);
      if((BBD=malloc(bbdNumBlocks*sectorSize)) == NULL ) {
            return NULL;
      }
      
      if((tmpBuf=malloc(MSAT_ORIG_SIZE)) == NULL ) {
            return NULL;
      }
      memcpy(tmpBuf,oleBuf+0x4c,MSAT_ORIG_SIZE);
      mblock=getlong(oleBuf,0x44);
      msat_size=getulong(oleBuf,0x48);
      i=0;
/*    fprintf(stderr, "i=%d mblock=%ld msat_size=%ld\n", i, mblock, msat_size); */
      
      while((mblock >= 0) && (i < msat_size)) {
            char *newbuf;
/*          fprintf(stderr, "i=%d mblock=%ld\n", i, mblock); */
            if ((newbuf=realloc(tmpBuf, sectorSize*(i+1)+MSAT_ORIG_SIZE)) != NULL) {
                  tmpBuf=newbuf;
            } else {
                  perror("BDB realloc error");
                  free(tmpBuf);
                  ole_finish();
                  return NULL;
            }
            
            fseek(newfile, 512+mblock*sectorSize, SEEK_SET);
            fread(tmpBuf+MSAT_ORIG_SIZE+sectorSize*i-(i==0 ? 0 : (4*i)),
                              1, sectorSize, newfile);
            i++;
            mblock=getlong(tmpBuf, MSAT_ORIG_SIZE+sectorSize*i-4);
      };
      
/*    fprintf(stderr, "bbdNumBlocks=%ld\n", bbdNumBlocks);   */
      for(i=0; i< bbdNumBlocks; i++) {
            long int bbdSector=getlong(tmpBuf,4*i);
            
/*          fprintf(stderr, "bbdSector(%d)=%ld\n",i,bbdSector); */
            if (bbdSector >= fileLength/sectorSize || bbdSector < 0) {
                  fprintf(stderr, "Bad BBD entry!\n");
                  ole_finish();
                  return NULL;
            }
            fseek(newfile, 512+bbdSector*sectorSize, SEEK_SET);
            if ( fread(BBD+i*sectorSize, 1, sectorSize, newfile) != sectorSize ) {
                  fprintf(stderr, "Can't read BBD!\n");
                  free(tmpBuf);
                  ole_finish();
                  return NULL;
            }
      }
      free(tmpBuf);
      
/* Read SBD into memory */
      sbdLen=0;
      sbdMaxLen=10;
      sbdCurrent = sbdStart = getlong(oleBuf,0x3c);
      if (sbdStart > 0) {
            if((SBD=malloc(sectorSize*sbdMaxLen)) == NULL ) {
                  ole_finish();
                  return NULL;
            }
            while(1) {
                  fseek(newfile, 512+sbdCurrent*sectorSize, SEEK_SET);
                  fread(SBD+sbdLen*sectorSize, 1, sectorSize, newfile);
                  sbdLen++;
                  if (sbdLen >= sbdMaxLen) {
                        char *newSBD;
                        
                        sbdMaxLen+=5;
                        if ((newSBD=realloc(SBD, sectorSize*sbdMaxLen)) != NULL) {
                              SBD=newSBD;
                        } else {
                              perror("SBD realloc error");
                              ole_finish();
                              return NULL;
                        }
                  }
                  sbdCurrent = getlong(BBD, sbdCurrent*4);
                  if(sbdCurrent < 0 ||
                        sbdCurrent >= fileLength/sectorSize)
                        break;
            }
            sbdNumber = (sbdLen*sectorSize)/shortSectorSize;
/*          fprintf(stderr, "sbdLen=%ld sbdNumber=%ld\n",sbdLen, sbdNumber); */
      } else {
            SBD=NULL;
      }
/* Read property catalog into memory */
      propLen = 0;
      propMaxLen = 5;
      propCurrent = propStart = getlong(oleBuf,0x30);
      if (propStart >= 0) {
            if((properties=malloc(propMaxLen*sectorSize)) == NULL ) {
                  ole_finish();
                  return NULL;
            }
            while(1) {
/*                fprintf(stderr, "propCurrent=%ld\n",propCurrent); */
                  fseek(newfile, 512+propCurrent*sectorSize, SEEK_SET);
                  fread(properties+propLen*sectorSize,
                          1, sectorSize, newfile);
                  propLen++;
                  if (propLen >= propMaxLen) {
                        char *newProp;
                        
                        propMaxLen+=5;
                        if ((newProp=realloc(properties, propMaxLen*sectorSize)) != NULL)
                              properties=newProp;
                        else {
                              perror("Properties realloc error");
                              ole_finish();
                              return NULL;
                        }
                  }
                  
                  propCurrent = getlong(BBD, propCurrent*4);
                  if(propCurrent < 0 ||
                     propCurrent >= fileLength/sectorSize ) {
                        break;
                  }
            }
/*          fprintf(stderr, "propLen=%ld\n",propLen);  */
            propNumber = (propLen*sectorSize)/PROP_BLOCK_SIZE;
            propCurNumber = 0;
      } else {
            ole_finish();
            properties = NULL;
            return NULL;
      }
      
      
/* Find Root Entry */
      while((tEntry=(oleEntry*)ole_readdir(newfile)) != NULL) {
            if (strcmp(tEntry->name,"Root Entry") == 0) {
                  rootEntry=tEntry;
                  break;
            }
            ole_close((FILE*)tEntry);
      }
      propCurNumber = 0;
      fseek(newfile, 0, SEEK_SET);
      
      return newfile;
}


Generated by  Doxygen 1.6.0   Back to index