]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/win32filter.c
f6533f3c6c90acb78890f07e2470146bd8e101e7
[bacula/bacula] / bacula / src / findlib / win32filter.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2015 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is 
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19
20 #include "win32filter.h"
21
22 #define WIN32_STREAM_HEADER_SIZE 20 /* the size of the WIN32_STREAM_ID header without the name */
23
24 /* search in a record of a STREAM_WIN32_DATA for the true data
25  * when found: return true, '*raw' is set at the beginning of the data
26  * and *use_len is the length of data to read.
27  * *raw_len is decremented and contains the amount of data that as not
28  * been filtered yet.
29  * For this STREAM_WIN32_DATA, you can call have_data() only one
30  * per record.
31  * If the stream where the data is can be spread all around the stream
32  * you must call have_data() until *raw_len is zero and increment
33  * *data before the next call.
34  */
35 bool Win32Filter::have_data(char **raw, int64_t *raw_len, int64_t *use_len)
36 {
37    int64_t size;
38    char *orig=*raw;
39    Dmsg1(100, "have_data(%lld)\n", *raw_len);
40    while (*raw_len > 0) {
41       /* In this rec, we could have multiple streams of data and headers
42        * to handle before to reach the data, then we must iterate
43        */
44
45       Dmsg4(100, "s off=%lld len=%lld skip_size=%lld data_size=%lld\n", *raw-orig, *raw_len, skip_size, data_size);
46       if (skip_size > 0) {
47          /* skip what the previous header told us to skip */
48          size = *raw_len < skip_size ? *raw_len : skip_size;
49          skip_size -= size;
50          *raw_len -= size;
51          *raw += size;
52       }
53
54       Dmsg4(100, "h off=%lld len=%lld skip_size=%lld data_size=%lld\n", *raw-orig, *raw_len, skip_size, data_size);
55       if (data_size == 0 && skip_size == 0 && *raw_len > 0) {
56          /* read a WIN32_STREAM header, merge it with the part that was read
57           * from the previous record, if any, if the header was split across
58           * 2 records.
59           */
60          size = WIN32_STREAM_HEADER_SIZE - header_pos;
61          if (*raw_len < size) {
62             size = *raw_len;
63          }
64          memcpy((char *)&header + header_pos, *raw, size);
65          header_pos += size;
66          *raw_len -= size;
67          *raw += size;
68          if (header_pos == WIN32_STREAM_HEADER_SIZE) {
69             Dmsg5(100, "header pos=%d size=%lld name_size=%d len=%lld StreamId=0x%x\n", header_pos, size,
70                   header.dwStreamNameSize, header.Size, header.dwStreamId);
71             header_pos = 0;
72             skip_size = header.dwStreamNameSize; /* skip the name of the stream */
73             if (header.dwStreamId == WIN32_BACKUP_DATA) {
74                data_size = header.Size;
75             } else {
76                skip_size += header.Size; /* skip the all stream */
77             }
78          }
79          Dmsg4(100, "H off=%lld len=%lld skip_size=%lld data_size=%lld\n", *raw-orig, *raw_len, skip_size, data_size);
80       }
81
82       Dmsg4(100, "d off=%lld len=%lld skip_size=%lld data_size=%lld\n", *raw - orig, *raw_len, skip_size, data_size);
83       if (data_size > 0 && skip_size == 0 && *raw_len > 0) {
84          /* some data to read */
85          size = *raw_len < data_size ? *raw_len : data_size;
86          data_size -= size;
87          *raw_len -= size;
88          *use_len = size;
89          Dmsg5(100, "D off=%lld len=%lld use_len=%lld skip_size=%lld data_size=%lld\n", *raw-orig, *raw_len,
90                *use_len, skip_size, data_size);
91          return true;
92       }
93    }
94
95    return false;
96 }