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
|
/* This file is part of the KDE project
Copyright (C) 1999 Werner Trobin <trobin@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
DESCRIPTION
This class is used to decode OLE 2 streams. When instantiated, it
constructs an internal "filesystem" that corresponds to the OLE storage
tree. This tree can be navigated, and the individual OLE streams
returned as a linear memory buffer.
*/
#ifndef KLAOLA_H
#define KLAOLA_H
#include <myfile.h>
#include <tqstring.h>
#include <tqptrlist.h>
class KLaola {
public:
KLaola(const myFile &file); // see myfile.h!
~KLaola();
bool isOk() {return ok;}
// A class representing an abstracted node in the OLE filesystem.
class OLENode {
public:
virtual ~OLENode() {};
virtual unsigned handle() const = 0;
virtual TQString name() const = 0;
// Does the node represent a stream datum, or a storage container
// of data?
virtual bool isDirectory() const = 0;
// If isDirectory() is true, return the CLSID associated with
// any child CompObj node. If the Node is a CompObj, return
// its CLSID. Otherwise return TQString().
//
// The CLSID is returned in the form:
//
// 00020900-0000-0000-C000-000000000046
//
virtual TQString readClassStream() const = 0;
// Return a human-readable description of a stream.
virtual TQString describe() const = 0;
protected:
OLENode() {}
};
// Wade through the "file system"
typedef TQPtrList<OLENode> NodeList;
NodeList parseRootDir();
NodeList parseCurrentDir();
const NodeList currentPath() const;
const NodeList find(const TQString &name, bool onlyCurrentDir=false);
bool enterDir(const OLENode *node);
bool leaveDir();
// Return the stream for a given node.
//
// Note: data - 512 byte blocks, but length is set correctly :)
myFile stream(const OLENode *node);
myFile stream(unsigned handle);
private:
KLaola(const KLaola &);
const KLaola &operator=(const KLaola &);
static const int s_area;
unsigned char read8(int i) const;
unsigned short read16(int i) const;
unsigned int read32(int i) const;
// Parsing functions.
bool parseHeader();
void readBigBlockDepot();
void readSmallBlockDepot();
void readSmallBlockFile();
void readRootList();
void readPPSEntry(int pos, const int handle);
void createTree(const int handle, const short index);
const unsigned char *readBBStream(int start, bool setmaxSblock=false);
const unsigned char *readSBStream(int start) const;
int nextBigBlock(int pos) const;
int nextSmallBlock(int pos) const;
// Dump the parsed structure info (similar to "lls"
// of the LAOLA-project).
void testIt(TQString prefix = "");
public:
typedef enum
{
DIRECTORY = 1,
FILE = 2,
ROOT_ENTRY = 5
} NodeType;
// If the first part of an on-disk name is less than 32, it is a prefix.
typedef enum
{
OLE_MANAGED_0,
CLSID,
OLE_MANAGED_2,
PARENT_MANAGED, // Marks an element as owned by the code that
// manages the parent storage of that element.
STRUCTURED_STORAGE, // For the exclusive use of the Structured Storage
// implementation.
RESERVED_FIRST,
RESERVED_LAST = 31,
NONE = 32
} Prefix;
class Node: public OLENode {
public:
Node(KLaola *laola) { m_laola = laola; }
~Node() {}
unsigned handle() const { return m_handle; }
TQString name() const;
bool isDirectory() const { return (type == DIRECTORY) || (type == ROOT_ENTRY); }
TQString readClassStream() const;
TQString describe() const;
KLaola *m_laola;
unsigned m_handle; // PPS entry number
Prefix m_prefix;
TQString m_name;
NodeType type;
int prevHandle; // Last pps
int nextHandle; // Next pps
int dirHandle; // Dir pps
int ts1s; // Timestamp 1, seconds
int ts1d; // Timestamp 1, days
int ts2s; // Timestamp 2, seconds
int ts2d; // Timestamp 2, days
unsigned sb; // Starting block
unsigned size; // Size of property
bool deadDir; // true, if the dir is a "dead end"
};
private:
// Lists of nodes.
NodeList m_nodeList;
NodeList m_currentPath;
// The OLE storage is represented as a tree. Each node in the tree may
// refer to a subtree. Each subtree is stored as a list of nodes.
struct TreeNode
{
Node *node;
short subtree;
};
typedef TQPtrList<TreeNode> SubTree;
TQPtrList<SubTree> m_nodeTree;
bool ok; // is the file OK?
myFile m_file;
unsigned char *bigBlockDepot;
unsigned char *smallBlockDepot;
unsigned char *smallBlockFile;
unsigned int maxblock; // maximum number of big-blocks
unsigned int maxSblock; // small-blocks
unsigned int num_of_bbd_blocks; // number of big block depot blocks
unsigned int root_startblock; // Root chain's first big block
unsigned int sbd_startblock; // small block depot's first big block
unsigned int *bbd_list; //array of num_of_bbd_blocks big block numbers
};
#endif // KLAOLA_H
|