-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathparsevbox.c
More file actions
206 lines (180 loc) · 5.67 KB
/
parsevbox.c
File metadata and controls
206 lines (180 loc) · 5.67 KB
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
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
typedef struct SSMFILEHDR
{
/** Magic string which identifies this file as a version of VBox saved state
* file format (SSMFILEHDR_MAGIC_V2_0). */
char szMagic[32];
/** The major version number. */
uint16_t u16VerMajor;
/** The minor version number. */
uint16_t u16VerMinor;
/** The build number. */
uint32_t u32VerBuild;
/** The SVN revision. */
uint32_t u32SvnRev;
/** 32 or 64 depending on the host. */
uint8_t cHostBits;
/** The size of RTGCPHYS. */
uint8_t cbGCPhys;
/** The size of RTGCPTR. */
uint8_t cbGCPtr;
/** Reserved header space - must be zero. */
uint8_t u8Reserved;
/** The number of units that (may) have stored data in the file. */
uint32_t cUnits;
/** Flags, see SSMFILEHDR_FLAGS_XXX. */
uint32_t fFlags;
/** The maximum size of decompressed data. */
uint32_t cbMaxDecompr;
/** The checksum of this header.
* This field is set to zero when calculating the checksum. */
uint32_t u32CRC;
} __attribute__((packed)) SSMFILEHDR;
/**
* Data unit header.
*/
typedef struct SSMFILEUNITHDRV2
{
/** Magic (SSMFILEUNITHDR_MAGIC or SSMFILEUNITHDR_END). */
char szMagic[8];
/** The offset in the saved state stream of the start of this unit.
* This is mainly intended for sanity checking. */
uint64_t offStream;
/** The CRC-in-progress value this unit starts at. */
uint32_t u32CurStreamCRC;
/** The checksum of this structure, including the whole name.
* Calculated with this field set to zero. */
uint32_t u32CRC;
/** Data version. */
uint32_t u32Version;
/** Instance number. */
uint32_t u32Instance;
/** Data pass number. */
uint32_t u32Pass;
/** Flags reserved for future extensions. Must be zero. */
uint32_t fFlags;
/** Size of the data unit name including the terminator. (bytes) */
uint32_t cbName;
/** Data unit name, variable size. */
//char szName[SSM_MAX_NAME_SIZE];
} __attribute__((packed)) SSMFILEUNITHDRV2;
static const uint8_t UTF8ExtraBytes[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
static const uint8_t FirstByteBits[7] = {
0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
};
static const unsigned long FirstByteMask[6] = {
0xFF, 0x1F, 0x0F, 0x07, 0x03, 0x03
};
enum {
Low6Bits = 0x3F, /* 00111111 */
High2Bits = 0xC0, /* 11000000 */
ByteMask = 0x00BF, /* 10111111 */
ContinueBits = 0x80 /* 10xxxxxx */
};
long read_length(FILE *f)
{
unsigned char ch;
fread(&ch, 1, 1, f);
if ((ch & 0x80)==0) {
return ch;
} else {
int extra_bytes = UTF8ExtraBytes[ch];
char extra[256];
fread(extra, extra_bytes, 1, f);
long res = ch & FirstByteMask[extra_bytes];
unsigned char *src = extra;
do {
res <<= 6;
res |= ((*src++) & Low6Bits);
if (--extra_bytes == 0)
break;
} while (1);
return res;
}
}
char buf[16*1024*1024];
char outbuf[32*1024*1024];
unsigned int
lzf_decompress (const void *const in_data, unsigned int in_len,
void *out_data, unsigned int out_len);
int main(int argc, char *argv[])
{
SSMFILEHDR head;
char outname[1024];
unsigned char c;
FILE *f = fopen(argv[1], "rb");
if (!f) {
printf("cant open file\n");
return 0;
}
fread(&head, sizeof(SSMFILEHDR), 1, f);
printf("%s %ld\n", head.szMagic, head.cbMaxDecompr);
SSMFILEUNITHDRV2 unit;
while (!feof(f) && !ferror(f)) {
fread(&unit, sizeof(SSMFILEUNITHDRV2), 1, f);
printf("Magic %s streampos : %lld cbsize: %d\n", unit.szMagic, unit.offStream, unit.cbName);
memset(buf, 0, sizeof(buf));
fread(buf, unit.cbName, 1, f);
char nn[512];
memset(nn, 0, sizeof(nn));
memcpy(nn, buf, unit.cbName);
printf("CBNAME: %s\n", nn);
sprintf(outname, "%s-%s.out", argv[1], nn);
printf("outname: %s\n", outname);
FILE *fout = fopen(outname, "wb");
int rectype;
while (!feof(f) && !ferror(f)) {
fread(&c, 1, 1, f);
printf("C=> %02x\n", c);
rectype = c & 0xf;
printf("RECORD TYPE %02x\n", rectype);
if (rectype==1 || rectype==2 || rectype==3 || rectype==4) {
long r = read_length(f);
printf("len %ld\n", r);
if (rectype==4) {
int n = fread(buf, 1, 1, f);
printf("Zero count: %d\n", buf[1]);
} else {
buf[r+1] = '\0';
int n = fread(buf, 1, r, f);
printf("READ = %d\n", n);
//printf("BUF: %s\n", buf);
if (rectype==2) {
fwrite(buf, r, 1, fout);
}
if (rectype==3) {
int outlen = buf[0]*1024;
int decres = lzf_decompress(buf+1, r-1, outbuf, outlen);
printf("Decompress result: %d\n", decres);
fwrite(outbuf, outlen, 1, fout);
fflush(fout);
}
}
if (rectype==1) {
break;
}
}
if (rectype==00) {
printf("INVALID TYPE\n");
break;
}
}
fclose(fout);
if (rectype==00) {
break;
}
}
return 0;
}