/*
* wof.h
*
- * Definitions for Windows Overlay File System Filter (WOF) ioctls. See
+ * Definitions for the Windows Overlay File System Filter (WOF) ioctls, as well
+ * some definitions for associated undocumented data structures. See
* http://msdn.microsoft.com/en-us/library/windows/hardware/ff540367(v=vs.85).aspx
- * for more information.
+ * for more information about the documented ioctls.
*
* The author dedicates this file to the public domain.
* You can do whatever you want with this file.
#ifndef _WOF_H_
#define _WOF_H_
-#include "wimlib/types.h"
#include "wimlib/compiler.h"
+#include "wimlib/types.h"
+
+/*
+ * The Windows Overlay FileSystem Filter (WOF, a.k.a. wof.sys) is a filesystem
+ * filter driver, available in Windows 8.1 and later, which allows files to be
+ * "externally backed", meaning that their data is stored in another location,
+ * possibly in compressed form.
+ *
+ * WOF implements a plug-in mechanism by which a specific "provider" is
+ * responsible for actually externally backing a given file. The currently
+ * known providers are:
+ *
+ * - The WIM provider: allows a file to be externally backed by a
+ * compressed resource in a WIM archive
+ * - The file provider: allows a file to be "externally backed" by a named
+ * data stream stored with the file itself, where that named data stream
+ * has the format of a compressed WIM resource
+ *
+ * For both of these providers, externally backed files are effectively
+ * read-only. If you try to write to such a file, Windows automatically
+ * decompresses it and turns it into a regular, non-externally-backed file.
+ *
+ * WOF provides various ioctls that control its operation. For example,
+ * FSCTL_SET_EXTERNAL_BACKING sets up a file as externally backed.
+ *
+ * WOF external backings are implemented using reparse points. One consequence
+ * of this is that WOF external backings can only be set on files that do not
+ * already have a reparse point set. Another consequence of this is that it is
+ * possible to create a WOF external backing by manually creating the reparse
+ * point, although this requires dealing with undocumented data structures and
+ * it only works when the WOF driver is not currently attached to the volume.
+ *
+ * Note that only the unnamed data stream portion of a file can be externally
+ * backed. Other NTFS streams and metadata are not externally backed.
+ */
+
-#define WOF_CURRENT_VERSION 1
-#define WOF_PROVIDER_WIM 1
-#define WIM_PROVIDER_CURRENT_VERSION 1
+/* Current version of the WOF driver/protocol */
+#define WOF_CURRENT_VERSION 1
+
+/* Specifies the WIM backing provider */
+#define WOF_PROVIDER_WIM 1
+
+/* Specifies the "file" backing provider (a.k.a. System Compression) */
+#define WOF_PROVIDER_FILE 2
+
+/* The current version of the WIM backing provider */
+#define WIM_PROVIDER_CURRENT_VERSION 1
+
+/* The current version of the file backing provider */
+#define FILE_PROVIDER_CURRENT_VERSION 1
/* Identifies a backing provider for a specific overlay service version. */
struct wof_external_info {
u32 provider;
};
-/* On Windows, WOF reparse points can only be directly created when the WOF
- * driver is NOT running on the volume. Otherwise, the WOF ioctl
- * (FSCTL_SET_EXTERNAL_BACKING, FSCTL_GET_EXTERNAL_BACKING,
- * FSCTL_DELETE_EXTERNAL_BACKING) must be used instead. */
/*
- * Format of the reparse data of WoF (Windows Overlay File System Filter)
- * reparse points. These include WIMBoot "pointer files".
- *
- * This is not documented by Microsoft!!!
- *
- * Notes:
- * - 'struct wim_provider_rpdata' must be preceded by
- * 'struct wof_external_info'.
- * - Reparse tag is 0x80000017
- * - Don't make these if the file has no unnamed data stream, has an empty
- * unnamed data stream, or already is a reparse point.
- * - There is nowhere to put named data streams. They have to copied
- * literally to the reparse point file.
+ * Format of the WIM provider reparse data. This is the data which follows the
+ * portion of the reparse point common to WOF. (The common portion consists of
+ * a reparse point header where the reparse tag is 0x80000017, then a 'struct
+ * wof_external_info' which specifies the provider.)
+ *
+ * Note that Microsoft does not document any of the reparse point formats for
+ * WOF, although they document the structures which must be passed into the
+ * ioctls, which are often similar.
*/
struct wim_provider_rpdata {
/* Set to 2. Uncertain meaning. */
/* Integer ID that identifies the WIM. */
le64 data_source_id;
- /* SHA1 message digest of the file's unnamed data stream. */
- u8 resource_hash[20];
+ /* SHA-1 message digest of the file's unnamed data stream. */
+ u8 unnamed_data_stream_hash[20];
- /* SHA1 message digest of the WIM's lookup table. */
- u8 wim_lookup_table_hash[20];
+ /* SHA-1 message digest of the WIM's blob table as stored on disk. */
+ u8 blob_table_hash[20];
/* Uncompressed size of the file's unnamed data stream, in bytes. */
- le64 stream_uncompressed_size;
+ le64 unnamed_data_stream_size;
- /* Compressed size of the file's unnamed data stream, in bytes. If
- * stream is stored uncompressed, set this the same as the uncompressed
- * size. */
- le64 stream_compressed_size;
+ /* Size of the file's unnamed data stream as stored in the WIM file.
+ * If this is the same as unnamed_data_stream_size, then the stream is
+ * uncompressed. If this is the *not* the same as
+ * unnamed_data_stream_size, then the stream is compressed. */
+ le64 unnamed_data_stream_size_in_wim;
/* Byte offset of the file's unnamed data stream in the WIM. */
- le64 stream_offset_in_wim;
+ le64 unnamed_data_stream_offset_in_wim;
} _packed_attribute;
/* WIM-specific information about a WIM data source */
le32 wim_type;
/* Index of the image in the WIM to use??? (This doesn't really make
- * sense, since WIM files combine streams for all images into a single
- * table. Set to 1 if unsure...) */
+ * sense, since WIM files combine file data "blobs" for all images into
+ * a single table. Set to 1 if unsure...) */
le32 wim_index;
/* GUID of the WIM file (copied from the WIM header, offset +0x18). */
static inline void
wof_check_structs(void)
{
- BUILD_BUG_ON(sizeof(struct WimOverlay_dat_header) != 24);
- BUILD_BUG_ON(sizeof(struct WimOverlay_dat_entry_1) != 40);
- BUILD_BUG_ON(sizeof(struct WimOverlay_dat_entry_2) != 104);
+ STATIC_ASSERT(sizeof(struct WimOverlay_dat_header) == 24);
+ STATIC_ASSERT(sizeof(struct WimOverlay_dat_entry_1) == 40);
+ STATIC_ASSERT(sizeof(struct WimOverlay_dat_entry_2) == 104);
}
/*****************************************************************************
* FSCTL_ADD_OVERLAY ioctl. */
u64 data_source_id;
- /* SHA1 message digest of the file's unnamed data stream. */
- u8 resource_hash[20];
+ /* SHA-1 message digest of the file's unnamed data stream. */
+ u8 unnamed_data_stream_hash[20];
+};
+
+struct file_provider_external_info {
+
+ /* Set to FILE_PROVIDER_CURRENT_VERSION. */
+ u32 version;
+
+ u32 compression_format;
+#define FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS4K 0
+#define FILE_PROVIDER_COMPRESSION_FORMAT_LZX 1
+#define FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS8K 2
+#define FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS16K 3
};
/*****************************************************************************
struct wim_provider_overlay_entry {
/* Byte offset of the next entry from the beginning of this structure,
* or 0 if there are no more entries. */
- uint32_t next_entry_offset;
+ u32 next_entry_offset;
- uint32_t padding;
+ u32 padding;
/* Identifier for the WIM file. */
- uint64_t data_source_id;
+ u64 data_source_id;
/* GUID of the WIM file. */
- uint8_t guid[16];
+ u8 guid[16];
/* Byte offset of the WIM's file name from the beginning of this
* structure. */
- uint32_t wim_file_name_offset;
+ u32 wim_file_name_offset;
/* Type of WIM file: WIM_BOOT_OS_WIM or WIM_BOOT_NOT_OS_WIM. */
- uint32_t wim_type;
+ u32 wim_type;
- /* Index of the backing image in the WIM??? (This doesn't really make
- * sense, since WIM files combine streams for all images into a single
- * table.) */
- uint32_t wim_index;
+ /* Index of the image in the WIM to use??? (This doesn't really make
+ * sense, since WIM files combine file data "blobs" for all images into
+ * a single table. Set to 1 if unsure...) */
+ u32 wim_index;
/* 0 when WIM provider active, otherwise
* WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
* WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED. */
- uint32_t flags;
+ u32 flags;
/* Full path to the WIM in the NT device namespace, e.g.
* "\Device\HardDiskVolume2\test.wim". Seems to be null-terminated,
#define WIM_BOOT_NOT_OS_WIM 1
/* Index of the image in the WIM to use??? (This doesn't really make
- * sense, since WIM files combine streams for all images into a single
- * table. Set to 1 if unsure...) */
+ * sense, since WIM files combine file data "blobs" for all images into
+ * a single table. Set to 1 if unsure...) */
u32 wim_index;
/* Byte offset of wim_file_name in this buffer, not including the