ntfs_compr.c revision 86927
1130167Sgad/* $NetBSD: ntfs_compr.c,v 1.3 1999/07/26 14:02:31 jdolecek Exp $ */ 2130167Sgad 3130167Sgad/*- 4130167Sgad * Copyright (c) 1998, 1999 Semen Ustimenko 5130167Sgad * All rights reserved. 6130167Sgad * 7130167Sgad * Redistribution and use in source and binary forms, with or without 8130167Sgad * modification, are permitted provided that the following conditions 9130167Sgad * are met: 10130167Sgad * 1. Redistributions of source code must retain the above copyright 11130167Sgad * notice, this list of conditions and the following disclaimer. 12130167Sgad * 2. Redistributions in binary form must reproduce the above copyright 13130167Sgad * notice, this list of conditions and the following disclaimer in the 14130167Sgad * documentation and/or other materials provided with the distribution. 15130167Sgad * 16130167Sgad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17130167Sgad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18130167Sgad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19130167Sgad * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20130167Sgad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21130167Sgad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22130167Sgad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23130167Sgad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24130167Sgad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25130167Sgad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26130167Sgad * SUCH DAMAGE. 27130167Sgad * 28130167Sgad * $FreeBSD: head/sys/fs/ntfs/ntfs_compr.c 86927 2001-11-26 23:45:12Z jhb $ 29130167Sgad */ 30130167Sgad 3113244Sgraichen#include <sys/param.h> 3213244Sgraichen#include <sys/systm.h> 3313244Sgraichen#include <sys/namei.h> 3413244Sgraichen#include <sys/vnode.h> 3513244Sgraichen#include <sys/mount.h> 3659004Shm#include <sys/file.h> 3759004Shm 3859004Shm#include <fs/ntfs/ntfs.h> 3959004Shm#include <fs/ntfs/ntfs_compr.h> 4059004Shm 4159004Shm#define GET_UINT16(addr) (*((u_int16_t *)(addr))) 4259004Shm 4359004Shmint 4459004Shmntfs_uncompblock( 4559004Shm u_int8_t * buf, 4659004Shm u_int8_t * cbuf) 4759004Shm{ 4859004Shm u_int32_t ctag; 4959004Shm int len, dshift, lmask; 5013244Sgraichen int blen, boff; 5113244Sgraichen int i, j; 5259004Shm int pos, cpos; 5359004Shm 5413244Sgraichen len = GET_UINT16(cbuf) & 0xFFF; 5513244Sgraichen dprintf(("ntfs_uncompblock: block length: %d + 3, 0x%x,0x%04x\n", 56114601Sobrien len, len, GET_UINT16(cbuf))); 57114601Sobrien 5813244Sgraichen if (!(GET_UINT16(cbuf) & 0x8000)) { 59130045Sgad if ((len + 1) != NTFS_COMPBLOCK_SIZE) { 6013244Sgraichen dprintf(("ntfs_uncompblock: len: %x instead of %d\n", 6196001Smaxim len, 0xfff)); 62130167Sgad } 6396001Smaxim memcpy(buf, cbuf + 2, len + 1); 6496001Smaxim bzero(buf + len + 1, NTFS_COMPBLOCK_SIZE - 1 - len); 6596001Smaxim return len + 3; 66210372Ssimon } 6730160Scharnier cpos = 2; 6830160Scharnier pos = 0; 6995999Smaxim while ((cpos < len + 3) && (pos < NTFS_COMPBLOCK_SIZE)) { 70210372Ssimon ctag = cbuf[cpos++]; 7130160Scharnier for (i = 0; (i < 8) && (pos < NTFS_COMPBLOCK_SIZE); i++) { 72111773Sgad if (ctag & 1) { 73106905Ssobomax for (j = pos - 1, lmask = 0xFFF, dshift = 12; 7430160Scharnier j >= 0x10; j >>= 1) { 7543071Swollman dshift--; 7630160Scharnier lmask >>= 1; 7730160Scharnier } 7813244Sgraichen boff = -1 - (GET_UINT16(cbuf + cpos) >> dshift); 79210372Ssimon blen = 3 + (GET_UINT16(cbuf + cpos) & lmask); 8013244Sgraichen for (j = 0; (j < blen) && (pos < NTFS_COMPBLOCK_SIZE); j++) { 8113244Sgraichen buf[pos] = buf[pos + boff]; 8243071Swollman pos++; 8316240Salex } 8413244Sgraichen cpos += 2; 8543071Swollman } else { 86119998Sgad buf[pos++] = cbuf[cpos++]; 8743071Swollman } 88111768Sgad ctag >>= 1; 89218127Smm } 90218127Smm } 91218127Smm return len + 3; 92218127Smm} 93218127Smm 94218127Smmint 95218127Smmntfs_uncompunit( 96218127Smm struct ntfsmount * ntmp, 97218127Smm u_int8_t * uup, 98218127Smm u_int8_t * cup) 99218127Smm{ 100218127Smm int i; 101218127Smm int off = 0; 102218127Smm int new; 103218127Smm 104218127Smm for (i = 0; i * NTFS_COMPBLOCK_SIZE < ntfs_cntob(NTFS_COMPUNIT_CL); i++) { 105218127Smm new = ntfs_uncompblock(uup + i * NTFS_COMPBLOCK_SIZE, cup + off); 106218127Smm if (new == 0) 107218127Smm return (EINVAL); 108218127Smm off += new; 109218127Smm } 110218127Smm return (0); 111218127Smm} 112218127Smm