/src/samba/librpc/ndr/ndr_cab.c
Line | Count | Source |
1 | | /* |
2 | | Unix SMB/CIFS implementation. |
3 | | |
4 | | routines for marshalling/unmarshalling cab structures |
5 | | |
6 | | Copyright (C) Guenther Deschner 2016 |
7 | | |
8 | | This program is free software; you can redistribute it and/or modify |
9 | | it under the terms of the GNU General Public License as published by |
10 | | the Free Software Foundation; either version 3 of the License, or |
11 | | (at your option) any later version. |
12 | | |
13 | | This program is distributed in the hope that it will be useful, |
14 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | GNU General Public License for more details. |
17 | | |
18 | | You should have received a copy of the GNU General Public License |
19 | | along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | | */ |
21 | | |
22 | | #include "includes.h" |
23 | | #include "librpc/gen_ndr/ndr_cab.h" |
24 | | #include "librpc/ndr/ndr_compression.h" |
25 | | |
26 | 202k | #define OFFSET_OF_FOLDER_COFFCABSTART(folder) (36 /* cfheader size */ + (size_t)(folder)*8) |
27 | | |
28 | | _PUBLIC_ void ndr_print_cf_time(struct ndr_print *ndr, const char *name, const struct cf_time *r) |
29 | 88.6k | { |
30 | 88.6k | uint8_t hour = 0, minute = 0, seconds = 0; |
31 | 88.6k | char *s; |
32 | 88.6k | if (r == NULL) { ndr_print_null(ndr); return; } |
33 | 88.6k | hour = r->time >> 11; |
34 | 88.6k | minute = (r->time >> 5) & 0x3f; |
35 | 88.6k | seconds = (r->time << 1) & 0x3e; |
36 | 88.6k | s = talloc_asprintf(ndr, "%02d:%02d:%02d", hour, minute, seconds); |
37 | 88.6k | if (s == NULL) { return; } |
38 | 88.6k | ndr_print_string(ndr, "time", s); |
39 | 88.6k | TALLOC_FREE(s); |
40 | 88.6k | } |
41 | | |
42 | | _PUBLIC_ void ndr_print_cf_date(struct ndr_print *ndr, const char *name, const struct cf_date *r) |
43 | 88.6k | { |
44 | 88.6k | uint16_t year = 0; |
45 | 88.6k | uint8_t month = 0, day = 0; |
46 | 88.6k | char *s; |
47 | 88.6k | if (r == NULL) { ndr_print_null(ndr); return; } |
48 | 88.6k | year = (r->date >> 9); |
49 | 88.6k | year += 1980; |
50 | 88.6k | month = (r->date >> 5 & 0xf); |
51 | 88.6k | day = (r->date & 0x1f); |
52 | 88.6k | s = talloc_asprintf(ndr, "%02"PRIu8"/%02"PRIu8"/%04"PRIu16, day, month, year); |
53 | 88.6k | if (s == NULL) { return; } |
54 | 88.6k | ndr_print_string(ndr, "date", s); |
55 | 88.6k | TALLOC_FREE(s); |
56 | 88.6k | } |
57 | | |
58 | | uint32_t ndr_count_cfdata(const struct cab_file *r) |
59 | 995 | { |
60 | 995 | uint32_t count = 0, i; |
61 | | |
62 | 584k | for (i = 0; i < r->cfheader.cFolders; i++) { |
63 | 583k | if (count + r->cffolders[i].cCFData < count) { |
64 | | /* Integer wrap. */ |
65 | 0 | return 0; |
66 | 0 | } |
67 | 583k | count += r->cffolders[i].cCFData; |
68 | 583k | } |
69 | | |
70 | 995 | return count; |
71 | 995 | } |
72 | | |
73 | | static uint32_t ndr_cab_compute_checksum(uint8_t *data, uint32_t length, uint32_t seed) |
74 | 765k | { |
75 | 765k | int num_ulong; |
76 | 765k | uint32_t checksum; |
77 | 765k | uint8_t *pb; |
78 | 765k | uint32_t ul; |
79 | | |
80 | 765k | num_ulong = length / 4; |
81 | 765k | checksum = seed; |
82 | 765k | pb = data; |
83 | | |
84 | 2.51M | while (num_ulong-- > 0) { |
85 | 1.74M | ul = (uint32_t)(*pb++); |
86 | 1.74M | ul |= (((uint32_t)(*pb++)) << 8); |
87 | 1.74M | ul |= (((uint32_t)(*pb++)) << 16); |
88 | 1.74M | ul |= (((uint32_t)(*pb++)) << 24); |
89 | | |
90 | 1.74M | checksum ^= ul; |
91 | 1.74M | } |
92 | | |
93 | 765k | ul = 0; |
94 | | |
95 | 765k | switch (length % 4) { |
96 | 704 | case 3: |
97 | 704 | ul |= (((uint32_t)(*pb++)) << 16); |
98 | 704 | FALL_THROUGH; |
99 | 2.05k | case 2: |
100 | 2.05k | ul |= (((uint32_t)(*pb++)) << 8); |
101 | 2.05k | FALL_THROUGH; |
102 | 4.12k | case 1: |
103 | 4.12k | ul |= (uint32_t)(*pb++); |
104 | 4.12k | FALL_THROUGH; |
105 | 765k | default: |
106 | 765k | break; |
107 | 765k | } |
108 | | |
109 | 765k | checksum ^= ul; |
110 | | |
111 | 765k | return checksum; |
112 | 765k | } |
113 | | |
114 | | /* Push all CFDATA of a folder. |
115 | | * |
116 | | * This works on a folder level because compression type is set per |
117 | | * folder, and a compression state can be shared between CFDATA of the |
118 | | * same folder. |
119 | | * |
120 | | * This is not a regular NDR func as we pass the compression type and |
121 | | * the number of CFDATA as extra arguments |
122 | | */ |
123 | | static enum ndr_err_code ndr_push_folder_cfdata(struct ndr_push *ndr, |
124 | | const struct CFDATA *r, |
125 | | enum cf_compress_type cab_ctype, |
126 | | size_t num_cfdata) |
127 | 202k | { |
128 | 202k | size_t i; |
129 | 202k | enum ndr_compression_alg ndr_ctype = 0; |
130 | | |
131 | 202k | ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX|LIBNDR_FLAG_LITTLE_ENDIAN|LIBNDR_FLAG_NOALIGN); |
132 | | |
133 | 202k | if (cab_ctype == CF_COMPRESS_MSZIP) { |
134 | 549 | ndr_ctype = NDR_COMPRESSION_MSZIP_CAB; |
135 | 549 | NDR_CHECK(ndr_push_compression_state_init(ndr, ndr_ctype)); |
136 | 549 | } |
137 | | |
138 | 585k | for (i = 0; i < num_cfdata; i++, r++) { |
139 | 383k | uint32_t compressed_length = 0; |
140 | 383k | uint32_t csum, csumPartial; |
141 | 383k | size_t compressed_offset, csum_offset, data_offset; |
142 | | |
143 | 383k | if (!r->ab.data) { |
144 | 6 | return ndr_push_error(ndr, NDR_ERR_LENGTH, |
145 | 6 | "NULL uncompressed data blob"); |
146 | 6 | } |
147 | 383k | if (r->ab.length != r->cbUncomp) { |
148 | 41 | return ndr_push_error(ndr, NDR_ERR_LENGTH, |
149 | 41 | "Uncompressed data blob size != uncompressed data size field"); |
150 | 41 | } |
151 | | |
152 | | /* |
153 | | * checksum is a function of the size fields |
154 | | * and the potentially compressed data bytes, |
155 | | * which haven't been compressed yet so |
156 | | * remember offset, write zeroes, fill out |
157 | | * later |
158 | | */ |
159 | 382k | csum_offset = ndr->offset; |
160 | 382k | NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); |
161 | | |
162 | | /* |
163 | | * similarly, we don't know the compressed |
164 | | * size yet, remember offset, write zeros, |
165 | | * fill out later |
166 | | */ |
167 | 382k | compressed_offset = ndr->offset; |
168 | 382k | NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 0)); |
169 | 382k | NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->cbUncomp)); |
170 | | |
171 | 382k | data_offset = ndr->offset; |
172 | | |
173 | 382k | switch (cab_ctype) { |
174 | 382k | case CF_COMPRESS_NONE: |
175 | | /* just copy the data */ |
176 | 382k | NDR_PUSH_NEED_BYTES(ndr, r->ab.length); |
177 | 382k | NDR_CHECK(ndr_push_bytes(ndr, r->ab.data, r->ab.length)); |
178 | 382k | compressed_length = r->ab.length; |
179 | 382k | break; |
180 | 5 | case CF_COMPRESS_LZX: |
181 | | /* |
182 | | * we have not yet worked out the details of LZX |
183 | | * compression |
184 | | */ |
185 | 5 | return NDR_ERR_COMPRESSION; |
186 | | |
187 | 466 | case CF_COMPRESS_MSZIP: { |
188 | 466 | struct ndr_push *push_sub, *push_compress; |
189 | | |
190 | | /* compress via subcontext */ |
191 | 466 | NDR_CHECK(ndr_push_subcontext_start(ndr, &push_sub, 0, -1)); |
192 | | |
193 | | /* |
194 | | * This assignment replaces a call to |
195 | | * ndr_push_compression_state_init(push_sub, ndr_ctype)) |
196 | | * here. This is instead done outside the loop. |
197 | | */ |
198 | 466 | push_sub->cstate = ndr->cstate; |
199 | | |
200 | 466 | NDR_CHECK(ndr_push_compression_start(push_sub, &push_compress)); |
201 | 466 | ndr_set_flags(&push_compress->flags, LIBNDR_FLAG_REMAINING); |
202 | 466 | NDR_CHECK(ndr_push_DATA_BLOB(push_compress, NDR_SCALARS, r->ab)); |
203 | 466 | NDR_CHECK(ndr_push_compression_end(push_sub, push_compress)); |
204 | 466 | NDR_CHECK(ndr_push_subcontext_end(ndr, push_sub, 0, -1)); |
205 | 466 | compressed_length = push_sub->offset; |
206 | | |
207 | 466 | break; |
208 | 466 | } |
209 | 0 | default: |
210 | 0 | return NDR_ERR_BAD_SWITCH; |
211 | 382k | } |
212 | | |
213 | | /* we can now write the compressed size and the checksum */ |
214 | 382k | SSVAL(ndr->data, compressed_offset, compressed_length); |
215 | | |
216 | | /* |
217 | | * Create checksum over compressed data. |
218 | | * |
219 | | * The 8 bytes are the header size. |
220 | | * |
221 | | * We have already have written the checksum and set it to zero, |
222 | | * earlier. So we know that after the checksum end the value |
223 | | * for the compressed length comes the blob data. |
224 | | * |
225 | | * NDR already did all the checks for integer wraps. |
226 | | */ |
227 | 382k | csumPartial = ndr_cab_compute_checksum(&ndr->data[data_offset], |
228 | 382k | compressed_length, 0); |
229 | | |
230 | | /* |
231 | | * Checksum over header (compressed and uncompressed length). |
232 | | * |
233 | | * The first 4 bytes are the checksum size. |
234 | | * The second 4 bytes are the size of the compressed and |
235 | | * uncompressed length fields. |
236 | | * |
237 | | * NDR already did all the checks for integer wraps. |
238 | | */ |
239 | 382k | csum = ndr_cab_compute_checksum(&ndr->data[compressed_offset], |
240 | 382k | data_offset - compressed_offset, |
241 | 382k | csumPartial); |
242 | | |
243 | 382k | SIVAL(ndr->data, csum_offset, csum); |
244 | 382k | } |
245 | | |
246 | 202k | TALLOC_FREE(ndr->cstate); |
247 | | |
248 | 202k | return NDR_ERR_SUCCESS; |
249 | 202k | } |
250 | | |
251 | | _PUBLIC_ enum ndr_err_code ndr_push_cab_file(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct cab_file *r) |
252 | 423 | { |
253 | 423 | uint32_t cntr_cffolders_0; |
254 | 423 | uint32_t cntr_cffiles_0; |
255 | 423 | size_t processed_cfdata = 0; |
256 | 423 | { |
257 | 423 | libndr_flags _flags_save_STRUCT = ndr->flags; |
258 | 423 | ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX|LIBNDR_FLAG_LITTLE_ENDIAN|LIBNDR_FLAG_NOALIGN); |
259 | 423 | NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); |
260 | | |
261 | 423 | if (ndr_flags & NDR_SCALARS) { |
262 | 423 | uint32_t i; |
263 | 423 | NDR_CHECK(ndr_push_align(ndr, 4)); |
264 | 423 | NDR_CHECK(ndr_push_CFHEADER(ndr, NDR_SCALARS, &r->cfheader)); |
265 | 202k | for (cntr_cffolders_0 = 0; cntr_cffolders_0 < (r->cfheader.cFolders); cntr_cffolders_0++) { |
266 | 202k | NDR_CHECK(ndr_push_CFFOLDER(ndr, NDR_SCALARS, &r->cffolders[cntr_cffolders_0])); |
267 | 202k | } |
268 | 88.7k | for (cntr_cffiles_0 = 0; cntr_cffiles_0 < (r->cfheader.cFiles); cntr_cffiles_0++) { |
269 | 88.3k | NDR_CHECK(ndr_push_CFFILE(ndr, NDR_SCALARS, &r->cffiles[cntr_cffiles_0])); |
270 | 88.3k | } |
271 | | #if 0 |
272 | | NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_count_cfdata(r))); |
273 | | #endif |
274 | | |
275 | | /* write in the folder header the offset of its first data block */ |
276 | 202k | for (i = 0; i < r->cfheader.cFolders; i++) { |
277 | 202k | size_t off = OFFSET_OF_FOLDER_COFFCABSTART(i); |
278 | | /* check that the offset we want to |
279 | | * write to is always inside our |
280 | | * current push buffer |
281 | | */ |
282 | 202k | if (off >= ndr->offset) { |
283 | 0 | return ndr_push_error(ndr, NDR_ERR_OFFSET, |
284 | 0 | "trying to write past current push buffer size"); |
285 | 0 | } |
286 | 202k | SIVAL(ndr->data, off, ndr->offset); |
287 | 202k | NDR_CHECK(ndr_push_folder_cfdata(ndr, r->cfdata + processed_cfdata, r->cffolders[i].typeCompress, r->cffolders[i].cCFData)); |
288 | 202k | processed_cfdata += r->cffolders[i].cCFData; |
289 | 202k | } |
290 | 371 | NDR_CHECK(ndr_push_trailer_align(ndr, 4)); |
291 | 371 | } |
292 | 371 | if (ndr_flags & NDR_BUFFERS) { |
293 | 371 | } |
294 | 371 | ndr->flags = _flags_save_STRUCT; |
295 | 371 | } |
296 | | |
297 | | |
298 | | /* write total file size in header */ |
299 | 371 | SIVAL(ndr->data, 8, ndr->offset); |
300 | | |
301 | 371 | return NDR_ERR_SUCCESS; |
302 | 423 | } |
303 | | |
304 | | |
305 | | /* Pull all CFDATA of a folder. |
306 | | * |
307 | | * This works on a folder level because compression type is set per |
308 | | * folder, and a compression state can be shared between CFDATA of the |
309 | | * same folder. |
310 | | * |
311 | | * This is not a regular NDR func as we pass the compression type and |
312 | | * the number of CFDATA as extra arguments |
313 | | */ |
314 | | static enum ndr_err_code ndr_pull_folder_cfdata(struct ndr_pull *ndr, |
315 | | struct CFDATA *r, |
316 | | enum cf_compress_type cab_ctype, |
317 | | size_t num_cfdata) |
318 | 219k | { |
319 | 219k | size_t i; |
320 | 219k | enum ndr_compression_alg ndr_ctype = 0; |
321 | | |
322 | 219k | if (cab_ctype == CF_COMPRESS_MSZIP) { |
323 | 912 | ndr_ctype = NDR_COMPRESSION_MSZIP_CAB; |
324 | 912 | NDR_CHECK(ndr_pull_compression_state_init(ndr, NDR_COMPRESSION_MSZIP_CAB, &ndr->cstate)); |
325 | 912 | } |
326 | | |
327 | 934k | for (i = 0; i < num_cfdata; i++, r++) { |
328 | 715k | NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->csum)); |
329 | 715k | NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->cbData)); |
330 | 715k | NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->cbUncomp)); |
331 | | |
332 | 715k | switch (cab_ctype) { |
333 | 588k | case CF_COMPRESS_NONE: |
334 | | /* just copy the data */ |
335 | 588k | NDR_PULL_NEED_BYTES(ndr, r->cbUncomp); |
336 | 588k | r->ab = data_blob_talloc(ndr->current_mem_ctx, |
337 | 588k | ndr->data+ndr->offset, |
338 | 588k | r->cbUncomp); |
339 | 588k | if (r->ab.data == NULL) { |
340 | 0 | return ndr_pull_error(ndr, NDR_ERR_ALLOC, |
341 | 0 | "failed to allocate buffer for uncompressed CFDATA block"); |
342 | 0 | } |
343 | 588k | ndr->offset += r->cbUncomp; |
344 | 588k | break; |
345 | | |
346 | 124k | case CF_COMPRESS_LZX: |
347 | | /* just copy the data (LZX decompression not implemented yet) */ |
348 | 124k | NDR_PULL_NEED_BYTES(ndr, r->cbData); |
349 | 124k | r->ab = data_blob_talloc(ndr->current_mem_ctx, |
350 | 124k | ndr->data+ndr->offset, |
351 | 124k | r->cbData); |
352 | 124k | if (r->ab.data == NULL) { |
353 | 0 | return ndr_pull_error(ndr, NDR_ERR_ALLOC, |
354 | 0 | "failed to allocate buffer for LZX-compressed CFDATA block"); |
355 | 0 | } |
356 | 124k | ndr->offset += r->cbData; |
357 | 124k | break; |
358 | | |
359 | 2.20k | case CF_COMPRESS_MSZIP: { |
360 | 2.20k | struct ndr_pull *pull_sub, *pull_compress; |
361 | 2.20k | NDR_PULL_NEED_BYTES(ndr, r->cbData); |
362 | | /* decompress via subcontext */ |
363 | 2.15k | NDR_CHECK(ndr_pull_subcontext_start(ndr, &pull_sub, 0, r->cbData)); |
364 | 2.15k | pull_sub->cstate = ndr->cstate; |
365 | 2.15k | NDR_CHECK(ndr_pull_compression_start(pull_sub, &pull_compress, |
366 | 2.15k | ndr_ctype, r->cbUncomp, r->cbData)); |
367 | 1.99k | ndr_set_flags(&pull_compress->flags, LIBNDR_FLAG_REMAINING); |
368 | 1.99k | NDR_CHECK(ndr_pull_DATA_BLOB(pull_compress, NDR_SCALARS, &r->ab)); |
369 | 1.99k | NDR_CHECK(ndr_pull_compression_end(pull_sub, pull_compress, ndr_ctype, r->cbUncomp)); |
370 | 1.99k | NDR_CHECK(ndr_pull_subcontext_end(ndr, pull_sub, 0, r->cbData)); |
371 | | |
372 | 1.99k | break; |
373 | 1.99k | } |
374 | 1.99k | default: |
375 | 38 | return NDR_ERR_BAD_SWITCH; |
376 | 715k | } |
377 | 715k | } |
378 | | |
379 | 218k | TALLOC_FREE(ndr->cstate); |
380 | | |
381 | 218k | return NDR_ERR_SUCCESS; |
382 | 219k | } |
383 | | |
384 | | _PUBLIC_ enum ndr_err_code ndr_pull_cab_file(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct cab_file *r) |
385 | 1.24k | { |
386 | 1.24k | uint32_t size_cffolders_0 = 0; |
387 | 1.24k | uint32_t cntr_cffolders_0; |
388 | 1.24k | TALLOC_CTX *_mem_save_cffolders_0 = NULL; |
389 | 1.24k | uint32_t size_cffiles_0 = 0; |
390 | 1.24k | uint32_t cntr_cffiles_0; |
391 | 1.24k | TALLOC_CTX *_mem_save_cffiles_0 = NULL; |
392 | 1.24k | uint32_t size_cfdata_0 = 0; |
393 | 1.24k | size_t processed_cfdata = 0; |
394 | 1.24k | TALLOC_CTX *_mem_save_cfdata_0 = NULL; |
395 | 1.24k | { |
396 | 1.24k | libndr_flags _flags_save_STRUCT = ndr->flags; |
397 | 1.24k | ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX|LIBNDR_FLAG_LITTLE_ENDIAN|LIBNDR_FLAG_NOALIGN); |
398 | 1.24k | NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); |
399 | 1.24k | if (ndr_flags & NDR_SCALARS) { |
400 | 1.24k | NDR_CHECK(ndr_pull_align(ndr, 4)); |
401 | 1.24k | NDR_CHECK(ndr_pull_CFHEADER(ndr, NDR_SCALARS, &r->cfheader)); |
402 | 1.22k | size_cffolders_0 = r->cfheader.cFolders; |
403 | 1.22k | NDR_PULL_ALLOC_N(ndr, r->cffolders, size_cffolders_0); |
404 | 1.22k | _mem_save_cffolders_0 = NDR_PULL_GET_MEM_CTX(ndr); |
405 | 1.22k | NDR_PULL_SET_MEM_CTX(ndr, r->cffolders, 0); |
406 | 875k | for (cntr_cffolders_0 = 0; cntr_cffolders_0 < (size_cffolders_0); cntr_cffolders_0++) { |
407 | 874k | NDR_CHECK(ndr_pull_CFFOLDER(ndr, NDR_SCALARS, &r->cffolders[cntr_cffolders_0])); |
408 | 874k | } |
409 | 1.16k | NDR_PULL_SET_MEM_CTX(ndr, _mem_save_cffolders_0, 0); |
410 | 1.16k | size_cffiles_0 = r->cfheader.cFiles; |
411 | 1.16k | NDR_PULL_ALLOC_N(ndr, r->cffiles, size_cffiles_0); |
412 | 1.16k | _mem_save_cffiles_0 = NDR_PULL_GET_MEM_CTX(ndr); |
413 | 1.16k | NDR_PULL_SET_MEM_CTX(ndr, r->cffiles, 0); |
414 | 322k | for (cntr_cffiles_0 = 0; cntr_cffiles_0 < (size_cffiles_0); cntr_cffiles_0++) { |
415 | 321k | NDR_CHECK(ndr_pull_CFFILE(ndr, NDR_SCALARS, &r->cffiles[cntr_cffiles_0])); |
416 | 321k | } |
417 | 995 | NDR_PULL_SET_MEM_CTX(ndr, _mem_save_cffiles_0, 0); |
418 | | #if 0 |
419 | | NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->cfdata_count)); |
420 | | #else |
421 | 995 | r->cfdata_count = ndr_count_cfdata(r); |
422 | 995 | #endif |
423 | 995 | size_cfdata_0 = r->cfdata_count; |
424 | 995 | NDR_PULL_ALLOC_N(ndr, r->cfdata, size_cfdata_0); |
425 | 981 | _mem_save_cfdata_0 = NDR_PULL_GET_MEM_CTX(ndr); |
426 | 981 | NDR_PULL_SET_MEM_CTX(ndr, r->cfdata, 0); |
427 | 219k | for (cntr_cffolders_0 = 0; cntr_cffolders_0 < (size_cffolders_0); cntr_cffolders_0++) { |
428 | 219k | NDR_CHECK(ndr_pull_folder_cfdata(ndr, |
429 | 219k | r->cfdata + processed_cfdata, |
430 | 219k | r->cffolders[cntr_cffolders_0].typeCompress, |
431 | 219k | r->cffolders[cntr_cffolders_0].cCFData)); |
432 | 218k | processed_cfdata += r->cffolders[cntr_cffolders_0].cCFData; |
433 | 218k | } |
434 | 423 | NDR_PULL_SET_MEM_CTX(ndr, _mem_save_cfdata_0, 0); |
435 | 423 | NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); |
436 | 423 | } |
437 | 423 | if (ndr_flags & NDR_BUFFERS) { |
438 | 423 | } |
439 | 423 | ndr->flags = _flags_save_STRUCT; |
440 | 423 | } |
441 | 0 | return NDR_ERR_SUCCESS; |
442 | 1.24k | } |