4 * Definitions for the Windows Overlay Filesystem filter (WOF) ioctls, as well
5 * some definitions for associated undocumented data structures.
7 * The following copying information applies to this specific source code file:
9 * Written in 2014-2021 by Eric Biggers <ebiggers3@gmail.com>
11 * To the extent possible under law, the author(s) have dedicated all copyright
12 * and related and neighboring rights to this software to the public domain
13 * worldwide via the Creative Commons Zero 1.0 Universal Public Domain
14 * Dedication (the "CC0").
16 * This software is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 * FOR A PARTICULAR PURPOSE. See the CC0 for more details.
20 * You should have received a copy of the CC0 along with this software; if not
21 * see <http://creativecommons.org/publicdomain/zero/1.0/>.
27 #include "wimlib/compiler.h"
28 #include "wimlib/types.h"
31 * The Windows Overlay Filesystem filter (WOF, a.k.a. wof.sys) is a filesystem
32 * filter driver, available in Windows 8.1 and later, which allows files to be
33 * "externally backed", meaning that their data is stored in another location,
34 * possibly in compressed form.
36 * WOF implements a plug-in mechanism by which a specific "provider" is
37 * responsible for actually externally backing a given file. The currently
38 * known providers are:
40 * - The WIM provider: allows a file to be externally backed by a
41 * compressed resource in a WIM archive
42 * - The file provider: allows a file to be "externally backed" by a named
43 * data stream stored with the file itself, where that named data stream
44 * has the format of a compressed WIM resource
46 * For both of these providers, externally backed files are effectively
47 * read-only. If you try to write to such a file, Windows automatically
48 * decompresses it and turns it into a regular, non-externally-backed file.
50 * WOF provides various ioctls that control its operation. For example,
51 * FSCTL_SET_EXTERNAL_BACKING sets up a file as externally backed.
53 * WOF external backings are implemented using reparse points. One consequence
54 * of this is that WOF external backings can only be set on files that do not
55 * already have a reparse point set. Another consequence of this is that it is
56 * possible to create a WOF external backing by manually creating the reparse
57 * point, although this requires dealing with undocumented data structures and
58 * it only works when the WOF driver is not currently attached to the volume.
60 * Note that only the unnamed data stream portion of a file can be externally
61 * backed. Other NTFS streams and metadata are not externally backed.
65 /*----------------------------------------------------------------------------*
66 * WOF ioctl definitions *
67 *----------------------------------------------------------------------------*/
69 #ifndef WOF_CURRENT_VERSION
70 /* Identifies a file backing provider and the overlay service version it supports.
71 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_wof_external_info */
72 typedef struct _WOF_EXTERNAL_INFO {
73 #define WOF_CURRENT_VERSION 1
76 } WOF_EXTERNAL_INFO, *PWOF_EXTERNAL_INFO;
77 #endif /* WOF_CURRENT_VERSION */
79 /* WIM provider ("WIMBoot") */
80 #ifndef WOF_PROVIDER_WIM
81 #define WOF_PROVIDER_WIM 1
83 * The identifier and status information for the Windows Image File (WIM)
84 * external backing provider.
85 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_wim_provider_external_info
87 typedef struct _WIM_PROVIDER_EXTERNAL_INFO {
88 #define WIM_PROVIDER_CURRENT_VERSION 1
91 LARGE_INTEGER DataSourceId;
92 #define WIM_PROVIDER_HASH_SIZE 20
93 UCHAR ResourceHash[WIM_PROVIDER_HASH_SIZE];
94 } WIM_PROVIDER_EXTERNAL_INFO, *PWIM_PROVIDER_EXTERNAL_INFO;
95 #endif /* WOF_PROVIDER_WIM */
97 /* File provider ("system compression") */
98 #ifndef WOF_PROVIDER_FILE
99 #define WOF_PROVIDER_FILE 2
100 /* Defines metadata specific to files provided by WOF_PROVIDER_FILE.
101 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_provider_external_info_v1 */
102 typedef struct _FILE_PROVIDER_EXTERNAL_INFO_V1 {
103 #define FILE_PROVIDER_CURRENT_VERSION 1
105 #define FILE_PROVIDER_COMPRESSION_XPRESS4K 0
106 #define FILE_PROVIDER_COMPRESSION_LZX 1
107 #define FILE_PROVIDER_COMPRESSION_XPRESS8K 2
108 #define FILE_PROVIDER_COMPRESSION_XPRESS16K 3
111 } FILE_PROVIDER_EXTERNAL_INFO_V1, *PFILE_PROVIDER_EXTERNAL_INFO_V1;
112 #endif /* WOF_PROVIDER_FILE */
114 /* Sets the backing source for a file.
115 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-set-external-backing */
116 #ifndef FSCTL_SET_EXTERNAL_BACKING
117 #define FSCTL_SET_EXTERNAL_BACKING \
118 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 195, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
121 /* Gets the backing information for a file from an external backing provider.
122 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-get-external-backing */
123 #ifndef FSCTL_GET_EXTERNAL_BACKING
124 #define FSCTL_GET_EXTERNAL_BACKING \
125 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 196, METHOD_BUFFERED, FILE_ANY_ACCESS)
128 #ifndef STATUS_OBJECT_NOT_EXTERNALLY_BACKED
129 #define STATUS_OBJECT_NOT_EXTERNALLY_BACKED 0xC000046D
132 /* Removes the association of a file with an external backing provider.
133 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-delete-external-backing */
134 #ifndef FSCTL_DELETE_EXTERNAL_BACKING
135 #define FSCTL_DELETE_EXTERNAL_BACKING \
136 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 197, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
139 /* Begins or continues an enumeration of files on a volume that have a backing source.
140 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-enum-external-backing */
141 #ifndef FSCTL_ENUM_EXTERNAL_BACKING
142 #define FSCTL_ENUM_EXTERNAL_BACKING \
143 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 198, METHOD_BUFFERED, FILE_ANY_ACCESS)
146 /* Enumerates all the data sources from a backing provider for a specified volume.
147 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-enum-overlay */
148 #ifndef FSCTL_ENUM_OVERLAY
149 #define FSCTL_ENUM_OVERLAY \
150 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 199, METHOD_NEITHER, FILE_ANY_ACCESS)
151 typedef struct _WIM_PROVIDER_OVERLAY_ENTRY {
152 ULONG NextEntryOffset;
153 LARGE_INTEGER DataSourceId;
155 ULONG WimFileNameOffset;
159 } WIM_PROVIDER_OVERLAY_ENTRY, *PWIM_PROVIDER_OVERLAY_ENTRY;
160 #endif /* FSCTL_ENUM_OVERLAY */
162 /* Add a new external backing source to a volume's namespace.
163 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-add-overlay */
164 #ifndef FSCTL_ADD_OVERLAY
165 #define FSCTL_ADD_OVERLAY \
166 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 204, METHOD_BUFFERED, FILE_WRITE_DATA)
167 typedef struct _WIM_PROVIDER_ADD_OVERLAY_INPUT {
168 #define WIM_BOOT_NOT_OS_WIM 0
169 #define WIM_BOOT_OS_WIM 1
172 ULONG WimFileNameOffset;
173 ULONG WimFileNameLength;
174 } WIM_PROVIDER_ADD_OVERLAY_INPUT, *PWIM_PROVIDER_ADD_OVERLAY_INPUT;
175 #endif /* FSCTL_ADD_OVERLAY */
177 /* Removes a backing source from a volume.
178 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-remove-overlay */
179 #ifndef FSCTL_REMOVE_OVERLAY
180 #define FSCTL_REMOVE_OVERLAY \
181 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 205, METHOD_BUFFERED, FILE_WRITE_DATA)
182 typedef struct _WIM_PROVIDER_REMOVE_OVERLAY_INPUT {
183 LARGE_INTEGER DataSourceId;
184 } WIM_PROVIDER_REMOVE_OVERLAY_INPUT, *PWIM_PROVIDER_REMOVE_OVERLAY_INPUT;
185 #endif /* FSCTL_REMOVE_OVERLAY */
187 /* Updates a new data source identifier for a backing source attached to a volume.
188 * Ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-update-overlay */
189 #ifndef FSCTL_UPDATE_OVERLAY
190 #define FSCTL_UPDATE_OVERLAY \
191 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 206, METHOD_BUFFERED, FILE_WRITE_DATA)
192 typedef struct _WIM_PROVIDER_UPDATE_OVERLAY_INPUT {
193 LARGE_INTEGER DataSourceId;
194 ULONG WimFileNameOffset;
195 ULONG WimFileNameLength;
196 } WIM_PROVIDER_UPDATE_OVERLAY_INPUT, *PWIM_PROVIDER_UPDATE_OVERLAY_INPUT;
197 #endif /* FSCTL_UPDATE_OVERLAY */
199 /*----------------------------------------------------------------------------*
200 * WOF reparse point and WimOverlay.dat structs (undocumented) *
201 *----------------------------------------------------------------------------*/
204 * Format of the WIM provider reparse data. This is the data which follows the
205 * portion of the reparse point common to WOF. (The common portion consists of
206 * a reparse point header where the reparse tag is 0x80000017, then a
207 * WOF_EXTERNAL_INFO struct which specifies the provider.)
209 * Note that Microsoft does not document any of the reparse point formats for
210 * WOF, although they document the structures which must be passed into the
211 * ioctls, which are often similar.
213 struct wim_provider_rpdata {
214 /* Set to 2. Uncertain meaning. */
217 /* 0 when WIM provider active, otherwise
218 * WIM_PROVIDER_EXTERNAL_FLAG_NOT_ACTIVE or
219 * WIM_PROVIDER_EXTERNAL_FLAG_SUSPENDED. */
222 /* Integer ID that identifies the WIM. */
225 /* SHA-1 message digest of the file's unnamed data stream. */
226 u8 unnamed_data_stream_hash[20];
228 /* SHA-1 message digest of the WIM's blob table as stored on disk. */
229 u8 blob_table_hash[20];
231 /* Uncompressed size of the file's unnamed data stream, in bytes. */
232 le64 unnamed_data_stream_size;
234 /* Size of the file's unnamed data stream as stored in the WIM file.
235 * If this is the same as unnamed_data_stream_size, then the stream is
236 * uncompressed. If this is the *not* the same as
237 * unnamed_data_stream_size, then the stream is compressed. */
238 le64 unnamed_data_stream_size_in_wim;
240 /* Byte offset of the file's unnamed data stream in the WIM. */
241 le64 unnamed_data_stream_offset_in_wim;
244 /* WIM-specific information about a WIM data source */
245 struct WimOverlay_dat_entry_1 {
247 /* Identifier for the WIM data source, (normally allocated by
248 * FSCTL_ADD_OVERLAY). Every 'WimOverlay_dat_entry_1' should have a
249 * different value for this. */
252 /* Byte offset, from the beginning of the file, of the corresponding
253 * 'struct WimOverlay_dat_entry_2' for this WIM data source. */
256 /* Size, in bytes, of the corresponding 'struct WimOverlay_dat_entry_2
257 * for this WIM data source, including wim_file_name and its null
261 /* Type of the WIM file: WIM_BOOT_OS_WIM or WIM_BOOT_NOT_OS_WIM. */
264 /* Index of the image in the WIM to use??? (This doesn't really make
265 * sense, since WIM files combine file data "blobs" for all images into
266 * a single table. Set to 1 if unsure...) */
269 /* GUID of the WIM file (copied from the WIM header, offset +0x18). */
274 * Format of file: "\System Volume Information\WimOverlay.dat"
276 * Not documented by Microsoft.
278 * The file consists of a 'struct WimOverlay_dat_header' followed by one or more
279 * 'struct WimOverlay_dat_entry_1', followed by the same number of 'struct
280 * WimOverlay_dat_entry_2'. Note that 'struct WimOverlay_dat_entry_1' is of
281 * fixed length, whereas 'struct WimOverlay_dat_entry_2' is of variable length.
283 struct WimOverlay_dat_header {
284 /* Set to WIMOVERLAY_DAT_MAGIC */
286 #define WIMOVERLAY_DAT_MAGIC 0x66436F57
288 /* Set to 1 (WIM_PROVIDER_CURRENT_VERSION) */
289 le32 wim_provider_version;
291 /* Set to 0x00000028 */
294 /* Set to number of WIMs registered (listed in the file) */
297 /* The next available data source ID. This is tracked so that data
298 * source IDs are never reused, even if a WIM is unregistered. */
299 le64 next_data_source_id;
301 struct WimOverlay_dat_entry_1 entry_1s[];
304 /* Location information about a WIM data source */
305 struct WimOverlay_dat_entry_2 {
312 /* Size, in bytes, of this 'struct WimOverlay_dat_entry_2', including
313 * wim_file_name and its null terminator. */
326 /* Size of this inner structure, in bytes. */
327 le32 inner_struct_size;
344 /*************************
345 * Partition information
346 ************************/
348 /* Partition identifier */
350 /* (For MBR-formatted disks) */
352 /* Offset, in bytes, of the MBR partition, from
353 * the beginning of the disk. */
354 le64 part_start_offset;
360 /* (For GPT-formatted disks) */
362 /* Unique GUID of the GPT partition */
363 u8 part_unique_guid[16];
370 /***********************
372 **********************/
374 /* 1 for MBR, 0 for GPT */
375 le32 partition_table_type;
376 #define WIMOVERLAY_PARTITION_TYPE_MBR 1
377 #define WIMOVERLAY_PARTITION_TYPE_GPT 0
379 /* Disk identifier */
381 /* (For MBR-formatted disks) */
383 /* 4-byte ID of the MBR disk */
390 /* (For GPT-formatted disks) */
392 /* GUID of the GPT disk */
397 /* Set to 0. (This is the right size for some sort of optional
399 le32 unknown_0x58[4];
401 /**************************
402 * Location in filesystem
403 *************************/
405 /* Null-terminated path to WIM file. Begins with \ but does
406 * *not* include drive letter! */
407 utf16lechar wim_file_name[];
411 static _unused_attribute void
412 wof_check_structs(void)
414 STATIC_ASSERT(sizeof(struct WimOverlay_dat_header) == 24);
415 STATIC_ASSERT(sizeof(struct WimOverlay_dat_entry_1) == 40);
416 STATIC_ASSERT(sizeof(struct WimOverlay_dat_entry_2) == 104);