Index: src/ole.c
===================================================================
RCS file: /work/oss/catdoc/src/ole.c,v
retrieving revision 1.14
diff -u -w -b -B -r1.14 ole.c
--- src/ole.c	24 Dec 2003 12:20:46 -0000	1.14
+++ src/ole.c	26 Oct 2004 09:53:48 -0000
@@ -24,7 +24,7 @@
 
 #define min(a,b) ((a) < (b) ? (a) : (b))
 
-long int sectorSize;
+long int sectorSize, shortSectorSize;
 /* BBD Info */
 long int  bbdStart, bbdNumBlocks;
 unsigned char *BBD=NULL;
@@ -39,6 +39,14 @@
 
 static char ole_sign[]={0xD0,0xCF,0x11,0xE0,0xA1,0xB1,0x1A,0xE1,0};
 
+long int pow2(int n) {
+	long int acc=1,i;
+	for(i=0; i<n;i++)
+		acc*=2;
+	return acc;
+}
+
+
 /** 
  * Initializes ole structure
  * 
@@ -52,9 +60,10 @@
  */
 FILE* ole_init(FILE *f, void *buffer, size_t bufSize)  {
 	unsigned char oleBuf[BBD_BLOCK_SIZE];
+	unsigned char *tmpBuf;
 	FILE *newfile;
 	int ret=0, i;
-	long int sbdMaxLen, sbdCurrent, propMaxLen, propCurrent;
+	long int sbdMaxLen, sbdCurrent, propMaxLen, propCurrent, mblock;
 	oleEntry *tEntry;
 
 	/* deleting old data (if it was allocated) */
@@ -83,6 +92,7 @@
 	}	
 	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 ) {
@@ -91,33 +101,61 @@
 	if (strncmp(oleBuf,ole_sign,8) != 0) {
 		return NULL;
 	}
-/* 	if ( (sectorSize = BBD_BLOCK_SIZE * getlong(oleBuf,0x40)) == 0) */
-	sectorSize = BBD_BLOCK_SIZE;
+ 	sectorSize = pow2(getshort(oleBuf,0x1e));
+	shortSectorSize=pow2(getshort(oleBuf,0x20));
 	
 /* Read BBD into memory */
 	bbdStart=getlong(oleBuf,0x4c);
 	bbdNumBlocks = getulong(oleBuf,0x2c);
-	if((BBD=malloc(bbdNumBlocks*BBD_BLOCK_SIZE)) == NULL ) {
+	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=getulong(oleBuf,0x44);
+	i=0;
+/* 	fprintf(stderr, "i=%d mblock=%ld\n", i, mblock); */
+	while(mblock>=0) {
+		char *newbuf;
+		if ((newbuf=realloc(tmpBuf, sectorSize+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, 1, sectorSize, newfile);
+		i++;
+		mblock=getulong(tmpBuf, MSAT_ORIG_SIZE+sectorSize*i-4);
+/* 		fprintf(stderr, "i=%d mblock=%ld\n", i, mblock); */
+	};
+	
 /*   	fprintf(stderr, "bbdNumBlocks=%ld\n", bbdNumBlocks);   */
 	for(i=0; i< bbdNumBlocks; i++) {
-		long int bbdSector=getlong(oleBuf,0x4c+4*i);
+		long int bbdSector=getlong(tmpBuf,4*i);
 		
-		if (bbdSector >= fileLength/sectorSize) {
+/*  		fprintf(stderr, "bbdSector(%d)=%ld\n",i,bbdSector); */
+		if (bbdSector >= fileLength/sectorSize || bbdSector < 0) {
 			fprintf(stderr, "Bad BBD entry!\n");
 			ole_finish();
 			return NULL;
 		}
-/*  		fprintf(stderr, "bbdSector=%ld\n",bbdSector);  */
-		fseek(newfile, (bbdSector+1)*BBD_BLOCK_SIZE, SEEK_SET);
-		if ( fread(BBD+i*BBD_BLOCK_SIZE, 1, BBD_BLOCK_SIZE, newfile) !=
-			 BBD_BLOCK_SIZE ) {
+		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;
@@ -128,8 +166,8 @@
 			return NULL;
 		}
 		while(1) {
-			fseek(newfile, (sbdCurrent+1)*sectorSize, SEEK_SET);
-			fread(SBD+sbdLen*BBD_BLOCK_SIZE, 1, sectorSize, newfile);
+			fseek(newfile, 512+sbdCurrent*sectorSize, SEEK_SET);
+			fread(SBD+sbdLen*sectorSize, 1, sectorSize, newfile);
 			sbdLen++;
 			if (sbdLen >= sbdMaxLen) {
 				char *newSBD;
@@ -148,7 +186,7 @@
 				sbdCurrent >= fileLength/sectorSize)
 				break;
 		}
-		sbdNumber = (sbdLen*sectorSize)/SBD_BLOCK_SIZE;
+		sbdNumber = (sbdLen*sectorSize)/shortSectorSize;
 /*   		fprintf(stderr, "sbdLen=%ld sbdNumber=%ld\n",sbdLen, sbdNumber); */
 	} else {
 		SBD=NULL;
@@ -164,7 +202,7 @@
 		}
 		while(1) {
 /*  			fprintf(stderr, "propCurrent=%ld\n",propCurrent); */
-			fseek(newfile, (propCurrent+1)*sectorSize, SEEK_SET);
+			fseek(newfile, 512+propCurrent*sectorSize, SEEK_SET);
 			fread(properties+propLen*sectorSize,
 				  1, sectorSize, newfile);
 			propLen++;
@@ -279,7 +317,7 @@
 	if (e->startBlock >= 0 &&
 		e->length > 0 &&
 		(e->startBlock <=
-		 fileLength/(e->isBigBlock ? sectorSize : SBD_BLOCK_SIZE))) {
+		 fileLength/(e->isBigBlock ? sectorSize : shortSectorSize))) {
 		if((e->blocks=malloc(chainMaxLen*sizeof(long int))) == NULL ) {
 			return NULL;
 		}
@@ -308,18 +346,18 @@
 			}
 			if(chainCurrent <= 0 ||
 			   chainCurrent >= ( e->isBigBlock ?
-								 ((bbdNumBlocks*BBD_BLOCK_SIZE)/4)
-								 : ((sbdNumber*SBD_BLOCK_SIZE)/4) ) ||
+								 ((bbdNumBlocks*sectorSize)/4)
+								 : ((sbdNumber*shortSectorSize)/4) ) ||
 			   (e->numOfBlocks >
-				e->length/(e->isBigBlock ? sectorSize : SBD_BLOCK_SIZE))) {
+				e->length/(e->isBigBlock ? sectorSize : shortSectorSize))) {
 /*   				fprintf(stderr, "chain End=%ld\n", chainCurrent);   */
 				break;
 			}
 			
 		}
 	}
-	if(e->length > (e->isBigBlock ? sectorSize : SBD_BLOCK_SIZE)*e->numOfBlocks)
-		e->length = (e->isBigBlock ? sectorSize : SBD_BLOCK_SIZE)*e->numOfBlocks;
+	if(e->length > (e->isBigBlock ? sectorSize : shortSectorSize)*e->numOfBlocks)
+		e->length = (e->isBigBlock ? sectorSize : shortSectorSize)*e->numOfBlocks;
 /*	fprintf(stderr, "READDIR: e->name=%s e->numOfBlocks=%ld length=%ld\n",
 	e->name, e->numOfBlocks, e->length);*/
 	
@@ -354,13 +392,13 @@
 long int calcFileBlockOffset(oleEntry *e, long int blk) {
 	long int res;
 	if ( e->isBigBlock ) {
-		res=(e->blocks[blk]+1)*sectorSize;
+		res=512+e->blocks[blk]*sectorSize;
 	} else {
-		long int sbdPerSector=sectorSize/SBD_BLOCK_SIZE;
+		long int sbdPerSector=sectorSize/shortSectorSize;
 		long int sbdSecNum=e->blocks[blk]/sbdPerSector;
 		long int sbdSecMod=e->blocks[blk]%sbdPerSector;
-		res=(rootEntry->blocks[sbdSecNum]+1)*sectorSize +
-			sbdSecMod*SBD_BLOCK_SIZE;
+		res=512+rootEntry->blocks[sbdSecNum]*sectorSize +
+			sbdSecMod*shortSectorSize;
 	}
 	return res;
 }
@@ -386,7 +424,7 @@
 	if( e->readed+llen > e->length )
 		llen= e->length - e->readed;
 	
-	ssize = (e->isBigBlock ? sectorSize : SBD_BLOCK_SIZE);
+	ssize = (e->isBigBlock ? sectorSize : shortSectorSize);
 	blockNumber=e->readed/ssize;
 /* 	fprintf(stderr, "blockNumber=%ld e->numOfBlocks=%ld llen=%ld\n", */
 /* 			blockNumber, e->numOfBlocks, llen); */
Index: src/ole.h
===================================================================
RCS file: /work/oss/catdoc/src/ole.h,v
retrieving revision 1.3
diff -u -w -b -B -r1.3 ole.h
--- src/ole.h	14 Nov 2003 14:32:39 -0000	1.3
+++ src/ole.h	26 Oct 2004 09:53:48 -0000
@@ -17,6 +17,7 @@
 #define SBD_BLOCK_SIZE      64
 #define PROP_BLOCK_SIZE    128
 #define OLENAMELENGHT       32
+#define MSAT_ORIG_SIZE     436
 
 typedef enum {
 	oleDir=1,
