File: laolareplace.old.c

package info (click to toggle)
abiword 0.7.7-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 20,604 kB
  • ctags: 18,358
  • sloc: cpp: 88,791; ansic: 66,296; sh: 7,777; makefile: 3,397; xml: 687; perl: 361; awk: 273; sed: 36; csh: 28
file content (431 lines) | stat: -rw-r--r-- 11,378 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

/*
Released under GPL, written by 
	Andrew Scriven <andy.scriven@research.natpower.co.uk>

Copyright (C) 1998
	Andrew Scriven
*/

/*
-----------------------------------------------------------------------
Andrew Scriven
Research and Engineering
Electron Building, Windmill Hill, Whitehill Way, Swindon, SN5 6PB, UK
Phone (44) 1793 896206, Fax (44) 1793 896251
-----------------------------------------------------------------------


The interface to OLEdecode now has
  int OLEdecode(char *filename, FILE **mainfd, FILE **tablefd0, FILE 
**tablefd1,FILE **data,FILE **summary)	
*/

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <assert.h>

#include "wv.h"

#define THEMIN(a,b) ((a)<(b) ? (a) : (b))

#define MAXBLOCKS 256

extern FILE *erroroutput;

struct pps_block
  {
  char name[64];
  char type;
  struct pps_block *previous;
  struct pps_block *next;
  struct pps_block *directory;
  S32 start;
  S32 size;
  int level;
  };

typedef struct pps_block pps_entry;

/* Routine prototypes */
unsigned short int ShortInt(unsigned char* array);
U32 LongInt(unsigned char* array);

unsigned short int ShortInt(unsigned char* array)
{
return sread_16ubit(array);
}

U32 LongInt(unsigned char* array)
{
return sread_32ubit(array);
}

pps_entry **pps_list=NULL;
unsigned char *SDepot=NULL;

/* recurse to follow forward/backward list of root pps's */
void unravel(pps_entry *pps_node)
{
  if (pps_node != NULL)
  	{
	if (pps_node->previous != NULL) 
		unravel(pps_node->previous);
	pps_node->level = 0;
	if(pps_node->next != NULL) 
		unravel(pps_node->next);
	}
}

int wvOLEDecode(FILE *input, FILE **mainfd, FILE **tablefd0, FILE
**tablefd1,FILE **data, FILE **summary)
{
  FILE *OLEfile=NULL;
  FILE *sbfile=NULL;
  FILE *infile=NULL;
  int BlockSize=0,Offset=0;
  int c,i,j,len,bytes;
  char *p;
  unsigned char *s,*t;
  unsigned char *Block,*BDepot=NULL,*Depot=NULL,*Root=NULL;
  S32 depot_len;
  
  char Main[]="WordDocument";
  char Table0[]="0Table";
  char Table1[]="1Table";
  char Data[]="Data";
  char Summary[]="\005SummaryInformation";
  S32 FilePos=0x0;
  S32 num_bbd_blocks;
  S32 root_list[MAXBLOCKS], sbd_list[MAXBLOCKS];
  S32 pps_size,pps_start=-1;
  S32 linkto;
  int root_entry=-1;
  S32 fullen;
  S32 temppos;
  
  *mainfd = NULL;
  *tablefd0 = NULL;
  *tablefd1 = NULL;
  *data = NULL;
  *summary = NULL;

  if(input == NULL) return 1;
  /* peek into file to guess file type */
  c=getc(input);
  if (c==EOF)
  	{
    wvError(("File is empty.\n"));
	return(2);
	}
  	
  ungetc(c,input);

#if 0
  if(isprint(c)) 
  		{
		wvError(("File looks like a plain text file.\n"));
		return(2);
	/* check for MS OLE wrapper */
		} 
	else 
#endif	
	if(c==0xd0) {
     Block = (unsigned char *)malloc(512);
	 if (Block == NULL)
	 	{
       	wvError(("1 ===========> probable corrupt ole file, unable to allocate %d bytes\n",512));
		return(3);
		}
     /* read header block */
     if(fread(Block,512,1,input)!=1) {
       wvError(("1 ===========> Input file has faulty OLE format\n"));
    return(3);
     }
     num_bbd_blocks=(S32)LongInt(Block+0x2c);
	 if ((num_bbd_blocks == 0) || (num_bbd_blocks < 0))
		{
       	wvError(("2 ===========> Input file has ridiculous bbd, mem for the depot was %d\n",512*num_bbd_blocks));
		return(3);
		}
     BDepot = (unsigned char *)malloc(512*num_bbd_blocks);
	 if (BDepot == NULL)
	 	{
       	wvError(("2 ===========> couldnt alloc ole mem for the depot of %d\n",512*num_bbd_blocks));
		return(3);
		}
     s = BDepot;
     root_list[0]=LongInt(Block+0x30);
     sbd_list[0]=(S16)LongInt(Block+0x3c);
    wvTrace(("num_bbd_blocks %d, root start %d, sbd start %d\n",num_bbd_blocks,root_list[0],sbd_list[0]));
	temppos = ftell(input);
	fseek(input,0,SEEK_END);
	fullen = ftell(input);
	fseek(input,temppos,SEEK_SET);

     /* read big block Depot */
     for(i=0;i<(int)num_bbd_blocks;i++) 
	 	{
		if (0x4c+(i*4) > 512)
			{
			wvError(("2.1 ===========> Input file has faulty bbd\n"));
			return(3);
			}
       	FilePos = 512*(LongInt(Block+0x4c+(i*4))+1);
		if (FilePos > fullen)
			{
			wvError(("2.2 ===========> Input file has faulty bbd\n"));
			return 3;
			}
       	if (-1 == fseek(input,FilePos,SEEK_SET))
			{
			wvError(("2.3 ===========> Input file has faulty bbd\n"));
			return(3);
			}
       	if(fread(s,512,1,input)!=1) 
			{
			wvError(("2.4 ===========> Input file has faulty bbd\n"));
			return 3;
			}
       	s += 0x200;
     	}

     /* Extract the sbd block list */
     for(len=1;len<MAXBLOCKS;len++)
	 	{
		if (((sbd_list[len-1]*4) < (512*num_bbd_blocks))  && ((sbd_list[len-1]*4) > 0))
			sbd_list[len] = LongInt(BDepot+(sbd_list[len-1]*4));
		else
			{
         	wvError(("3 ===========> Input file has faulty OLE format\n"));
			return(3);
			}
		if(sbd_list[len]==-2) break;
     	}
     SDepot = (unsigned char *)malloc(512*len);
	 if (SDepot== NULL)
	 	{
       	wvError(("1 ===========> probable corrupt ole file, unable to allocate %d bytes\n",512*len));
		return(3);
		}
     s = SDepot;
     /* Read in Small Block Depot */
     for(i=0;i<len;i++) {
       FilePos = 512 *(sbd_list[i]+1);
       fseek(input,FilePos,SEEK_SET);
       if(fread(s,512,1,input)!=1) {
         wvError(("3 ===========> Input file has faulty OLE format\n"));
         return 3;
       }
       s += 0x200;
     }
     /* Extract the root block list */
     for(len=1;len<MAXBLOCKS;len++)
		{
		if ( ((root_list[len-1]*4) >= (512*num_bbd_blocks)) || ( (root_list[len-1]*4) < 0) )
			{
         	wvError(("3.1 ===========> Input file has faulty OLE format\n"));
			return(3);
			}
		root_list[len] = LongInt(BDepot+(root_list[len-1]*4));
		if(root_list[len]==-2) break;
		}
     Root = (unsigned char *)malloc(512*len);
	 if (Root == NULL)
	 	{
       	wvError(("1 ===========> probable corrupt ole file, unable to allocate %d bytes\n",512*len));
		return(3);
		}
     s = Root;
     /* Read in Root stream data */
     for(i=0;i<len;i++) {
       FilePos = 512 *(root_list[i]+1);
       fseek(input,FilePos,SEEK_SET);
       if(fread(s,512,1,input)!=1) {
         wvError(("4 ===========> Input file has faulty OLE format\n"));
         return 3;
       }
       s += 0x200;
     }

     /* assign space for pps list */
     pps_list = (pps_entry **)malloc(len*4*sizeof(pps_entry *));
	 if (pps_list == NULL)
	 	{
       	wvError(("1 ===========> probable corrupt ole file, unable to allocate %d bytes\n",len*4*sizeof(pps_entry *)));
		return(3);
		}
     for(j=0;j<len*4;j++) 
	 	{
	 	pps_list[j] = (pps_entry *)malloc(sizeof(pps_entry));
		if (pps_list[j] == NULL)
			{
			wvError(("1 ===========> probable corrupt ole file, unable to allocate %d bytes\n",sizeof(pps_entry)));
			return(3);
			}
		}
     /* Store pss entry details and look out for Root Entry */
     for(j=0;j<len*4;j++) {
       pps_list[j]->level = -1;
       s = Root+(j*0x80);
       i=ShortInt(s+0x40);
	   if (((j*0x80) + i) >= (512 * len))
	   	{
		wvError(("1.1 ===========> probable corrupt ole file\n"));
		return(3);
		}
       for(p=pps_list[j]->name,t=s;t<s+i;t++) 
	   	*p++ = *t++;
       s+=0x42;
       pps_list[j]->type = *s;
       if(pps_list[j]->type == 5) {
         root_entry = j; /* this is root */
         pps_list[j]->level = 0;
       }
       s+=0x02;
       linkto = LongInt(s);
       if ((linkto != -1) && (linkto < (len*4)) && (linkto > -1))
	   	pps_list[j]->previous = pps_list[linkto];
       else pps_list[j]->previous = NULL;
       s+=0x04;
       linkto = LongInt(s);
       if ((linkto != -1) && (linkto < (len*4)) && (linkto > -1))
	   	pps_list[j]->next = pps_list[linkto];
       else pps_list[j]->next = NULL;
       s+=0x04;
       linkto = LongInt(s);
       if ((linkto != -1) && (linkto < (len*4)) && (linkto > -1))
	   	pps_list[j]->directory = pps_list[linkto];
       else pps_list[j]->directory = NULL;
       s+=0x28;
       pps_list[j]->start = LongInt(s);
       s+=0x04;
       pps_list[j]->size = LongInt(s);
     }

     /* go through the pps entries, tagging them with level number
        use recursive routine to follow list starting at root entry */
     unravel(pps_list[root_entry]->directory);

     /* go through the level 0 list looking for named entries */
     for(j=0;j<len*4;j++) {
       if(pps_list[j]->level != 0) continue; /* skip nested stuff */
       pps_start = pps_list[j]->start;
       pps_size  = pps_list[j]->size;
       OLEfile = NULL;
       if(pps_list[j]->type==5) {  /* Root entry */
         OLEfile = tmpfile();
         sbfile = OLEfile;
         wvTrace(("Reading sbFile %d\n",pps_start));
       }
       else if(!strcmp(pps_list[j]->name,Main)) {
         OLEfile = tmpfile();
         *mainfd = OLEfile;
         wvTrace(("Reading Main %d\n",pps_start));
       }
       else if(!strcmp(pps_list[j]->name,Table0)) {
         OLEfile = tmpfile();
         *tablefd0 = OLEfile;
         wvTrace(("Reading Table0 %d\n",pps_start));
       }
       else if(!strcmp(pps_list[j]->name,Table1)) {
         OLEfile = tmpfile();
         *tablefd1 = OLEfile;
         wvTrace(("Reading Table1 %d\n",pps_start));
       }
       else if(!strcmp(pps_list[j]->name,Data)) {
         OLEfile = tmpfile();
         *data = OLEfile;
         wvTrace(("Reading Data %d\n",pps_start));
       }
       else if(!strcmp(pps_list[j]->name,Summary)) {
         OLEfile = tmpfile();
         *summary= OLEfile;
         wvTrace(("Reading Summary%d\n",pps_start));
       }
	   	
       if(pps_size<=0) OLEfile = NULL;
       if(OLEfile == NULL) continue;
	   /* 
       if (pps_size>=4096 | OLEfile==sbfile) 
	   */
       if ((pps_size>=4096) || (OLEfile==sbfile))
	   {
         Offset = 1;
         BlockSize = 512;
         infile = input;
         Depot = BDepot;
  		 depot_len=512*num_bbd_blocks;
       } else {
         Offset = 0;
         BlockSize = 64;
         infile = sbfile;
         Depot = SDepot;
  		 depot_len= 512*len;
       }
       while(pps_start != -2) {
         wvTrace(("Reading block %d, Offset %x\n",pps_start,Offset));
         FilePos = (pps_start+Offset)* BlockSize;
         bytes = THEMIN(BlockSize,pps_size);
         if (fseek(infile,FilePos,SEEK_SET) != 0) {
		 /*wvError(("6 ===========> Input file has faulty OLE format\n"));*/
		  return(3);
		 }
         if(fread(Block,bytes,1,infile)!=1) {
           /*wvError(("5 ===========> Input file has faulty OLE format\n"));*/
			wvFree(Root);
			wvFree(BDepot);
			wvFree(Block);
           return(3);
         }
         fwrite(Block,bytes,1,OLEfile);
		 if ( (pps_start*4 > depot_len) || (pps_start*4 < 0) )
		 	{
			/*wvWarning("5 ===========> Input file has dodgy OLE format\n");*/
			wvFree(Root);
			wvFree(BDepot);
			wvFree(Block);
			return(3);
			pps_size = 0;
			}
		else
			{
			pps_start = LongInt(Depot+(pps_start*4));
			pps_size -= BlockSize;
		 	}
         if(pps_size <= 0) pps_start=-2;
       }
       rewind(OLEfile);
     }

	for(j=0;j<len*4;j++) {
	 	free(pps_list[j]);
	 }
    free(pps_list);
    wvFree(Root);
    wvFree(BDepot);
    wvFree(Block);
    fclose(input);
    return 0;
  } else {
    /* not a OLE file! */
  if(isprint(c)) 
  		{
		wvTrace(("File looks like a plain text file.\n"));
		return 2;
		} 
    wvTrace(("7 ===========> Input file is not an OLE file\n"));
    return 2;
  }
}

void wvOLEFree(void)
    {
	if (SDepot != NULL)
		free(SDepot);
	}