Import Upstream version 0.7

parent 3d7ab613
......@@ -38,4 +38,5 @@ Config.in
core
.gdb_history
.gdbinit
*.hiv
CC=gcc
CFLAGS=-O3
CFLAGS=-O2 -g
#CFLAGS=-O2 -flto -ffunction-sections -fdata-sections -fno-unwind-tables -fno-asynchronous-unwind-tables
#CFLAGS=-Og -g3
BUILD_CFLAGS=-std=gnu99 -I. -D_FILE_OFFSET_BITS=64 -pipe -Wall -pedantic
LDFLAGS=-s
BUILD_CFLAGS = -std=gnu99 -I. -D_FILE_OFFSET_BITS=64 -pipe -fstrict-aliasing
#BUILD_CFLAGS += -Wall -Wextra -Wstrict-aliasing -Wcast-align -pedantic -Wno-unused-parameter
BUILD_CFLAGS += -Wall -Wextra -Wwrite-strings -Wcast-align -Wstrict-aliasing -pedantic -Wstrict-overflow -Wstrict-prototypes -Wpointer-arith -Wundef
BUILD_CFLAGS += -Wshadow -Wfloat-equal -Wstrict-overflow=5 -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wunreachable-code -Wformat=2 -Winit-self
#LDFLAGS=-s
#LDFLAGS=-flto -s -Wl,--gc-sections
#LDFLAGS=
LDFLAGS=
FUSE_CFLAGS=$(shell pkg-config fuse --cflags)
FUSE_LDFLAGS=$(shell pkg-config fuse --libs)
FUSE_LIBS=-lfuse
......@@ -18,13 +21,19 @@ datarootdir=${prefix}/share
datadir=${datarootdir}
sysconfdir=${prefix}/etc
OBJS_LIB=ntreg.o jody_string.o
OBJS_FSCK=fsck_winregfs.o $(OBJS_LIB)
OBJS_MOUNT=winregfs.o jody_hash.o $(OBJS_LIB)
BUILD_CFLAGS += $(CFLAGS_EXTRA)
all: mount.winregfs fsck.winregfs manual
mount.winregfs: winregfs.o ntreg.o jody_hash.o
$(CC) $(CFLAGS) $(LDFLAGS) $(FUSE_CFLAGS) $(BUILD_CFLAGS) $(FUSE_LDFLAGS) -o mount.winregfs winregfs.o ntreg.o jody_hash.o $(FUSE_LIBS)
mount.winregfs: $(OBJS_MOUNT)
$(CC) $(CFLAGS) $(LDFLAGS) $(FUSE_CFLAGS) $(BUILD_CFLAGS) $(FUSE_LDFLAGS) -o mount.winregfs $(OBJS_MOUNT) $(FUSE_LIBS)
fsck.winregfs: fsck_winregfs.o ntreg.o
$(CC) $(CFLAGS) $(LDFLAGS) $(FUSE_CFLAGS) $(BUILD_CFLAGS) $(FUSE_LDFLAGS) -o fsck.winregfs fsck_winregfs.o ntreg.o
fsck.winregfs: $(OBJS_FSCK)
$(CC) $(CFLAGS) $(LDFLAGS) $(FUSE_CFLAGS) $(BUILD_CFLAGS) $(FUSE_LDFLAGS) -o fsck.winregfs $(OBJS_FSCK)
manual:
gzip -9 < mount.winregfs.8 > mount.winregfs.8.gz
......
Windows Registry FUSE Filesystem TODO list
------------------------------------------
* Fix 8 KiB file write limit issue (may really be in ntreg.c)
For now an error is issued on attempts to write >8192 bytes
since there are extremely few values that contain this much
data; the XP compatibility shim cache is pretty much the
only value of such a size (all others are <6000 bytes)
* Allow arbitrary value types using a hexadecimal extension
(used in SAM and some MS Click-to-Run registry keys)
* Unicode and non-ASCII character support
This is not only useful for non-Latin characters, it also
can be used to find novel registry-resident malware such as
Poweliks, which uses a non-ASCII name to block the Windows
registry editor from being able to touch it.
#!/bin/sh
# Jody's generic chroot build script
# Version 1.0
ARCHES="i386 x86-64 uclibc-i386 uclibc-x86-64"
test -z "$NAME" && NAME="$(basename "$(pwd)")"
test -e "version.h" && VER="$(grep '#define VER ' version.h | tr -d \\\" | cut -d' ' -f3)"
......@@ -51,12 +54,12 @@ if [ "$DO_CHROOT_BUILD" = "1" ]
else
echo baz
export DO_CHROOT_BUILD=1
for X in $ARCHES
for ARCH in $ARCHES
do
export ARCH
export CHROOT="$CHROOT_BASE/$ARCH"
test ! -d $CHROOT && echo "$CHROOT not present, not building $ARCH package." && continue
echo "Performing package build for $CHROOT"
export CHROOT="$CHROOT_BASE/$X"
export ARCH="$X"
test ! -d $CHROOT && echo "$CHROOT not present, not building $CHROOT_ARCH package." && exit 1
test ! -x $CHROOT/bin/sh && echo "$CHROOT does not seem to be a chroot; aborting." && exit 1
mount --bind /dev $CHROOT/dev || clean_exit
mount --bind /usr/src $CHROOT/usr/src || clean_exit
......@@ -64,7 +67,7 @@ if [ "$DO_CHROOT_BUILD" = "1" ]
mount -t proc proc $CHROOT/proc || clean_exit
mount -t sysfs sysfs $CHROOT/sys || clean_exit
mount -t tmpfs tmpfs $CHROOT/tmp || clean_exit
if echo "$CHROOT_ARCH" | grep -q "i386"
if echo "$ARCH" | grep -q "i386"
then linux32 chroot $CHROOT $WD/$0 $WD
else chroot $CHROOT $WD/$0 $WD
fi
......
#ifndef CONFIG_H
#define CONFIG_H
/* Threaded mode suffers from decreased performance */
#define ENABLE_THREADED 0
#define ENABLE_LOGGING 0
#define ENABLE_DEBUG_LOGGING 0
#define ENABLE_DEBUG_PRINTF 1
#define ENABLE_DEBUG_PRINTF 0
#define ENABLE_NKOFS_CACHE 1
#define ENABLE_NKOFS_CACHE_STATS 0
#define CACHE_ITEMS 64
#define NKOFS_CACHE_ITEMS 64
#endif /* CONFIG_H */
.\" Copyright (c) 2014 Jody Bruchon
.\" Copyright (c) 2014-2017 Jody Bruchon
.\" Licensed under the GNU General Public License v2
.\"
.TH winregfs 8 "20 May 2014" "fsck.winregfs"
......
/*
* Windows registry "filesystem checker"
* Reads all the keys in a hive and reports any errors triggered
*
* Copyright (C) 2014, 2015 by Jody Bruchon <jody@jodybruchon.com>
* Copyright (C) 2014-2017 by Jody Bruchon <jody@jodybruchon.com>
*
* Licensed under GNU GPL v2. See LICENSE and README for details.
*
*/
#define _FSCK_
#define FSCK_WINREGFS
#include <stdio.h>
#include <stdlib.h>
......@@ -20,6 +21,7 @@
#include <fcntl.h>
#include <libgen.h>
#include "ntreg.h"
#include "jody_string.h"
#include "winregfs.h"
#define UPDATE_INTERVAL 300
......@@ -38,7 +40,7 @@ struct fsck_stat {
int update_delay;
};
void invalidate_cache(void) {
void invalidate_nk_cache(void) {
return;
}
......@@ -107,7 +109,6 @@ static int process_key(struct fsck_stat * const restrict stats,
strncpy(filename, keypath, ABSPATHLEN);
if(strncmp(keypath, "\\", 3)) strncat(filename, "\\", ABSPATHLEN);
strncat(filename, ex.name, ABSPATHLEN);
free(ex.name);
error_count += process_key(stats, filename, depth, verbose);
}
if (i < 0) {
......@@ -130,7 +131,6 @@ static int process_key(struct fsck_stat * const restrict stats,
strncat(filename, "\\", ABSPATHLEN);
if (strlen(vex.name) == 0) strncpy(filename, "@", 2);
else strncat(filename, vex.name, ABSPATHLEN);
free(vex.name);
}
if (i < 0) {
if (verbose) printf("\rValue read failure: %s\n", keypath);
......@@ -150,7 +150,7 @@ int main(int argc, char *argv[])
int error_count, warn_count, verbose = 0;
struct fsck_stat stats;
if (argc == 2 && !strncasecmp(argv[1], "-v", 2)) {
if (argc == 2 && !strcaseeq(argv[1], "-v")) {
fprintf(stderr, "Windows Registry Hive File Checker %s (%s)\n", VER, VERDATE);
return EXIT_SUCCESS;
}
......
/*
* Jody Bruchon's fast hashing function
/* Jody Bruchon's fast hashing function
*
* This function was written to generate a fast hash that also has a
* fairly low collision rate. The collision rate is much higher than
* a secure hash algorithm, but the calculation is drastically simpler
* and faster.
*
* Copyright (C) 2014-2015 by Jody Bruchon <jody@jodybruchon.com>
* Released under the terms of the GNU GPL version 2
*
* Copyright (C) 2014-2017 by Jody Bruchon <jody@jodybruchon.com>
* Released under The MIT License
*/
#include <stdio.h>
#include <stdlib.h>
#include "jody_hash.h"
/* DO NOT modify the shift unless you know what you're doing.
* This shift was decided upon after lots of testing and
* changing it will likely cause lots of hash collisions. */
#ifndef JODY_HASH_SHIFT
#define JODY_HASH_SHIFT 11
#endif
/* The salt value's purpose is to cause each byte in the
* hash_t word to have a positionally dependent variation.
* It is injected into the calculation to prevent a string of
* identical bytes from easily producing an identical hash. */
/* The tail mask table is used for block sizes that are
* indivisible by the width of a hash_t. It is ANDed with the
* final hash_t-sized element to zero out data in the buffer
* that is not part of the data to be hashed. */
/* Set hash parameters based on requested hash width */
#if JODY_HASH_WIDTH == 64
#define JODY_HASH_CONSTANT 0x1f3d5b79U
static const hash_t tail_mask[] = {
0x0000000000000000,
0x00000000000000ff,
0x000000000000ffff,
0x0000000000ffffff,
0x00000000ffffffff,
0x000000ffffffffff,
0x0000ffffffffffff,
0x00ffffffffffffff,
0xffffffffffffffff
};
#endif /* JODY_HASH_WIDTH == 64 */
#if JODY_HASH_WIDTH == 32
#define JODY_HASH_CONSTANT 0x1f3d5b79U
static const hash_t tail_mask[] = {
0x00000000,
0x000000ff,
0x0000ffff,
0x00ffffff,
0xffffffff,
};
#endif /* JODY_HASH_WIDTH == 32 */
#if JODY_HASH_WIDTH == 16
#define JODY_HASH_CONSTANT 0x1f5bU
static const hash_t tail_mask[] = {
0x0000,
0x00ff,
0xffff,
};
#endif /* JODY_HASH_WIDTH == 16 */
/* Hash a block of arbitrary size; must be divisible by sizeof(hash_t)
* The first block should pass a start_hash of zero.
* All blocks after the first should pass start_hash as the value
......@@ -22,67 +72,42 @@
* of any amount of data. If data is not divisible by the size of
* hash_t, it is MANDATORY that the caller provide a data buffer
* which is divisible by sizeof(hash_t). */
extern hash_t jody_block_hash(const hash_t * data,
const hash_t start_hash, const unsigned int count)
extern hash_t jody_block_hash(const hash_t * restrict data,
const hash_t start_hash, const size_t count)
{
register hash_t hash = start_hash;
unsigned int len;
hash_t tail;
hash_t hash = start_hash;
hash_t element;
hash_t partial_salt;
size_t len;
#ifdef ARCH_HAS_LITTLE_ENDIAN
/* Little-endian 64-bit hash_t tail mask */
const hash_t le64_tail_mask[] = {
0x0000000000000000,
0xff00000000000000,
0xffff000000000000,
0xffffff0000000000,
0xffffffff00000000,
0xffffffffff000000,
0xffffffffffff0000,
0xffffffffffffff00,
0xffffffffffffffff,
};
#define TAIL_MASK le64_tail_mask
#else
/* Big-endian 64-bit hash_t tail mask */
const hash_t be64_tail_mask[] = {
0x0000000000000000,
0x00000000000000ff,
0x000000000000ffff,
0x0000000000ffffff,
0x00000000ffffffff,
0x000000ffffffffff,
0x0000ffffffffffff,
0x00ffffffffffffff,
0xffffffffffffffff,
};
#define TAIL_MASK be64_tail_mask
#endif /* ARCH_HAS_LITTLE_ENDIAN */
/* Don't bother trying to hash a zero-length block */
if (count == 0) return hash;
len = count / sizeof(hash_t);
for (; len > 0; len--) {
hash += *data;
element = *data;
hash += element;
hash += JODY_HASH_CONSTANT;
hash = (hash << JODY_HASH_SHIFT) | hash >> (sizeof(hash_t) * 8 - JODY_HASH_SHIFT);
hash += (*data & (hash_t)0x000000ff);
hash ^= (*data);
hash += (*data & (hash_t)0xffffff00);
hash ^= element;
hash = (hash << JODY_HASH_SHIFT) | hash >> (sizeof(hash_t) * 8 - JODY_HASH_SHIFT);
hash += *data;
hash ^= JODY_HASH_CONSTANT;
hash += element;
data++;
}
/* Handle data tail (for blocks indivisible by sizeof(hash_t)) */
len = count & (sizeof(hash_t) - 1);
if (len) {
tail = *data;
tail &= TAIL_MASK[len];
hash += tail;
partial_salt = JODY_HASH_CONSTANT & tail_mask[len];
element = *data & tail_mask[len];
hash += element;
hash += partial_salt;
hash = (hash << JODY_HASH_SHIFT) | hash >> (sizeof(hash_t) * 8 - JODY_HASH_SHIFT);
hash += (tail & (hash_t)0x000000ff);
hash ^= (tail);
hash += (tail & (hash_t)0xffffff00);
hash ^= element;
hash = (hash << JODY_HASH_SHIFT) | hash >> (sizeof(hash_t) * 8 - JODY_HASH_SHIFT);
hash += tail;
hash ^= partial_salt;
hash += element;
}
return hash;
......
/* Jody Bruchon's fast hashing function (headers)
*
* Copyright (C) 2014-2015 by Jody Bruchon <jody@jodybruchon.com>
* See jody_hash.c for more information.
*/
* See jody_hash.c for license information */
#ifndef _JODY_HASH_H
#define _JODY_HASH_H
#ifndef JODY_HASH_H
#define JODY_HASH_H
#ifdef __cplusplus
extern "C" {
#endif
/* Required for uint64_t */
#include <stdint.h>
/* Width of a jody_hash. Changing this will also require
* changing the width of tail masks and endian conversion */
#ifndef JODY_HASH_WIDTH
#define JODY_HASH_WIDTH 64
#endif
#if JODY_HASH_WIDTH == 64
typedef uint64_t hash_t;
#define JODY_HASH_SHIFT 11
#endif
#if JODY_HASH_WIDTH == 32
typedef uint32_t hash_t;
#endif
#if JODY_HASH_WIDTH == 16
typedef uint16_t hash_t;
#endif
/* Version increments when algorithm changes incompatibly */
#define JODY_HASH_VERSION 4
extern hash_t jody_block_hash(const hash_t * restrict data,
const hash_t start_hash, const size_t count);
extern hash_t jody_block_hash(const hash_t * const,
const hash_t, const unsigned int);
#ifdef __cplusplus
}
#endif
#endif /* _JODY_HASH_H */
#endif /* JODY_HASH_H */
/*
* Jody Bruchon's string function library <jody@jodybruchon.com>
* Copyright (C) 2015-2017
* Distributed under the GNU General Public License version 2
*/
#include <stdint.h>
#include <unistd.h>
/* Like strncasecmp() but only tests for equality */
extern int strncaseeq(const char *s1, const char *s2, size_t len)
{
size_t i = 0;
while (i < len) {
if (*s1 != *s2) {
unsigned char c1, c2;
c1 = *(const unsigned char *)s1;
c2 = *(const unsigned char *)s2;
/* Transform upper case to lower case */
if (c1 == 0 || c2 == 0) return 1;
if (c1 >= 'A' && c1 <= 'Z') c1 |= 0x20;
if (c2 >= 'A' && c2 <= 'Z') c2 |= 0x20;
if (c1 != c2) return 1;
} else {
if (*s1 == 0) return 0;
}
s1++; s2++;
i++;
}
return 0;
}
/* Like strcasecmp() but only tests for equality */
extern int strcaseeq(const char *s1, const char *s2)
{
while (1) {
if (*s1 != *s2) {
unsigned char c1, c2;
c1 = *(const unsigned char *)s1;
c2 = *(const unsigned char *)s2;
/* Transform upper case to lower case */
if (c1 == 0 || c2 == 0) return 1;
if (c1 >= 'A' && c1 <= 'Z') c1 |= 0x20;
if (c2 >= 'A' && c2 <= 'Z') c2 |= 0x20;
if (c1 != c2) return 1;
} else {
if (*s1 == 0) return 0;
}
s1++; s2++;
}
return 1;
}
/* Like strncmp() but only tests for equality */
extern int strneq(const char *s1, const char *s2, size_t len)
{
size_t i = 0;
if (!len) return 0;
while (*s1 != '\0' && *s2 != '\0') {
if (*s1 != *s2) return 1;
s1++; s2++; i++;
if (i == len) return 0;
}
if (*s1 != *s2) return 1;
return 0;
}
/* Like strcmp() but only tests for equality */
extern int streq(const char *s1, const char *s2)
{
while (*s1 != '\0' && *s2 != '\0') {
if (*s1 != *s2) return 1;
s1++; s2++;
}
if (*s1 != *s2) return 1;
return 0;
}
/*
* Jody Bruchon's string function library <jody@jodybruchon.com>
* Copyright (C) 2015-2017
* Distributed under the GNU General Public License version 2
*/
#ifndef JODY_STRING_H
#define JODY_STRING_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <unistd.h>
extern int strncaseeq(const char *s1, const char *s2, size_t len);
extern int strcaseeq(const char *s1, const char *s2);
extern int strneq(const char *s1, const char *s2, size_t len);
extern int streq(const char *s1, const char *s2);
/* Inline strcpy() */
inline void xstrcpy(char * restrict dest, const char * restrict src)
{
while (*src != '\0') {
*dest = *src;
dest++; src++;
}
*dest = '\0';
}
#ifdef __cplusplus
}
#endif
#endif /* JODY_STRING_H */
.\" Copyright (c) 2014 Jody Bruchon
.\" Copyright (c) 2014-2017 Jody Bruchon
.\" Licensed under the GNU General Public License v2
.\"
.TH winregfs 8 "1 May 2014" "mount.winregfs"
.TH winregfs 8 "10 Mar 2017" "mount.winregfs"
.SH NAME
winregfs \- Windows registry FUSE filesystem
.SH SYNOPSIS
......@@ -13,11 +13,37 @@ winregfs \- Windows registry FUSE filesystem
Windows registry hive files as ordinary filesystems. Registry hive file
editing can be performed with ordinary shell scripts and command-line tools
once mounted.
Registry values are shown as files with a file extension corresponding to
the data type of the value. These are generally named after the REG_* types
seen in the Windows registry editor. For example, \fBdw\fP is a DWORD,
\fBsz\fP is a string, \fBesz\fP is an expanding string, \fBbin\fP is a raw
binary value, and \fBmsz\fP is a multi-line string. Types different from
the "standard" types may appear in rare instances.
Because registry keys and values can have forward slashes in their names,
there is a special word \fB_SLASH_\fP that is used in place of any real
slashes and is converted back-and-forth automatically.
Opening a value's name without the extension is supported, but you should
always use the extension if possible to avoid ambiguity issues.
.SH KNOWN ISSUES
\fBwinregfs\fP does not currently support writing value data greater than
8,192 bytes (8 KiB) in size. If such a write occurs, the data will be
truncated and an error will be returned. Unicode data is not currently
supported, partly due to a lack of support in the ntreg library.
Incorrect or unrecognized structures in a registry file may cause this
program to crash. It is not recommended for use on important data and
while most operations generally work as expected, you use it at your own
risk. Please report any bugs you encounter.
\fBwinregfs\fP loads the entire hive file into one large chunk of memory.
This is a side effect of adopting the low-level registry library from the
program \fBchntpw\fP. There is a silent delay as the hive is loaded and
if the file is large enough there is a chance of failure due to being
unable to allocate enough contiguous memory. Changing this behavior is a
very difficult task due to how the ntreg library works with the data.
.SH SEE ALSO
.BR fusermount (8),
.BR fsck.winregfs (8)
This diff is collapsed.
......@@ -20,22 +20,23 @@
* See file LGPL.txt for the full license.
*
* Modified for Windows Registry FUSE filesystem project "winregfs"
* by Jody Bruchon <jody@jodybruchon.com> on 2014-04-16
* by Jody Bruchon <jody@jodybruchon.com> since 2014-04-16
*
*/
#ifndef _NTREG_H
#define _NTREG_H
#ifndef NTREG_H
#define NTREG_H
#define SZ_MAX 4096 /* Max unicode strlen before we truncate */
#ifdef __cplusplus
extern "C" {
#endif
#define KEY_ROOT 0x2c /* Type ID of ROOT key node */
#define KEY_NORMAL 0x20 /* Normal nk key */
#define ABSPATHLEN 4096
/* hbin page size. hbins are minimum this, and always multiple of this */
#define HBIN_PAGESIZE 0x1000
/* Hive filesize seems to always be multiple of this */
......@@ -228,7 +229,7 @@ struct vk_key {
/* Offset Size Contents */
int16_t id; /* 0x0000 Word ID: ASCII-"vk" = 0x6B76 */
int16_t len_name; /* 0x0002 Word name length */
int32_t len_data; /* 0x0004 D-Word length of the data */
uint32_t len_data; /* 0x0004 D-Word length of the data */
int32_t ofs_data; /* 0x0008 D-Word Offset of Data */
int32_t val_type; /* 0x000C D-Word Type of value */
int16_t flag; /* 0x0010 Word Flag
......@@ -279,7 +280,7 @@ struct nk_key {
struct ex_data {
int nkoffs;
struct nk_key *nk;
char *name;
char name[ABSPATHLEN];
};
struct vex_data {
......@@ -288,7 +289,7 @@ struct vex_data {
int type; /* Value type REG_??? */
int size; /* Values size (normalized, inline accounted for) */
int32_t val; /* Actual value itself if type==REG_DWORD */
char *name;
char name[ABSPATHLEN];
};
struct keyval {
......@@ -325,7 +326,7 @@ struct keyval {
/* Maximum number of dirty pages before forced commit */
#define MAX_DIRTY 16
#define MAX_DIRTY 32
/* Hive definition, allocated by open_hive(), dealloc by close_hive()
* contains state data, must be passed in all functions
......@@ -339,10 +340,10 @@ struct hive {
int unuseblk; /* Total # of unused blocks */
int usetot; /* total # of bytes in useblk */
int unusetot; /* total # of bytes in unuseblk */
int size; /* Hives size (filesize) in bytes, incl regf header */
off_t size; /* Hives size (filesize) in bytes, incl regf header */
int rootofs; /* Offset of root-node */
int lastbin; /* Offset to last HBIN */
int endofs; /* Offset of first non HBIN page, we can expand from here */
unsigned int endofs; /* Offset of first non HBIN page, we can expand from here */
int dirty[MAX_DIRTY];/* Dirty page list */
int dirty_entries; /* Number of dirty pages */
int16_t nkindextype; /* Subkey-indextype the root key uses */
......@@ -368,11 +369,14 @@ struct hive {
/******* Function prototypes **********/
void cheap_uni2ascii(char *src, char *dest, int l);
void cheap_ascii2uni(char *src, char *dest, int l);
void cheap_uni2ascii(const char *src, char *dest, int l);
void cheap_ascii2uni(const char *src, char *dest, int l);
int flush_dirty_pages(struct hive *hdesc);
int parse_block(struct hive *hdesc, int vofs);
int ex_next_n(struct hive *hdesc, int nkofs, int *count, int *countri, struct ex_data *sptr);
int ex_next_n(const struct hive * const hdesc, int nkofs, int * const restrict count,
int * const restrict countri, struct ex_data * const restrict sptr);
int ex_next_v(struct hive *hdesc, int nkofs, int *count, struct vex_data *sptr);
int get_abs_path(struct hive *hdesc, int nkofs, char *path, int maxlen);
int trav_path(struct hive *hdesc, int vofs, const char * restrict path, int type);
......@@ -399,8 +403,10 @@ int del_key(struct hive *hdesc, int nkofs, char *name);
int add_bin(struct hive *hdesc, int size);
int de_escape(char *s, int wide);
char *string_regw2prog(void *string, int len);
void string_regw2prog(char * const restrict cstring, const void * const restrict string, int len);
#ifdef __cplusplus
}
#endif
#endif /* NTREG_H */
/*
* Windows Registry FUSE Filesystem
*
* Written by Jody Bruchon <jody@jodybruchon.com> 2014-04-20
*
* Licensed under GNU GPL v2. See LICENSE and README for details.
* Version number definitions
*
*/
#ifndef __WINREGFS_VERSION_H__
#define VER "0.6"
#define VERDATE "2015-02-10"
#endif
#ifndef WINREGFS_VERSION_H
#define WINREGFS_VERSION_H
#define VER "0.7"
#define VERDATE "2017-03-10"
#endif /* WINREGFS_VERSION_H */
This diff is collapsed.
/*
* Windows Registry FUSE Filesystem
*
* Copyright (C) 2014, 2015 by Jody Bruchon <jody@jodybruchon.com>
* Copyright (C) 2014-2017 by Jody Bruchon <jody@jodybruchon.com>
*
* Licensed under GNU GPL v2. See LICENSE and README for details.
*
*/
#ifndef _WINREGFS_H
#define _WINREGFS_H
#ifndef WINREGFS_H
#define WINREGFS_H
#include "version.h"
#ifndef _FSCK_
#ifndef FSCK_WINREGFS
#define FUSE_USE_VERSION 26
#include <fuse.h>
#endif
......@@ -36,11 +36,11 @@
# endif
#endif
#if ENABLE_NKOFS_CACHE
# if !CACHE_ITEMS
# error ENABLE_NKOFS_CACHE enabled; CACHE_ITEMS must be set and non-zero
# if !NKOFS_CACHE_ITEMS
# error ENABLE_NKOFS_CACHE enabled; NKOFS_CACHE_ITEMS must be set and non-zero
# endif
#endif
#ifdef _FSCK_
#ifdef FSCK_WINREGFS
#undef ENABLE_LOGGING
#define ENABLE_LOGGING 0
#undef ENABLE_THREADED
......@@ -55,7 +55,7 @@
#define HASH_MISS 3
#define HASH_FAIL 4
#else
#define cache_stats(a,b)
#define nk_cache_stats(a,b)
#endif /* NKOFS_CACHE_STATS */
/* Data structures */
......@@ -67,19 +67,19 @@ struct winregfs_data {
FILE *log;
#endif
#if ENABLE_NKOFS_CACHE
/* Cache previous nkofs/path/key sets up to CACHE_ITEMS */
int cache_pos;
char *last_path[CACHE_ITEMS];
int last_nkofs[CACHE_ITEMS];
struct nk_key *last_key[CACHE_ITEMS];
hash_t hash[CACHE_ITEMS];
/* Cache previous nkofs/path/key sets up to NKOFS_CACHE_ITEMS */
int nk_cache_pos;
char *nk_last_path[NKOFS_CACHE_ITEMS];
int nk_last_nkofs[NKOFS_CACHE_ITEMS];
struct nk_key *nk_last_key[NKOFS_CACHE_ITEMS];
hash_t nk_hash[NKOFS_CACHE_ITEMS];
# if ENABLE_NKOFS_CACHE_STATS
int delay; /* Cache log throttling interval */
int cache_miss;
int cache_hit;
int hash_miss;