Line data Source code
1 : /* $OpenBSD: ntfs_compr.c,v 1.7 2013/11/24 16:02:30 jsing Exp $ */
2 : /* $NetBSD: ntfs_compr.c,v 1.1 2002/12/23 17:38:31 jdolecek Exp $ */
3 :
4 : /*-
5 : * Copyright (c) 1998, 1999 Semen Ustimenko
6 : * All rights reserved.
7 : *
8 : * Redistribution and use in source and binary forms, with or without
9 : * modification, are permitted provided that the following conditions
10 : * are met:
11 : * 1. Redistributions of source code must retain the above copyright
12 : * notice, this list of conditions and the following disclaimer.
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 : * SUCH DAMAGE.
28 : *
29 : * Id: ntfs_compr.c,v 1.4 1999/05/12 09:42:54 semenu Exp
30 : */
31 :
32 : #include <sys/param.h>
33 : #include <sys/systm.h>
34 : #include <sys/mount.h>
35 :
36 : #include <ntfs/ntfs.h>
37 : #include <ntfs/ntfs_compr.h>
38 :
39 : #define GET_UINT16(addr) (*((u_int16_t *)(addr)))
40 :
41 : int
42 0 : ntfs_uncompblock(u_int8_t *buf, u_int8_t *cbuf)
43 : {
44 : u_int32_t ctag;
45 : int len, dshift, lmask;
46 : int blen, boff;
47 : int i, j;
48 : int pos, cpos;
49 :
50 0 : len = GET_UINT16(cbuf) & 0xFFF;
51 : DPRINTF("ntfs_uncompblock: block length: %d + 3, 0x%x,0x%04x\n",
52 : len, len, GET_UINT16(cbuf));
53 :
54 0 : if (!(GET_UINT16(cbuf) & 0x8000)) {
55 0 : if ((len + 1) != NTFS_COMPBLOCK_SIZE) {
56 : DPRINTF("ntfs_uncompblock: len: %x instead of %d\n",
57 : len, 0xfff);
58 : }
59 0 : memcpy(buf, cbuf + 2, len + 1);
60 0 : bzero(buf + len + 1, NTFS_COMPBLOCK_SIZE - 1 - len);
61 0 : return (len + 3);
62 : }
63 : cpos = 2;
64 : pos = 0;
65 0 : while ((cpos < len + 3) && (pos < NTFS_COMPBLOCK_SIZE)) {
66 0 : ctag = cbuf[cpos++];
67 0 : for (i = 0; (i < 8) && (pos < NTFS_COMPBLOCK_SIZE); i++) {
68 0 : if (ctag & 1) {
69 0 : for (j = pos - 1, lmask = 0xFFF, dshift = 12;
70 0 : j >= 0x10; j >>= 1) {
71 0 : dshift--;
72 0 : lmask >>= 1;
73 : }
74 0 : boff = -1 - (GET_UINT16(cbuf + cpos) >> dshift);
75 0 : blen = 3 + (GET_UINT16(cbuf + cpos) & lmask);
76 0 : for (j = 0; (j < blen) &&
77 0 : (pos < NTFS_COMPBLOCK_SIZE); j++) {
78 0 : buf[pos] = buf[pos + boff];
79 0 : pos++;
80 : }
81 0 : cpos += 2;
82 0 : } else {
83 0 : buf[pos++] = cbuf[cpos++];
84 : }
85 0 : ctag >>= 1;
86 : }
87 : }
88 0 : return (len + 3);
89 0 : }
90 :
91 : int
92 0 : ntfs_uncompunit(struct ntfsmount *ntmp, u_int8_t *uup, u_int8_t *cup)
93 : {
94 : int i;
95 : int off = 0;
96 : int new;
97 :
98 0 : for (i = 0; i * NTFS_COMPBLOCK_SIZE < ntfs_cntob(NTFS_COMPUNIT_CL);
99 0 : i++) {
100 0 : new = ntfs_uncompblock(uup + i * NTFS_COMPBLOCK_SIZE,
101 0 : cup + off);
102 0 : if (new == 0)
103 0 : return (EINVAL);
104 0 : off += new;
105 : }
106 0 : return (0);
107 0 : }
|