Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/libntfs
In directory usw-pr-cvs1:/tmp/cvs-serv26977/libntfs
Modified Files:
volume.c
Added Files:
bitmap.c bootsect.c mft.c ntfs_rec.c
Log Message:
More files added to ntfs lib. Fixed some consistency problems.
--- NEW FILE ---
/*
* bitmap.c - Bitmap handling code. Part of the Linux-NTFS project.
*
* Copyright (c) 2000,2001 Anton Altaparmakov.
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "bitmap.h"
/*
* NOTES:
*
* - Operations are 8-bit only to ensure the functions work both on little
* and big endian machines! So don't make them 32-bit ops!
* - bitmap starts at bit = 0 and ends at bit = bitmap size - 1.
* - _Caller_ has to make sure that the bit to operate on is less than the
* size of the bitmap.
*/
inline void set_bit(__u8 *bitmap, const __u64 bit, const __u8 new_value)
{
if (!bitmap || new_value > 1)
return;
if (!new_value)
bitmap[bit >> 3] &= ~(1 << (bit & 7));
else
bitmap[bit >> 3] |= (1 << (bit & 7));
}
inline char get_bit(const __u8 *bitmap, const __u64 bit)
{
if (!bitmap)
return -1;
return (bitmap[bit >> 3] >> (bit & 7)) & 1;
}
inline char get_and_set_bit(__u8 *bitmap, const __u64 bit,
const __u8 new_value)
{
__u8 b, old_value;
if (!bitmap || new_value > 1)
return -1;
b = bitmap[bit >> 3];
old_value = (b >> (bit & 7)) & 1;
if (new_value != old_value) {
if (!new_value)
bitmap[bit >> 3] = b & ~(1 << (bit & 7));
else
bitmap[bit >> 3] = b | (1 << (bit & 7));
}
return old_value;
}
--- NEW FILE ---
/*
* bootsect.c - Boot sector handling code. Part of the Linux-NTFS project.
*
* Copyright (c) 2000,2001 Anton Altaparmakov.
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <linux/types.h>
#include "bootsect.h"
#include "endians.h"
int is_boot_sector_ntfs(const NTFS_BOOT_SECTOR *b, const int silent)
{
__u32 i;
if (!silent)
printf("\nBeginning bootsector check...\n");
/* Calculate the checksum. */
if ((void*)b < (void*)&b->checksum) {
__u32 *u = (__u32 *)b;
__u32 *bi = (__u32 *)(&b->checksum);
if (!silent)
printf("Calculating bootsector checksum... ");
for (i = 0; u < bi; ++u)
i += le32_to_cpup(u);
if (le32_to_cpu(b->checksum) && le32_to_cpu(b->checksum) != i)
goto not_ntfs;
if (!silent)
puts("OK");
}
/* Check OEMidentifier is "NTFS " */
if (!silent)
printf("Checking OEMid... ");
if (b->oem_id != cpu_to_le64(0x202020205346544e)) /* "NTFS " */
goto not_ntfs;
if (!silent)
puts("OK");
/* Check bytes per sector value is between 256 and 4096. */
if (!silent)
printf("Checking bytes per sector... ");
if (le16_to_cpu(b->bpb.bytes_per_sector) < 0x100 ||
le16_to_cpu(b->bpb.bytes_per_sector) > 0x1000)
goto not_ntfs;
if (!silent)
puts("OK");
/* Check sectors per cluster value is valid. */
if (!silent)
printf("Checking sectors per cluster... ");
switch (b->bpb.sectors_per_cluster) {
case 1: case 2: case 4: case 8: case 16:
case 32: case 64: case 128:
break;
default:
goto not_ntfs;
}
if (!silent)
puts("OK");
/* Check reserved/unused fields are really zero. */
if (!silent)
printf("Checking reserved fields are zero... ");
if (le16_to_cpu(b->bpb.reserved_sectors) ||
le16_to_cpu(b->bpb.root_entries) ||
le16_to_cpu(b->bpb.sectors) ||
le16_to_cpu(b->bpb.sectors_per_fat) ||
le32_to_cpu(b->bpb.large_sectors) ||
b->bpb.fats)
goto not_ntfs;
if (!silent)
puts("OK");
/* Check clusters per file mft record value is valid. */
if (!silent)
printf("Checking clusters per mft record... ");
if ((__u8)b->clusters_per_mft_record < 0xe1 ||
(__u8)b->clusters_per_mft_record > 0xf7) {
switch (b->clusters_per_mft_record) {
case 1: case 2: case 4: case 8: case 0x10: case 0x20: case 0x40:
break;
default:
goto not_ntfs;
}
}
if (!silent)
puts("OK");
/* Check clusters per index block value is valid. */
if (!silent)
printf("Checking clusters per index block... ");
if ((__u8)b->clusters_per_index_block < 0xe1 ||
(__u8)b->clusters_per_index_block > 0xf7) {
switch (b->clusters_per_index_block) {
case 1: case 2: case 4: case 8: case 0x10: case 0x20: case 0x40:
break;
default:
goto not_ntfs;
}
}
if (!silent)
puts("OK");
if (b->end_of_sector_marker != cpu_to_le16(0xaa55))
fprintf(stderr, "Warning: Bootsector has invalid end of " \
"sector marker.\n");
if (!silent)
puts("Bootsector check completed successfully.");
return 1;
not_ntfs:
if (!silent) {
puts("FAILED");
puts("Bootsector check failed. Aborting...");
}
return 0;
}
--- NEW FILE ---
/*
* mft.c - Mft record handling code. Part of the Linux-NTFS project.
*
* Copyright (c) 2000,2001 Anton Altaparmakov.
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
#include "mft.h"
#include "endians.h"
inline __u32 get_mft_record_data_size(const MFT_RECORD_HEADER *b)
{
if (!b || !is_mft_recordp(b))
return 0;
/* Get the number of used bytes and return it. */
return le32_to_cpu(b->bytes_in_use);
}
--- NEW FILE ---
/*
* ntfs_rec.c - NTFS record handling code. Part of the Linux-NTFS project.
*
* Copyright (c) 2000,2001 Anton Altaparmakov.
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
#include "ntfs_rec.h"
#include "endians.h"
int post_read_mst_fixup(NTFS_RECORD_HEADER *b, const __u32 size)
{
__u16 usa_ofs, usa_count, usn;
__u16 *usa_pos, *data_pos;
/* Setup the variables. */
usa_ofs = le16_to_cpu(b->usa_ofs);
usa_count = le16_to_cpu(b->usa_count);
/* Size and alignement checks. */
if ( size & (NTFS_SECTOR_SIZE - 1) ||
usa_ofs & 1 ||
usa_ofs + (usa_count * 2) > size ||
(size >> NTFS_SECTOR_SIZE_BITS) != usa_count)
return 1;
/* Decrement usa_count to get number of fixups. */
--usa_count;
/* Position of usn in update sequence array. */
usa_pos = (__u16*)b + usa_ofs/sizeof(__u16);
/*
* The update sequence number which has to be equal to each of the
* __u16 values before they are fixed up. Note no need to care for
* endianness since we are comparing and moving data for on disk
* structures which means the data is consistent. - If it is
* consistenty the wrong endianness it doesn't make any difference.
*/
usn = *usa_pos;
/*
* Position in protected data of first __u16 that needs fixing up.
*/
data_pos = (__u16*)b + NTFS_SECTOR_SIZE/sizeof(__u16) - 1;
/* Fixup all sectors. */
while (usa_count--) {
if (*data_pos != usn) {
/*
* Incomplete multi sector transfer detected! )-:
* Set the magic to "BAAD" and return failure.
* Note that magic_BAAD is already converted to le32.
*/
b->magic = magic_BAAD;
return 0;
}
/*
* Increment position in usa and restore original data from
* the usa into the data buffer.
*/
*data_pos = *(++usa_pos);
/* Increment position in data as well. */
data_pos += NTFS_SECTOR_SIZE/sizeof(__u16);
}
return 1;
}
int pre_write_mst_fixup(NTFS_RECORD_HEADER *b, const __u32 size)
{
__u16 usa_ofs, usa_count, usn;
__u16 *usa_pos, *data_pos;
/* Sanity check + only fixup if it makes sense. */
if (!b || is_baad_record(b->magic) || is_hole_record(b->magic))
return 0;
/* Setup the variables. */
usa_ofs = le16_to_cpu(b->usa_ofs);
usa_count = le16_to_cpu(b->usa_count);
/* Size and alignement checks. */
if ( size & (NTFS_SECTOR_SIZE - 1) ||
usa_ofs & 1 ||
usa_ofs + (usa_count * 2) > size ||
(size >> NTFS_SECTOR_SIZE_BITS) != usa_count)
return 0;
/* Decrement usa_count to get number of fixups. */
--usa_count;
/* Position of usn in update sequence array. */
usa_pos = (__u16*)((__u8*)b + usa_ofs);
/*
* Cyclically increment the update sequence number
* (skipping 0 and -1, i.e. 0xffff).
*/
usn = le16_to_cpup(usa_pos) + 1;
if (usn == 0xffff || !usn)
usn = 1;
usn = cpu_to_le16(usn);
*usa_pos = usn;
/* Position in data of first __u16 that needs fixing up. */
data_pos = (__u16*)b + NTFS_SECTOR_SIZE/sizeof(__u16) - 1;
/* Fixup all sectors. */
while (usa_count--) {
/*
* Increment the position in the usa and save the
* original data from the data buffer into the usa.
*/
*(++usa_pos) = *data_pos;
/* Apply fixup to data. */
*data_pos = usn;
/* Increment position in data as well. */
data_pos += NTFS_SECTOR_SIZE/sizeof(__u16);
}
return 1;
}
Index: volume.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/libntfs/volume.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** volume.c 2001/01/25 14:00:43 1.1
--- volume.c 2001/01/25 22:25:43 1.2
***************
*** 40,44 ****
const char *FAILED = "FAILED";
ntfs_volume *vol = NULL;
! BOOT_SECTOR *bs = NULL;
MFT_RECORD_HEADER *mb = NULL;
ATTRIBUTE_RECORD_HEADER *a;
--- 40,44 ----
const char *FAILED = "FAILED";
ntfs_volume *vol = NULL;
! NTFS_BOOT_SECTOR *bs = NULL;
MFT_RECORD_HEADER *mb = NULL;
ATTRIBUTE_RECORD_HEADER *a;
***************
*** 69,73 ****
}
/* Allocate the boot sector structure. */
! if (!(bs = (BOOT_SECTOR *)malloc(sizeof(BOOT_SECTOR)))) {
puts(FAILED);
perror("Error allocating memory for bootsector");
--- 69,73 ----
}
/* Allocate the boot sector structure. */
! if (!(bs = (NTFS_BOOT_SECTOR *)malloc(sizeof(NTFS_BOOT_SECTOR)))) {
puts(FAILED);
perror("Error allocating memory for bootsector");
***************
*** 84,88 ****
}
/* Now read the bootsector. */
! br = ntfs_pread(vol->fd, bs, sizeof(BOOT_SECTOR), 1, 0);
if (br != 1) {
int eo = errno;
--- 84,88 ----
}
/* Now read the bootsector. */
! br = ntfs_pread(vol->fd, bs, sizeof(NTFS_BOOT_SECTOR), 1, 0);
if (br != 1) {
int eo = errno;
|